Last active
October 2, 2025 20:19
-
-
Save joshcough/ceef229750c279c320a02ca30f9967c5 to your computer and use it in GitHub Desktop.
Command(s) for dealing with iterm2 raw session logs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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