Skip to content

Instantly share code, notes, and snippets.

@joshcough
Last active August 28, 2026 14:42
Show Gist options
  • Select an option

  • Save joshcough/ceef229750c279c320a02ca30f9967c5 to your computer and use it in GitHub Desktop.

Select an option

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
}
@kvietmeier

Copy link
Copy Markdown

@josh - Thanks for a great script! I converted this to bash (I use bash 5.x on my Mac) and added some archiving functionally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment