tools: add clawlog helper for unified logs
This commit is contained in:
309
scripts/clawlog.sh
Executable file
309
scripts/clawlog.sh
Executable file
@@ -0,0 +1,309 @@
|
||||
#!/bin/bash
|
||||
|
||||
# VibeTunnel Logging Utility
|
||||
# Simplifies access to VibeTunnel logs using macOS unified logging system
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Configuration
|
||||
SUBSYSTEM="com.steipete.clawdis"
|
||||
DEFAULT_LEVEL="info"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to handle sudo password errors
|
||||
handle_sudo_error() {
|
||||
echo -e "\n${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
echo -e "${YELLOW}⚠️ Password Required for Log Access${NC}"
|
||||
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n"
|
||||
echo -e "vtlog needs to use sudo to show complete log data (Apple hides sensitive info by default)."
|
||||
echo -e "\nTo avoid password prompts, configure passwordless sudo for the log command:"
|
||||
echo -e "See: ${BLUE}apple/docs/logging-private-fix.md${NC}\n"
|
||||
echo -e "Quick fix:"
|
||||
echo -e " 1. Run: ${GREEN}sudo visudo${NC}"
|
||||
echo -e " 2. Add: ${GREEN}$(whoami) ALL=(ALL) NOPASSWD: /usr/bin/log${NC}"
|
||||
echo -e " 3. Save and exit (:wq)\n"
|
||||
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Default values
|
||||
STREAM_MODE=false
|
||||
TIME_RANGE="5m" # Default to last 5 minutes
|
||||
CATEGORY=""
|
||||
LOG_LEVEL="$DEFAULT_LEVEL"
|
||||
SEARCH_TEXT=""
|
||||
OUTPUT_FILE=""
|
||||
ERRORS_ONLY=false
|
||||
SERVER_ONLY=false
|
||||
TAIL_LINES=50 # Default number of lines to show
|
||||
SHOW_TAIL=true
|
||||
SHOW_HELP=false
|
||||
|
||||
# Function to show usage
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
clawlog - Clawdis Logging Utility
|
||||
|
||||
USAGE:
|
||||
vtlog [OPTIONS]
|
||||
|
||||
DESCRIPTION:
|
||||
View Clawdis logs with full details (bypasses Apple's privacy redaction).
|
||||
Requires sudo access configured for /usr/bin/log command.
|
||||
|
||||
LOG FLOW ARCHITECTURE:
|
||||
Clawdis logs flow through the macOS unified log (subsystem: com.steipete.clawdis).
|
||||
|
||||
LOG CATEGORIES (examples):
|
||||
• voicewake - Voice wake detection/test harness
|
||||
• relay - Relay process manager
|
||||
• xpc - XPC service calls
|
||||
• notifications - Notification helper
|
||||
• screenshot - Screenshotter
|
||||
• shell - ShellRunner
|
||||
|
||||
QUICK START:
|
||||
vtlog -n 100 Show last 100 lines from all components
|
||||
vtlog -f Follow logs in real-time
|
||||
vtlog -e Show only errors
|
||||
vtlog -c ServerManager Show logs from ServerManager only
|
||||
|
||||
OPTIONS:
|
||||
-h, --help Show this help message
|
||||
-f, --follow Stream logs continuously (like tail -f)
|
||||
-n, --lines NUM Number of lines to show (default: 50)
|
||||
-l, --last TIME Time range to search (default: 5m)
|
||||
Examples: 5m, 1h, 2d, 1w
|
||||
-c, --category CAT Filter by category (e.g., ServerManager, SessionService)
|
||||
-e, --errors Show only error messages
|
||||
-d, --debug Show debug level logs (more verbose)
|
||||
-s, --search TEXT Search for specific text in log messages
|
||||
-o, --output FILE Export logs to file
|
||||
--server Show only server output logs
|
||||
--all Show all logs without tail limit
|
||||
--list-categories List all available log categories
|
||||
--json Output in JSON format
|
||||
|
||||
EXAMPLES:
|
||||
vtlog Show last 50 lines from past 5 minutes (default)
|
||||
vtlog -f Stream logs continuously
|
||||
vtlog -n 100 Show last 100 lines
|
||||
vtlog -e Show only recent errors
|
||||
vtlog -l 30m -n 200 Show last 200 lines from past 30 minutes
|
||||
vtlog -c ServerManager Show recent ServerManager logs
|
||||
vtlog -s "fail" Search for "fail" in recent logs
|
||||
vtlog --server -e Show recent server errors
|
||||
vtlog -f -d Stream debug logs continuously
|
||||
|
||||
CATEGORIES:
|
||||
Common categories include:
|
||||
- ServerManager - Server lifecycle and configuration
|
||||
- SessionService - Terminal session management
|
||||
- TerminalManager - Terminal spawning and control
|
||||
- GitRepository - Git integration features
|
||||
- ScreencapService - Screen capture functionality
|
||||
- WebRTCManager - WebRTC connections
|
||||
- UnixSocket - Unix socket communication
|
||||
- WindowTracker - Window tracking and focus
|
||||
- NgrokService - Ngrok tunnel management
|
||||
- ServerOutput - Node.js server output
|
||||
|
||||
TIME FORMATS:
|
||||
- 5m = 5 minutes - 1h = 1 hour
|
||||
- 2d = 2 days - 1w = 1 week
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# Function to list categories
|
||||
list_categories() {
|
||||
echo -e "${BLUE}Fetching VibeTunnel log categories from the last hour...${NC}\n"
|
||||
|
||||
# Get unique categories from recent logs
|
||||
log show --predicate "subsystem == \"$SUBSYSTEM\"" --last 1h 2>/dev/null | \
|
||||
grep -E "category: \"[^\"]+\"" | \
|
||||
sed -E 's/.*category: "([^"]+)".*/\1/' | \
|
||||
sort | uniq | \
|
||||
while read -r cat; do
|
||||
echo " • $cat"
|
||||
done
|
||||
|
||||
echo -e "\n${YELLOW}Note: Only categories with recent activity are shown${NC}"
|
||||
}
|
||||
|
||||
# Show help if no arguments provided
|
||||
if [[ $# -eq 0 ]]; then
|
||||
show_usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
-f|--follow)
|
||||
STREAM_MODE=true
|
||||
SHOW_TAIL=false
|
||||
shift
|
||||
;;
|
||||
-n|--lines)
|
||||
TAIL_LINES="$2"
|
||||
shift 2
|
||||
;;
|
||||
-l|--last)
|
||||
TIME_RANGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-c|--category)
|
||||
CATEGORY="$2"
|
||||
shift 2
|
||||
;;
|
||||
-e|--errors)
|
||||
ERRORS_ONLY=true
|
||||
shift
|
||||
;;
|
||||
-d|--debug)
|
||||
LOG_LEVEL="debug"
|
||||
shift
|
||||
;;
|
||||
-s|--search)
|
||||
SEARCH_TEXT="$2"
|
||||
shift 2
|
||||
;;
|
||||
-o|--output)
|
||||
OUTPUT_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--server)
|
||||
SERVER_ONLY=true
|
||||
CATEGORY="ServerOutput"
|
||||
shift
|
||||
;;
|
||||
--list-categories)
|
||||
list_categories
|
||||
exit 0
|
||||
;;
|
||||
--json)
|
||||
STYLE_ARGS="--style json"
|
||||
shift
|
||||
;;
|
||||
--all)
|
||||
SHOW_TAIL=false
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}Unknown option: $1${NC}"
|
||||
echo "Use -h or --help for usage information"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Build the predicate
|
||||
PREDICATE="subsystem == \"$SUBSYSTEM\""
|
||||
|
||||
# Add category filter if specified
|
||||
if [[ -n "$CATEGORY" ]]; then
|
||||
PREDICATE="$PREDICATE AND category == \"$CATEGORY\""
|
||||
fi
|
||||
|
||||
# Add error filter if specified
|
||||
if [[ "$ERRORS_ONLY" == true ]]; then
|
||||
PREDICATE="$PREDICATE AND (eventType == \"error\" OR messageType == \"error\" OR eventMessage CONTAINS \"ERROR\" OR eventMessage CONTAINS \"[31m\")"
|
||||
fi
|
||||
|
||||
# Add search filter if specified
|
||||
if [[ -n "$SEARCH_TEXT" ]]; then
|
||||
PREDICATE="$PREDICATE AND eventMessage CONTAINS[c] \"$SEARCH_TEXT\""
|
||||
fi
|
||||
|
||||
# Build the command - always use sudo with --info to show private data
|
||||
if [[ "$STREAM_MODE" == true ]]; then
|
||||
# Streaming mode
|
||||
CMD="sudo log stream --predicate '$PREDICATE' --level $LOG_LEVEL --info"
|
||||
|
||||
echo -e "${GREEN}Streaming VibeTunnel logs continuously...${NC}"
|
||||
echo -e "${YELLOW}Press Ctrl+C to stop${NC}\n"
|
||||
else
|
||||
# Show mode
|
||||
CMD="sudo log show --predicate '$PREDICATE'"
|
||||
|
||||
# Add log level for show command
|
||||
if [[ "$LOG_LEVEL" == "debug" ]]; then
|
||||
CMD="$CMD --debug"
|
||||
else
|
||||
CMD="$CMD --info"
|
||||
fi
|
||||
|
||||
# Add time range
|
||||
CMD="$CMD --last $TIME_RANGE"
|
||||
|
||||
if [[ "$SHOW_TAIL" == true ]]; then
|
||||
echo -e "${GREEN}Showing last $TAIL_LINES log lines from the past $TIME_RANGE${NC}"
|
||||
else
|
||||
echo -e "${GREEN}Showing all logs from the past $TIME_RANGE${NC}"
|
||||
fi
|
||||
|
||||
# Show applied filters
|
||||
if [[ "$ERRORS_ONLY" == true ]]; then
|
||||
echo -e "${RED}Filter: Errors only${NC}"
|
||||
fi
|
||||
if [[ -n "$CATEGORY" ]]; then
|
||||
echo -e "${BLUE}Category: $CATEGORY${NC}"
|
||||
fi
|
||||
if [[ -n "$SEARCH_TEXT" ]]; then
|
||||
echo -e "${YELLOW}Search: \"$SEARCH_TEXT\"${NC}"
|
||||
fi
|
||||
echo "" # Empty line for readability
|
||||
fi
|
||||
|
||||
# Add style arguments if specified
|
||||
if [[ -n "${STYLE_ARGS:-}" ]]; then
|
||||
CMD="$CMD $STYLE_ARGS"
|
||||
fi
|
||||
|
||||
# Execute the command
|
||||
if [[ -n "$OUTPUT_FILE" ]]; then
|
||||
# First check if sudo works without password for the log command
|
||||
if sudo -n /usr/bin/log show --last 1s 2>&1 | grep -q "password"; then
|
||||
handle_sudo_error
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}Exporting logs to: $OUTPUT_FILE${NC}\n"
|
||||
if [[ "$SHOW_TAIL" == true ]] && [[ "$STREAM_MODE" == false ]]; then
|
||||
eval "$CMD" 2>&1 | tail -n "$TAIL_LINES" > "$OUTPUT_FILE"
|
||||
else
|
||||
eval "$CMD" > "$OUTPUT_FILE" 2>&1
|
||||
fi
|
||||
|
||||
# Check if file was created and has content
|
||||
if [[ -s "$OUTPUT_FILE" ]]; then
|
||||
LINE_COUNT=$(wc -l < "$OUTPUT_FILE" | tr -d ' ')
|
||||
echo -e "${GREEN}✓ Exported $LINE_COUNT lines to $OUTPUT_FILE${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ No logs found matching the criteria${NC}"
|
||||
fi
|
||||
else
|
||||
# Run interactively
|
||||
# First check if sudo works without password for the log command
|
||||
if sudo -n /usr/bin/log show --last 1s 2>&1 | grep -q "password"; then
|
||||
handle_sudo_error
|
||||
fi
|
||||
|
||||
if [[ "$SHOW_TAIL" == true ]] && [[ "$STREAM_MODE" == false ]]; then
|
||||
# Apply tail for non-streaming mode
|
||||
eval "$CMD" 2>&1 | tail -n "$TAIL_LINES"
|
||||
echo -e "\n${YELLOW}Showing last $TAIL_LINES lines. Use --all or -n to see more.${NC}"
|
||||
else
|
||||
eval "$CMD"
|
||||
fi
|
||||
fi
|
||||
Reference in New Issue
Block a user