Skip to main content

Application Monitoring

Monitoring multiple application sources simultaneously is one of kitty's most practical use cases. This lesson builds a structured multi-window monitoring tab.

Learning Focus

Build a reusable application monitoring tab that auto-assigns log sources, resource monitors, and API checks to separate kitty windows.

Monitoring Layout

┌─────────────────────────────────────────────────────────┐
│ Tab: "monitor" │
│ │
│ ┌─────────────────────┬──────────────────────────────┐ │
│ │ htop │ tail -f app.log │ │
│ │ (CPU/MEM/LOAD) │ (application logs) │ │
│ │ │ │ │
│ ├─────────────────────┼──────────────────────────────┤ │
│ │ watch -n 5 df -h │ watch -n 10 curl health │ │
│ │ (disk usage) │ (API health checks) │ │
│ │ │ │ │
│ └─────────────────────┴──────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ tail -f error.log (dedicated bottom pane) │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

Complete Monitoring Script

~/bin/monitor-app.sh
#!/bin/bash
TAB_TITLE="monitor"

# Check if tab already exists
kitty @ ls | grep -q "\"title\":\"$TAB_TITLE\"" && {
echo "Monitoring tab already exists. Focusing it."
kitty @ focus-tab --match-title "$TAB_TITLE"
exit 0
}

# Create the monitoring tab
kitty @ launch --type=tab --title "$TAB_TITLE"

# Wait for tab creation
sleep 0.2

# Send htop command (first window)
kitty @ send-text --match-title "$TAB_TITLE" "htop\n"

# Split right for app logs
kitty @ launch --type=window --location=hsplit
kitty @ send-text --match-title "$TAB_TITLE" "tail -f /var/log/app.log\n"

# Split bottom-left for disk monitoring
kitty @ launch --type=window --location=vsplit
kitty @ send-text --match-title "$TAB_TITLE" "watch -n 5 df -h\n"

# Split bottom-right for API health
kitty @ launch --type=window --location=vsplit
kitty @ send-text --match-title "$TAB_TITLE" \
"watch -n 10 'curl -s -o /dev/null -w \"%{http_code}\" http://localhost:8080/health'\n"

echo "Monitoring tab created — 4 panes active"

Using Broadcast Kitten

Send commands to multiple windows simultaneously:

# Start broadcast mode
kitty +kitten broadcast

# While in broadcast mode, every keystroke goes to all windows
# Type: systemctl restart nginx
# This runs on all visible kitty windows

# Exit broadcast mode
# Press: Ctrl+Shift+b

Broadcast with Filters

# Broadcast only to windows matching a title pattern
kitty +kitten broadcast --match "server-*"

# Broadcast to specific window IDs
kitty +kitten broadcast --match-id 1 --match-id 2

Automating with kitty @ send-text

~/bin/check-all.sh
#!/bin/bash
# Check status across all monitored services

kitty @ send-text --match-title monitor "systemctl status nginx\n"
kitty @ send-text --match-title monitor "systemctl status postgresql\n"
kitty @ send-text --match-title monitor "curl -sI http://localhost:8080 | head -1\n"

Integrating with Alerting

Pipe alert notifications into a dedicated kitty window:

~/bin/alert-watcher.sh
#!/bin/bash
# Start a dedicated alert window

kitty @ launch --type=window --title "alerts"
kitty @ send-text --match-title alerts \
"journalctl -f -n 0 -u alert-manager.service | \
grep --line-buffered --color=always 'CRITICAL\|WARNING'\n"

Filtered Log Views

# Watch only errors across all app logs
kitty @ launch --type=window --title "errors"
kitty @ send-text --match-title errors \
"tail -f /var/log/app/*.log | grep --line-buffered 'ERROR\\|FATAL'\n"

# Watch HTTP 5xx responses
kitty @ launch --type=window --title "5xx"
kitty @ send-text --match-title 5xx \
"tail -f /var/log/nginx/access.log | grep --line-buffered ' 5[0-9][0-9] '\n"

Timestamped Log Capture

# Enable pane output logging
kitty @ set-spacing margins=0
# Use pipe to capture output (manual method)
# Start: script /var/log/tmux-captures/monitor-$(date +%Y%m%d).log
# Stop: exit

Monitoring Tab Automation

~/.bashrc
# Quick aliases
alias monitor="~/bin/monitor-app.sh"
alias check-all="~/bin/check-all.sh"
alias broadcast-on="kitty +kitten broadcast"
alias broadcast-off="printf '\x1b]0;'"

Common Pitfalls

PitfallSymptomFix
Broadcast affects all windowsCommands sent to editor panesUse --match to filter windows
Log tail stops after rotationtail -f shows no new linesUse tail -F (capital F) to follow by name
Watch command uses too much CPUHigh CPU from refreshIncrease interval: watch -n 10 instead of -n 2
Window title matching fails--match-title does not find windowVerify title with kitty @ ls
Remote control not respondingkitty @ returns emptyCheck allow_remote_control yes is set

Hands-On Practice

# Create a simple monitoring tab manually
kitty @ launch --type=tab --title "monitor-practice"

# Split into 2 columns
kitty @ launch --type=window --location=hsplit

# Run monitoring commands
kitty @ send-text --match-title "monitor-practice" \
"watch -n 2 'echo \"CPU: \$(uptime)\"'\n"

kitty @ send-text --match-title "monitor-practice" \
"watch -n 2 'echo \"Memory: \$(free -h | grep Mem)\"'\n"

# Test broadcast in practice tab
echo "Broadcast test: Press Ctrl+Shift+b to exit broadcast mode"
# kitty +kitten broadcast --match "monitor-practice"

What's Next