Skip to content

Instantly share code, notes, and snippets.

@joshcough
Last active October 2, 2025 20:19
Show Gist options
  • Save joshcough/ceef229750c279c320a02ca30f9967c5 to your computer and use it in GitHub Desktop.
Save joshcough/ceef229750c279c320a02ca30f9967c5 to your computer and use it in GitHub Desktop.
Command(s) for dealing with iterm2 raw session logs
#!/usr/bin/env zsh
# =============================================================================
# TERMINAL LOGGING SYSTEM
# =============================================================================
# Complete logging management for iTerm2 sessions
# Source this from your .zshrc with: source ~/.terminal_logging_rc
# =============================================================================
# CONFIGURATION
# =============================================================================
# Set your log directory here (default: ~/.terminal_logs)
TERMINAL_LOG_DIR="${TERMINAL_LOG_DIR:-$HOME/.terminal_logs}"
# =============================================================================
# INTERNAL HELPER FUNCTIONS
# =============================================================================
_terminal_log_find() {
find "$TERMINAL_LOG_DIR" -name "*.log" -type f -exec ls -t {} + 2>/dev/null | head -1
}
_terminal_log_clean_file() {
local log_file="$1"
if [[ ! -f "$log_file" ]]; then
echo "Error: Log file not found: $log_file"
_terminal_log_notify "Log file not found: $log_file"
return 1
fi
# Remove ANSI escape codes and control characters to make logs readable and searchable
perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)//g' "$log_file" | col -b > "${log_file}.log.txt"
echo "Cleaned log: ${log_file}.log.txt"
}
# Helper function for cleaning logs with optional exclusion
_terminal_log_clean_logs() {
local exclude_current="${1:-false}"
local current_log
local cleaned_count=0
if [[ "$exclude_current" == "true" ]]; then
current_log=$(_terminal_log_find)
fi
# Use find for better performance with large numbers of files
while IFS= read -r -d '' log; do
# Skip current session during startup cleaning to avoid interfering with active logging
if [[ "$exclude_current" == "true" && "$log" == "$current_log" ]]; then
continue
fi
# Only clean if no .log.txt exists OR if raw log is newer (handles partial sessions and updates)
if [[ ! -f "${log}.log.txt" ]] || [[ "$log" -nt "${log}.log.txt" ]]; then
if [[ "$exclude_current" == "false" ]]; then
echo "Cleaning $(basename "$log")"
fi
_terminal_log_clean_file "$log" > /dev/null
((cleaned_count++))
fi
done < <(find "$TERMINAL_LOG_DIR" -name "*.log" -type f -print0)
return $cleaned_count
}
_terminal_log_clean_previous() {
if [[ ! -d "$TERMINAL_LOG_DIR" ]]; then
return 0
fi
_terminal_log_clean_logs "true"
}
_terminal_log_check_file_size() {
local file="$1"
local label="$2"
local warning_size=$((100 * 1024 * 1024))
local size=$(stat -f%z "$file" 2>/dev/null || echo 0)
if [[ $size -gt $warning_size ]]; then
local msg="⚠️ Large $label: $(basename "$file") ($(printf "%.1f" "$(echo "$size/1024/1024" | bc -l)")MB)"
echo "$msg"
_terminal_log_notify "$msg"
return 0
fi
return 1
}
_terminal_log_check_sizes() {
local warning_size=$((100 * 1024 * 1024)) # 100MB threshold
local found_large=false
if [[ -d "$TERMINAL_LOG_DIR" ]]; then
for file in "$TERMINAL_LOG_DIR"/*.log "$TERMINAL_LOG_DIR"/*.log.txt; do
[[ -f "$file" ]] || continue
_terminal_log_check_file_size "$file" "log file" && found_large=true
done
fi
for file in ~/.zsh_history ~/.bash_history ~/.zhistory ~/.history; do
[[ -f "$file" ]] || continue
_terminal_log_check_file_size "$file" "history file" && found_large=true
done
if [[ $found_large == false ]]; then
echo "✅ All files are reasonable sizes"
fi
}
_terminal_log_notify() {
osascript -e "display notification \"$1\" with title \"Terminal Logging\""
}
# =============================================================================
# COMMAND FUNCTIONS
# =============================================================================
_terminal_log_cmd_view() {
# Always get fresh current session (handles tab/window switches)
local current_log=$(_terminal_log_find)
if [[ -n "$current_log" ]]; then
echo "Cleaning and opening current session log: $(basename "$current_log")"
_terminal_log_clean_file "$current_log"
code "${current_log}.log.txt"
else
echo "No current session log found. iTerm2 logging may not be enabled."
fi
}
_terminal_log_cmd_clean() {
local file="$1"
if [[ -z "$file" ]]; then
echo "Usage: terminal_log clean <file>"
return 1
fi
_terminal_log_clean_file "$file"
}
_terminal_log_cmd_clean_all() {
if [[ ! -d "$TERMINAL_LOG_DIR" ]]; then
echo "No log directory found"
return 0
fi
echo "Cleaning all log files that need it..."
_terminal_log_clean_logs "false"
local cleaned_count=$?
if [[ $cleaned_count -eq 0 ]]; then
echo "✅ All log files are already cleaned and up to date"
else
echo "✅ Cleaned $cleaned_count log files"
fi
}
_terminal_log_cmd_list() {
_terminal_log_cmd_clean_all
echo ""
echo "Terminal log files:"
find "$TERMINAL_LOG_DIR" -name "*.log.txt" -type f -exec ls -lht {} + 2>/dev/null
}
_terminal_log_cmd_rg() {
if [[ $# -eq 0 ]]; then
echo "Usage: terminal_log rg <search_pattern>"
echo "Search through all cleaned log files"
return 1
fi
# Clean all logs first to ensure we're searching current content (including active session)
_terminal_log_cmd_clean_all > /dev/null
rg --type-add "logtxt:*.log.txt" --type logtxt "$@" "$TERMINAL_LOG_DIR"
}
_terminal_log_cmd_path() {
local current_log=$(_terminal_log_find)
if [[ -n "$current_log" ]]; then
echo "$current_log"
else
echo "No current log file found"
fi
}
_terminal_log_cmd_help() {
cat << EOF
📝 TERMINAL LOG - Session Logging Management
USAGE:
terminal_log <subcommand> [options]
SUBCOMMANDS:
view Clean and open current session log in VS Code
clean <file> Clean a specific log file (removes ANSI codes)
clean-all Clean all log files that need cleaning
list List all log files (cleaned and readable)
rg <pattern> Search through all cleaned log files
path Show path to current session log file
sizes Check for large log/history files (>100MB)
help, --help Show this help message
EXAMPLES:
terminal_log view # Open current session log
terminal_log clean-all # Clean all logs that need it
terminal_log list # See all your log files
terminal_log rg "error" # Search for "error" in all logs
terminal_log sizes # Check for large files
FILE STRUCTURE:
$TERMINAL_LOG_DIR/ Directory containing all session logs (configurable)
*.log Raw logs from iTerm2 (with ANSI codes)
*.log.txt Cleaned logs (readable, searchable with rg)
TIPS:
• Most logs are cleaned automatically on startup; 'clean-all' only cleans those that need it.
• Change log directory by setting TERMINAL_LOG_DIR in your .zshrc before sourcing this file.
• Use 'rg' to search through .log.txt files for commands/output
• 'terminal_log view' is your main tool for reviewing sessions
• Current session: $CURRENT_SESSION_LOG
EOF
}
# =============================================================================
# MAIN COMMAND INTERFACE (SIMPLIFIED)
# =============================================================================
terminal_log() {
local subcommand="$1"
shift
case "$subcommand" in
"view") _terminal_log_cmd_view "$@" ;;
"clean") _terminal_log_cmd_clean "$@" ;;
"clean-all") _terminal_log_cmd_clean_all "$@" ;;
"list") _terminal_log_cmd_list "$@" ;;
"rg") _terminal_log_cmd_rg "$@" ;;
"path") _terminal_log_cmd_path "$@" ;;
"sizes"|"check-sizes") _terminal_log_check_sizes "$@" ;;
"--help"|"help"|"") _terminal_log_cmd_help "$@" ;;
*)
echo "Unknown subcommand: $subcommand"
echo "Run 'terminal_log --help' for usage information"
return 1
;;
esac
}
# =============================================================================
# SESSION MANAGEMENT
# =============================================================================
setup_session_logging() {
# Brief delay to let iTerm2 create the log file
sleep 0.1
export CURRENT_SESSION_LOG=$(_terminal_log_find)
if [[ -z "$CURRENT_SESSION_LOG" ]]; then
echo "⚠️ iTerm2 logging may not be enabled"
fi
}
# =============================================================================
# STARTUP INITIALIZATION
# =============================================================================
init_terminal_logging() {
_terminal_log_check_sizes > /dev/null 2>&1
_terminal_log_clean_previous
if [[ "$TERM_PROGRAM" == "iTerm.app" ]]; then
setup_session_logging
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment