mirror of
https://github.com/tw93/Mole.git
synced 2026-02-08 19:39:17 +00:00
feat: log cleanup operations for troubleshooting
This commit is contained in:
138
lib/core/log.sh
138
lib/core/log.sh
@@ -23,10 +23,15 @@ fi
|
||||
|
||||
readonly LOG_FILE="${HOME}/.config/mole/mole.log"
|
||||
readonly DEBUG_LOG_FILE="${HOME}/.config/mole/mole_debug_session.log"
|
||||
readonly LOG_MAX_SIZE_DEFAULT=1048576 # 1MB
|
||||
readonly OPERATIONS_LOG_FILE="${HOME}/.config/mole/operations.log"
|
||||
readonly LOG_MAX_SIZE_DEFAULT=1048576 # 1MB
|
||||
readonly OPLOG_MAX_SIZE_DEFAULT=5242880 # 5MB
|
||||
|
||||
# Ensure log directory and file exist with correct ownership
|
||||
ensure_user_file "$LOG_FILE"
|
||||
if [[ "${MO_NO_OPLOG:-}" != "1" ]]; then
|
||||
ensure_user_file "$OPERATIONS_LOG_FILE"
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
# Log Rotation
|
||||
@@ -40,9 +45,18 @@ rotate_log_once() {
|
||||
|
||||
local max_size="$LOG_MAX_SIZE_DEFAULT"
|
||||
if [[ -f "$LOG_FILE" ]] && [[ $(get_file_size "$LOG_FILE") -gt "$max_size" ]]; then
|
||||
mv "$LOG_FILE" "${LOG_FILE}.old" 2> /dev/null || true
|
||||
mv "$LOG_FILE" "${LOG_FILE}.old" 2>/dev/null || true
|
||||
ensure_user_file "$LOG_FILE"
|
||||
fi
|
||||
|
||||
# Rotate operations log (5MB limit)
|
||||
if [[ "${MO_NO_OPLOG:-}" != "1" ]]; then
|
||||
local oplog_max_size="$OPLOG_MAX_SIZE_DEFAULT"
|
||||
if [[ -f "$OPERATIONS_LOG_FILE" ]] && [[ $(get_file_size "$OPERATIONS_LOG_FILE") -gt "$oplog_max_size" ]]; then
|
||||
mv "$OPERATIONS_LOG_FILE" "${OPERATIONS_LOG_FILE}.old" 2>/dev/null || true
|
||||
ensure_user_file "$OPERATIONS_LOG_FILE"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
@@ -53,9 +67,9 @@ rotate_log_once() {
|
||||
log_info() {
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "[$timestamp] INFO: $1" >> "$LOG_FILE" 2> /dev/null || true
|
||||
echo "[$timestamp] INFO: $1" >>"$LOG_FILE" 2>/dev/null || true
|
||||
if [[ "${MO_DEBUG:-}" == "1" ]]; then
|
||||
echo "[$timestamp] INFO: $1" >> "$DEBUG_LOG_FILE" 2> /dev/null || true
|
||||
echo "[$timestamp] INFO: $1" >>"$DEBUG_LOG_FILE" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -63,9 +77,9 @@ log_info() {
|
||||
log_success() {
|
||||
echo -e " ${GREEN}${ICON_SUCCESS}${NC} $1"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "[$timestamp] SUCCESS: $1" >> "$LOG_FILE" 2> /dev/null || true
|
||||
echo "[$timestamp] SUCCESS: $1" >>"$LOG_FILE" 2>/dev/null || true
|
||||
if [[ "${MO_DEBUG:-}" == "1" ]]; then
|
||||
echo "[$timestamp] SUCCESS: $1" >> "$DEBUG_LOG_FILE" 2> /dev/null || true
|
||||
echo "[$timestamp] SUCCESS: $1" >>"$DEBUG_LOG_FILE" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -73,9 +87,9 @@ log_success() {
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}$1${NC}"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "[$timestamp] WARNING: $1" >> "$LOG_FILE" 2> /dev/null || true
|
||||
echo "[$timestamp] WARNING: $1" >>"$LOG_FILE" 2>/dev/null || true
|
||||
if [[ "${MO_DEBUG:-}" == "1" ]]; then
|
||||
echo "[$timestamp] WARNING: $1" >> "$DEBUG_LOG_FILE" 2> /dev/null || true
|
||||
echo "[$timestamp] WARNING: $1" >>"$DEBUG_LOG_FILE" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -83,9 +97,9 @@ log_warning() {
|
||||
log_error() {
|
||||
echo -e "${YELLOW}${ICON_ERROR}${NC} $1" >&2
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "[$timestamp] ERROR: $1" >> "$LOG_FILE" 2> /dev/null || true
|
||||
echo "[$timestamp] ERROR: $1" >>"$LOG_FILE" 2>/dev/null || true
|
||||
if [[ "${MO_DEBUG:-}" == "1" ]]; then
|
||||
echo "[$timestamp] ERROR: $1" >> "$DEBUG_LOG_FILE" 2> /dev/null || true
|
||||
echo "[$timestamp] ERROR: $1" >>"$DEBUG_LOG_FILE" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -93,10 +107,84 @@ log_error() {
|
||||
debug_log() {
|
||||
if [[ "${MO_DEBUG:-}" == "1" ]]; then
|
||||
echo -e "${GRAY}[DEBUG]${NC} $*" >&2
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] DEBUG: $*" >> "$DEBUG_LOG_FILE" 2> /dev/null || true
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] DEBUG: $*" >>"$DEBUG_LOG_FILE" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Operation Logging (Enabled by default)
|
||||
# ============================================================================
|
||||
# Records all file operations for user troubleshooting
|
||||
# Disable with MO_NO_OPLOG=1
|
||||
|
||||
oplog_enabled() {
|
||||
[[ "${MO_NO_OPLOG:-}" != "1" ]]
|
||||
}
|
||||
|
||||
# Log an operation to the operations log file
|
||||
# Usage: log_operation <command> <action> <path> [detail]
|
||||
# Example: log_operation "clean" "REMOVED" "/path/to/file" "15.2MB"
|
||||
# Example: log_operation "clean" "SKIPPED" "/path/to/file" "whitelist"
|
||||
# Example: log_operation "uninstall" "REMOVED" "/Applications/App.app" "150MB"
|
||||
log_operation() {
|
||||
# Allow disabling via environment variable
|
||||
oplog_enabled || return 0
|
||||
|
||||
local command="${1:-unknown}" # clean/uninstall/optimize/purge
|
||||
local action="${2:-UNKNOWN}" # REMOVED/SKIPPED/FAILED/REBUILT
|
||||
local path="${3:-}"
|
||||
local detail="${4:-}"
|
||||
|
||||
# Skip if no path provided
|
||||
[[ -z "$path" ]] && return 0
|
||||
|
||||
local timestamp
|
||||
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
local log_line="[$timestamp] [$command] $action $path"
|
||||
[[ -n "$detail" ]] && log_line+=" ($detail)"
|
||||
|
||||
echo "$log_line" >>"$OPERATIONS_LOG_FILE" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Log session start marker
|
||||
# Usage: log_operation_session_start <command>
|
||||
log_operation_session_start() {
|
||||
oplog_enabled || return 0
|
||||
|
||||
local command="${1:-mole}"
|
||||
local timestamp
|
||||
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
{
|
||||
echo ""
|
||||
echo "# ========== $command session started at $timestamp =========="
|
||||
} >>"$OPERATIONS_LOG_FILE" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Log session end with summary
|
||||
# Usage: log_operation_session_end <command> <items_count> <total_size>
|
||||
log_operation_session_end() {
|
||||
oplog_enabled || return 0
|
||||
|
||||
local command="${1:-mole}"
|
||||
local items="${2:-0}"
|
||||
local size="${3:-0}"
|
||||
local timestamp
|
||||
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
local size_human=""
|
||||
if [[ "$size" =~ ^[0-9]+$ ]] && [[ "$size" -gt 0 ]]; then
|
||||
size_human=$(bytes_to_human "$((size * 1024))" 2>/dev/null || echo "${size}KB")
|
||||
else
|
||||
size_human="0B"
|
||||
fi
|
||||
|
||||
{
|
||||
echo "# ========== $command session ended at $timestamp, $items items, $size_human =========="
|
||||
} >>"$OPERATIONS_LOG_FILE" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Enhanced debug logging for operations
|
||||
debug_operation_start() {
|
||||
local operation_name="$1"
|
||||
@@ -112,7 +200,7 @@ debug_operation_start() {
|
||||
echo ""
|
||||
echo "=== $operation_name ==="
|
||||
[[ -n "$operation_desc" ]] && echo "Description: $operation_desc"
|
||||
} >> "$DEBUG_LOG_FILE" 2> /dev/null || true
|
||||
} >>"$DEBUG_LOG_FILE" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -126,7 +214,7 @@ debug_operation_detail() {
|
||||
echo -e "${GRAY}[DEBUG] $detail_type: $detail_value${NC}" >&2
|
||||
|
||||
# Also log to file
|
||||
echo "$detail_type: $detail_value" >> "$DEBUG_LOG_FILE" 2> /dev/null || true
|
||||
echo "$detail_type: $detail_value" >>"$DEBUG_LOG_FILE" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -146,7 +234,7 @@ debug_file_action() {
|
||||
echo -e "${GRAY}[DEBUG] $action: $msg${NC}" >&2
|
||||
|
||||
# Also log to file
|
||||
echo "$action: $msg" >> "$DEBUG_LOG_FILE" 2> /dev/null || true
|
||||
echo "$action: $msg" >>"$DEBUG_LOG_FILE" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -158,16 +246,16 @@ debug_risk_level() {
|
||||
if [[ "${MO_DEBUG:-}" == "1" ]]; then
|
||||
local color="$GRAY"
|
||||
case "$risk_level" in
|
||||
LOW) color="$GREEN" ;;
|
||||
MEDIUM) color="$YELLOW" ;;
|
||||
HIGH) color="$RED" ;;
|
||||
LOW) color="$GREEN" ;;
|
||||
MEDIUM) color="$YELLOW" ;;
|
||||
HIGH) color="$RED" ;;
|
||||
esac
|
||||
|
||||
# Output to stderr with color
|
||||
echo -e "${GRAY}[DEBUG] Risk Level: ${color}${risk_level}${GRAY}, $reason${NC}" >&2
|
||||
|
||||
# Also log to file
|
||||
echo "Risk Level: $risk_level, $reason" >> "$DEBUG_LOG_FILE" 2> /dev/null || true
|
||||
echo "Risk Level: $risk_level, $reason" >>"$DEBUG_LOG_FILE" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -179,7 +267,7 @@ log_system_info() {
|
||||
|
||||
# Reset debug log file for this new session
|
||||
ensure_user_file "$DEBUG_LOG_FILE"
|
||||
if ! : > "$DEBUG_LOG_FILE" 2> /dev/null; then
|
||||
if ! : >"$DEBUG_LOG_FILE" 2>/dev/null; then
|
||||
echo -e "${YELLOW}${ICON_WARNING}${NC} Debug log not writable: $DEBUG_LOG_FILE" >&2
|
||||
fi
|
||||
|
||||
@@ -192,19 +280,19 @@ log_system_info() {
|
||||
echo "Hostname: $(hostname)"
|
||||
echo "Architecture: $(uname -m)"
|
||||
echo "Kernel: $(uname -r)"
|
||||
if command -v sw_vers > /dev/null; then
|
||||
if command -v sw_vers >/dev/null; then
|
||||
echo "macOS: $(sw_vers -productVersion), $(sw_vers -buildVersion)"
|
||||
fi
|
||||
echo "Shell: ${SHELL:-unknown}, ${TERM:-unknown}"
|
||||
|
||||
# Check sudo status non-interactively
|
||||
if sudo -n true 2> /dev/null; then
|
||||
if sudo -n true 2>/dev/null; then
|
||||
echo "Sudo Access: Active"
|
||||
else
|
||||
echo "Sudo Access: Required"
|
||||
fi
|
||||
echo "----------------------------------------------------------------------"
|
||||
} >> "$DEBUG_LOG_FILE" 2> /dev/null || true
|
||||
} >>"$DEBUG_LOG_FILE" 2>/dev/null || true
|
||||
|
||||
# Notification to stderr
|
||||
echo -e "${GRAY}[DEBUG] Debug logging enabled. Session log: $DEBUG_LOG_FILE${NC}" >&2
|
||||
@@ -216,7 +304,7 @@ log_system_info() {
|
||||
|
||||
# Run command silently (ignore errors)
|
||||
run_silent() {
|
||||
"$@" > /dev/null 2>&1 || true
|
||||
"$@" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
# Run command with error logging
|
||||
@@ -224,12 +312,12 @@ run_logged() {
|
||||
local cmd="$1"
|
||||
# Log to main file, and also to debug file if enabled
|
||||
if [[ "${MO_DEBUG:-}" == "1" ]]; then
|
||||
if ! "$@" 2>&1 | tee -a "$LOG_FILE" | tee -a "$DEBUG_LOG_FILE" > /dev/null; then
|
||||
if ! "$@" 2>&1 | tee -a "$LOG_FILE" | tee -a "$DEBUG_LOG_FILE" >/dev/null; then
|
||||
log_warning "Command failed: $cmd"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
if ! "$@" 2>&1 | tee -a "$LOG_FILE" > /dev/null; then
|
||||
if ! "$@" 2>&1 | tee -a "$LOG_FILE" >/dev/null; then
|
||||
log_warning "Command failed: $cmd"
|
||||
return 1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user