#!/bin/bash # MEV Bot Production Log Manager # Comprehensive log management with real-time monitoring, alerting, and analytics set -euo pipefail # Production Configuration PROJECT_ROOT="/home/administrator/projects/mev-beta" LOGS_DIR="$PROJECT_ROOT/logs" ARCHIVE_DIR="$PROJECT_ROOT/logs/archives" ANALYTICS_DIR="$PROJECT_ROOT/logs/analytics" ALERTS_DIR="$PROJECT_ROOT/logs/alerts" CONFIG_FILE="$PROJECT_ROOT/config/log-manager.conf" # Default Configuration DEFAULT_RETENTION_DAYS=30 DEFAULT_ARCHIVE_SIZE_LIMIT="10G" DEFAULT_LOG_SIZE_LIMIT="1G" DEFAULT_ERROR_THRESHOLD=100 DEFAULT_ALERT_EMAIL="" DEFAULT_SLACK_WEBHOOK="" DEFAULT_MONITORING_INTERVAL=60 # Colors and formatting RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' BOLD='\033[1m' NC='\033[0m' # Performance metrics declare -A METRICS=( ["archives_created"]=0 ["logs_rotated"]=0 ["alerts_sent"]=0 ["errors_detected"]=0 ["corruption_found"]=0 ["performance_issues"]=0 ) # Initialize configuration init_config() { if [[ ! -f "$CONFIG_FILE" ]]; then mkdir -p "$(dirname "$CONFIG_FILE")" cat > "$CONFIG_FILE" << EOF # MEV Bot Log Manager Configuration RETENTION_DAYS=${DEFAULT_RETENTION_DAYS} ARCHIVE_SIZE_LIMIT=${DEFAULT_ARCHIVE_SIZE_LIMIT} LOG_SIZE_LIMIT=${DEFAULT_LOG_SIZE_LIMIT} ERROR_THRESHOLD=${DEFAULT_ERROR_THRESHOLD} ALERT_EMAIL=${DEFAULT_ALERT_EMAIL} SLACK_WEBHOOK=${DEFAULT_SLACK_WEBHOOK} MONITORING_INTERVAL=${DEFAULT_MONITORING_INTERVAL} AUTO_ROTATE=true AUTO_ANALYZE=true AUTO_ALERT=true COMPRESS_LEVEL=9 HEALTH_CHECK_ENABLED=true PERFORMANCE_TRACKING=true EOF log "Created default configuration: $CONFIG_FILE" fi source "$CONFIG_FILE" } # Logging functions with levels log() { echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] INFO:${NC} $1" | tee -a "$LOGS_DIR/log-manager.log" } warn() { echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARN:${NC} $1" | tee -a "$LOGS_DIR/log-manager.log" } error() { echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" | tee -a "$LOGS_DIR/log-manager.log" ((METRICS["errors_detected"]++)) } success() { echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] SUCCESS:${NC} $1" | tee -a "$LOGS_DIR/log-manager.log" } debug() { if [[ "${DEBUG:-false}" == "true" ]]; then echo -e "${CYAN}[$(date +'%Y-%m-%d %H:%M:%S')] DEBUG:${NC} $1" | tee -a "$LOGS_DIR/log-manager.log" fi } # Create directory structure setup_directories() { local dirs=("$ARCHIVE_DIR" "$ANALYTICS_DIR" "$ALERTS_DIR" "$LOGS_DIR/rotated" "$LOGS_DIR/health") for dir in "${dirs[@]}"; do if [[ ! -d "$dir" ]]; then mkdir -p "$dir" debug "Created directory: $dir" fi done } # Enhanced log rotation with size and time-based triggers rotate_logs() { log "Starting intelligent log rotation..." local rotated_count=0 local timestamp=$(date +"%Y%m%d_%H%M%S") # Find logs that need rotation while IFS= read -r -d '' logfile; do local filename=$(basename "$logfile") local size=$(stat -c%s "$logfile" 2>/dev/null || echo 0) local size_mb=$((size / 1024 / 1024)) # Check if rotation is needed (size > limit or age > 24h) local needs_rotation=false if [[ $size -gt $(numfmt --from=iec "${LOG_SIZE_LIMIT}") ]]; then needs_rotation=true debug "Log $filename needs rotation: size ${size_mb}MB exceeds limit" fi if [[ $(find "$logfile" -mtime +0 -print 2>/dev/null) ]]; then needs_rotation=true debug "Log $filename needs rotation: older than 24 hours" fi if [[ "$needs_rotation" == "true" ]]; then local rotated_name="${filename%.log}_${timestamp}.log" mv "$logfile" "$LOGS_DIR/rotated/$rotated_name" gzip "$LOGS_DIR/rotated/$rotated_name" touch "$logfile" # Create fresh log file ((rotated_count++)) log "Rotated $filename -> ${rotated_name}.gz (${size_mb}MB)" fi done < <(find "$LOGS_DIR" -maxdepth 1 -name "*.log" -type f -print0) METRICS["logs_rotated"]=$rotated_count success "Log rotation completed: $rotated_count files rotated" } # Real-time log analysis with pattern detection analyze_logs() { log "Starting comprehensive log analysis..." local analysis_file="$ANALYTICS_DIR/analysis_$(date +%Y%m%d_%H%M%S).json" local main_log="$LOGS_DIR/mev_bot.log" if [[ ! -f "$main_log" ]]; then warn "Main log file not found: $main_log" return 1 fi # Performance metrics extraction local total_lines=$(wc -l < "$main_log") local error_lines=$(grep -c "ERROR" "$main_log" || echo 0) local warn_lines=$(grep -c "WARN" "$main_log" || echo 0) local success_lines=$(grep -c "SUCCESS\|✅" "$main_log" || echo 0) # MEV-specific metrics local opportunities=$(grep -c "opportunity" "$main_log" || echo 0) local rejections=$(grep -c "REJECTED" "$main_log" || echo 0) local parsing_failures=$(grep -c "PARSING FAILED" "$main_log" || echo 0) local direct_parsing=$(grep -c "DIRECT PARSING" "$main_log" || echo 0) # Transaction processing metrics local blocks_processed=$(grep -c "Block.*Processing.*transactions" "$main_log" || echo 0) local dex_transactions=$(grep -c "DEX transactions" "$main_log" || echo 0) # Error pattern analysis local zero_address_issues=$(grep -c "zero.*address" "$main_log" || echo 0) local connection_errors=$(grep -c "connection.*failed\|context.*canceled" "$main_log" || echo 0) local timeout_errors=$(grep -c "timeout\|deadline exceeded" "$main_log" || echo 0) # Performance trending (last 1000 lines for recent activity) local recent_errors=$(tail -1000 "$main_log" | grep -c "ERROR" || echo 0) local recent_success=$(tail -1000 "$main_log" | grep -c "SUCCESS" || echo 0) # Calculate rates and health scores local error_rate=$(echo "scale=2; $error_lines * 100 / $total_lines" | bc -l 2>/dev/null || echo 0) local success_rate=$(echo "scale=2; $success_lines * 100 / $total_lines" | bc -l 2>/dev/null || echo 0) local health_score=$(echo "scale=0; 100 - $error_rate" | bc -l 2>/dev/null || echo 100) # Generate comprehensive analysis cat > "$analysis_file" << EOF { "analysis_timestamp": "$(date -Iseconds)", "log_file": "$main_log", "system_info": { "hostname": "$(hostname)", "uptime": "$(uptime -p 2>/dev/null || echo 'unknown')", "load_average": "$(uptime | awk -F'load average:' '{print $2}' | xargs)" }, "log_statistics": { "total_lines": $total_lines, "file_size_mb": $(echo "scale=2; $(stat -c%s "$main_log") / 1024 / 1024" | bc -l), "error_lines": $error_lines, "warning_lines": $warn_lines, "success_lines": $success_lines, "error_rate_percent": $error_rate, "success_rate_percent": $success_rate, "health_score": $health_score }, "mev_metrics": { "opportunities_detected": $opportunities, "events_rejected": $rejections, "parsing_failures": $parsing_failures, "direct_parsing_attempts": $direct_parsing, "blocks_processed": $blocks_processed, "dex_transactions": $dex_transactions }, "error_patterns": { "zero_address_issues": $zero_address_issues, "connection_errors": $connection_errors, "timeout_errors": $timeout_errors }, "recent_activity": { "recent_errors": $recent_errors, "recent_success": $recent_success, "recent_health_trend": "$([ -n "${recent_errors}" ] && [ "${recent_errors}" -lt 10 ] 2>/dev/null && echo good || echo concerning)" }, "alerts_triggered": [] } EOF # Check for alert conditions check_alert_conditions "$analysis_file" success "Log analysis completed: $analysis_file" echo -e "${BLUE}Health Score: $health_score/100${NC} | Error Rate: ${error_rate}% | Success Rate: ${success_rate}%" } # Alert system with multiple notification channels check_alert_conditions() { local analysis_file="$1" local alerts_triggered=() # Read analysis data local error_rate=$(jq -r '.log_statistics.error_rate_percent' "$analysis_file" 2>/dev/null || echo 0) local health_score=$(jq -r '.log_statistics.health_score' "$analysis_file" 2>/dev/null || echo 100) local parsing_failures=$(jq -r '.mev_metrics.parsing_failures' "$analysis_file" 2>/dev/null || echo 0) local zero_address_issues=$(jq -r '.error_patterns.zero_address_issues' "$analysis_file" 2>/dev/null || echo 0) # Define alert conditions if (( $(echo "$error_rate > 10" | bc -l) )); then alerts_triggered+=("HIGH_ERROR_RATE:$error_rate%") send_alert "High Error Rate" "Error rate is $error_rate%, exceeding 10% threshold" fi if (( $(echo "$health_score < 80" | bc -l) )); then alerts_triggered+=("LOW_HEALTH_SCORE:$health_score") send_alert "Low Health Score" "System health score is $health_score/100, below 80 threshold" fi if (( parsing_failures > 50 )); then alerts_triggered+=("PARSING_FAILURES:$parsing_failures") send_alert "High Parsing Failures" "$parsing_failures parsing failures detected" fi if (( zero_address_issues > 100 )); then alerts_triggered+=("ZERO_ADDRESS_CORRUPTION:$zero_address_issues") send_alert "Address Corruption" "$zero_address_issues zero address issues detected" fi # Update analysis file with alerts if [[ ${#alerts_triggered[@]} -gt 0 ]]; then local alerts_json=$(printf '%s\n' "${alerts_triggered[@]}" | jq -R . | jq -s .) jq ".alerts_triggered = $alerts_json" "$analysis_file" > "${analysis_file}.tmp" && mv "${analysis_file}.tmp" "$analysis_file" METRICS["alerts_sent"]=${#alerts_triggered[@]} fi } # Multi-channel alert delivery send_alert() { local title="$1" local message="$2" local timestamp=$(date -Iseconds) local alert_file="$ALERTS_DIR/alert_$(date +%Y%m%d_%H%M%S).json" # Create alert record cat > "$alert_file" << EOF { "timestamp": "$timestamp", "title": "$title", "message": "$message", "hostname": "$(hostname)", "severity": "warning", "system_load": "$(uptime | awk -F'load average:' '{print $2}' | xargs)", "disk_usage": "$(df -h $LOGS_DIR | tail -1 | awk '{print $5}')" } EOF error "ALERT: $title - $message" # Email notification if [[ -n "${ALERT_EMAIL:-}" ]] && command -v mail >/dev/null 2>&1; then echo "MEV Bot Alert: $title - $message ($(hostname) at $timestamp)" | mail -s "MEV Bot Alert: $title" "$ALERT_EMAIL" fi # Slack notification if [[ -n "${SLACK_WEBHOOK:-}" ]] && command -v curl >/dev/null 2>&1; then curl -X POST -H 'Content-type: application/json' \ --data "{\"text\":\"🚨 MEV Bot Alert: $title\n$message\nHost: $(hostname)\nTime: $timestamp\"}" \ "$SLACK_WEBHOOK" >/dev/null 2>&1 || true fi } # Log corruption detection and health checks health_check() { log "Running comprehensive health checks..." local health_report="$LOGS_DIR/health/health_$(date +%Y%m%d_%H%M%S).json" local issues=() # Check log file integrity while IFS= read -r -d '' logfile; do if [[ ! -r "$logfile" ]]; then issues+=("UNREADABLE_LOG:$(basename "$logfile")") continue fi # Check for truncated logs if [[ $(tail -c 1 "$logfile" | wc -l) -eq 0 ]]; then issues+=("TRUNCATED_LOG:$(basename "$logfile")") fi # Check for corruption patterns if grep -q "\x00" "$logfile" 2>/dev/null; then issues+=("NULL_BYTES:$(basename "$logfile")") ((METRICS["corruption_found"]++)) fi # Check for encoding issues if ! file "$logfile" | grep -q "text"; then issues+=("ENCODING_ISSUE:$(basename "$logfile")") fi done < <(find "$LOGS_DIR" -maxdepth 1 -name "*.log" -type f -print0) # Check disk space local disk_usage=$(df "$LOGS_DIR" | tail -1 | awk '{print $5}' | sed 's/%//') if (( disk_usage > 90 )); then issues+=("HIGH_DISK_USAGE:${disk_usage}%") send_alert "High Disk Usage" "Log directory is ${disk_usage}% full" fi # Check archive integrity while IFS= read -r -d '' archive; do if ! tar -tzf "$archive" >/dev/null 2>&1; then issues+=("CORRUPTED_ARCHIVE:$(basename "$archive")") ((METRICS["corruption_found"]++)) fi done < <(find "$ARCHIVE_DIR" -name "*.tar.gz" -type f -print0 2>/dev/null) # Generate health report local health_status="healthy" if [[ ${#issues[@]} -gt 0 ]]; then health_status="issues_detected" fi cat > "$health_report" << EOF { "timestamp": "$(date -Iseconds)", "status": "$health_status", "issues_count": ${#issues[@]}, "issues": $(printf '%s\n' "${issues[@]}" | jq -R . | jq -s . 2>/dev/null || echo '[]'), "disk_usage_percent": $disk_usage, "log_files_count": $(find "$LOGS_DIR" -maxdepth 1 -name "*.log" -type f | wc -l), "archive_files_count": $(find "$ARCHIVE_DIR" -name "*.tar.gz" -type f 2>/dev/null | wc -l), "total_log_size_mb": $(du -sm "$LOGS_DIR" | cut -f1), "system_load": "$(uptime | awk -F'load average:' '{print $2}' | xargs)" } EOF if [[ ${#issues[@]} -eq 0 ]]; then success "Health check passed: No issues detected" else warn "Health check found ${#issues[@]} issues: ${issues[*]}" fi echo "$health_report" } # Performance monitoring with trending monitor_performance() { log "Monitoring system performance..." local perf_file="$ANALYTICS_DIR/performance_$(date +%Y%m%d_%H%M%S).json" # System metrics local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//') local memory_usage=$(free | grep Mem | awk '{printf("%.1f", $3/$2 * 100.0)}') local load_avg=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//') # MEV bot specific metrics local mev_processes=$(pgrep -f mev-bot | wc -l) local mev_memory=0 if [[ $mev_processes -gt 0 ]]; then mev_memory=$(pgrep -f mev-bot | xargs ps -o pid,rss --no-headers | awk '{sum+=$2} END {print sum/1024}' 2>/dev/null || echo 0) fi # Log processing rate local log_lines_per_min=0 if [[ -f "$LOGS_DIR/mev_bot.log" ]]; then log_lines_per_min=$(tail -100 "$LOGS_DIR/mev_bot.log" | grep "$(date '+%Y/%m/%d %H:%M')" | wc -l || echo 0) fi cat > "$perf_file" << EOF { "timestamp": "$(date -Iseconds)", "system_metrics": { "cpu_usage_percent": $cpu_usage, "memory_usage_percent": $memory_usage, "load_average": $load_avg, "uptime_seconds": $(awk '{print int($1)}' /proc/uptime) }, "mev_bot_metrics": { "process_count": $mev_processes, "memory_usage_mb": $mev_memory, "log_rate_lines_per_min": $log_lines_per_min }, "log_metrics": { "total_log_size_mb": $(du -sm "$LOGS_DIR" | cut -f1), "archive_size_mb": $(du -sm "$ARCHIVE_DIR" 2>/dev/null | cut -f1 || echo 0), "active_log_files": $(find "$LOGS_DIR" -maxdepth 1 -name "*.log" -type f | wc -l) } } EOF # Check for performance issues if (( $(echo "$cpu_usage > 80" | bc -l) )); then ((METRICS["performance_issues"]++)) send_alert "High CPU Usage" "CPU usage is ${cpu_usage}%" fi if (( $(echo "$memory_usage > 85" | bc -l) )); then ((METRICS["performance_issues"]++)) send_alert "High Memory Usage" "Memory usage is ${memory_usage}%" fi debug "Performance monitoring completed: $perf_file" } # Advanced archiving with compression optimization advanced_archive() { log "Starting advanced archive process..." local timestamp=$(date +"%Y%m%d_%H%M%S") local archive_name="mev_logs_${timestamp}" local temp_dir="$ARCHIVE_DIR/.tmp_$archive_name" mkdir -p "$temp_dir" # Copy logs with metadata preservation find "$LOGS_DIR" -maxdepth 1 -name "*.log" -type f -exec cp -p {} "$temp_dir/" \; # Copy rotated logs if [[ -d "$LOGS_DIR/rotated" ]]; then cp -r "$LOGS_DIR/rotated" "$temp_dir/" fi # Copy analytics and health data if [[ -d "$ANALYTICS_DIR" ]]; then cp -r "$ANALYTICS_DIR" "$temp_dir/" fi if [[ -d "$ALERTS_DIR" ]]; then cp -r "$ALERTS_DIR" "$temp_dir/" fi # Generate comprehensive metadata cat > "$temp_dir/archive_metadata.json" << EOF { "archive_info": { "timestamp": "$(date -Iseconds)", "archive_name": "$archive_name", "created_by": "$(whoami)", "hostname": "$(hostname)", "mev_bot_version": "$(git rev-parse HEAD 2>/dev/null || echo 'unknown')", "git_branch": "$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')", "compression_level": ${COMPRESS_LEVEL:-9} }, "system_snapshot": { "os": "$(uname -s)", "kernel": "$(uname -r)", "architecture": "$(uname -m)", "uptime": "$(uptime -p 2>/dev/null || echo 'unknown')", "load_average": "$(uptime | awk -F'load average:' '{print $2}' | xargs)", "memory_total_gb": $(echo "scale=2; $(grep MemTotal /proc/meminfo | awk '{print $2}') / 1024 / 1024" | bc -l), "disk_space_logs": "$(df -h $LOGS_DIR | tail -1 | awk '{print $4}')" }, "content_summary": { "total_files": $(find "$temp_dir" -type f | wc -l), "total_size_bytes": $(find "$temp_dir" -type f -exec stat -c%s {} + | awk '{sum+=$1} END {print sum+0}'), "log_files": $(find "$temp_dir" -name "*.log" | wc -l), "compressed_files": $(find "$temp_dir" -name "*.gz" | wc -l) }, "metrics": $(echo "${METRICS[@]}" | tr ' ' '\n' | awk -F= '{print "\"" $1 "\":" $2}' | paste -sd, | sed 's/^/{/' | sed 's/$/}/') } EOF # Create optimized archive cd "$ARCHIVE_DIR" tar -cf "${archive_name}.tar.gz" --use-compress-program="gzip -${COMPRESS_LEVEL:-9}" -C "$(dirname "$temp_dir")" "$(basename "$temp_dir")" # Verify archive integrity if tar -tzf "${archive_name}.tar.gz" >/dev/null 2>&1; then local archive_size=$(stat -c%s "${archive_name}.tar.gz" | numfmt --to=iec) success "Archive created successfully: ${archive_name}.tar.gz ($archive_size)" # Update symlink ln -sf "${archive_name}.tar.gz" "latest_archive.tar.gz" # Cleanup temp directory rm -rf "$temp_dir" ((METRICS["archives_created"]++)) else error "Archive verification failed: ${archive_name}.tar.gz" rm -f "${archive_name}.tar.gz" return 1 fi } # Cleanup with advanced retention policies intelligent_cleanup() { log "Starting intelligent cleanup with retention policies..." local deleted_archives=0 local deleted_size=0 # Archive retention by age while IFS= read -r -d '' archive; do local size=$(stat -c%s "$archive") rm "$archive" ((deleted_archives++)) deleted_size=$((deleted_size + size)) debug "Deleted old archive: $(basename "$archive")" done < <(find "$ARCHIVE_DIR" -name "mev_logs_*.tar.gz" -mtime +${RETENTION_DAYS} -print0 2>/dev/null) # Size-based cleanup if total exceeds limit local total_size=$(du -sb "$ARCHIVE_DIR" 2>/dev/null | cut -f1 || echo 0) local size_limit=$(numfmt --from=iec "${ARCHIVE_SIZE_LIMIT}") if [[ $total_size -gt $size_limit ]]; then warn "Archive directory exceeds size limit, cleaning oldest archives..." while [[ $total_size -gt $size_limit ]] && [[ $(find "$ARCHIVE_DIR" -name "mev_logs_*.tar.gz" | wc -l) -gt 1 ]]; do local oldest=$(find "$ARCHIVE_DIR" -name "mev_logs_*.tar.gz" -printf '%T+ %p\n' | sort | head -1 | cut -d' ' -f2) if [[ -f "$oldest" ]]; then local size=$(stat -c%s "$oldest") rm "$oldest" ((deleted_archives++)) deleted_size=$((deleted_size + size)) total_size=$((total_size - size)) debug "Deleted for size limit: $(basename "$oldest")" fi done fi # Cleanup analytics and alerts older than retention period find "$ANALYTICS_DIR" -name "*.json" -mtime +${RETENTION_DAYS} -delete 2>/dev/null || true find "$ALERTS_DIR" -name "*.json" -mtime +${RETENTION_DAYS} -delete 2>/dev/null || true find "$LOGS_DIR/health" -name "*.json" -mtime +${RETENTION_DAYS} -delete 2>/dev/null || true if [[ $deleted_archives -gt 0 ]]; then local deleted_size_human=$(echo $deleted_size | numfmt --to=iec) success "Cleanup completed: $deleted_archives archives deleted ($deleted_size_human freed)" else log "Cleanup completed: No files needed deletion" fi } # Real-time monitoring daemon start_monitoring() { log "Starting real-time monitoring daemon..." local monitor_pid_file="$LOGS_DIR/.monitor.pid" if [[ -f "$monitor_pid_file" ]] && kill -0 $(cat "$monitor_pid_file") 2>/dev/null; then warn "Monitoring daemon already running (PID: $(cat "$monitor_pid_file"))" return 1 fi # Background monitoring loop ( echo $$ > "$monitor_pid_file" while true; do sleep "${MONITORING_INTERVAL}" # Quick health check if [[ "${HEALTH_CHECK_ENABLED}" == "true" ]]; then health_check >/dev/null 2>&1 fi # Performance monitoring if [[ "${PERFORMANCE_TRACKING}" == "true" ]]; then monitor_performance >/dev/null 2>&1 fi # Auto-rotation check if [[ "${AUTO_ROTATE}" == "true" ]]; then local needs_rotation=$(find "$LOGS_DIR" -maxdepth 1 -name "*.log" -size +${LOG_SIZE_LIMIT} | wc -l) if [[ $needs_rotation -gt 0 ]]; then rotate_logs >/dev/null 2>&1 fi fi # Auto-analysis if [[ "${AUTO_ANALYZE}" == "true" ]]; then analyze_logs >/dev/null 2>&1 fi done ) & local daemon_pid=$! echo "$daemon_pid" > "$monitor_pid_file" success "Monitoring daemon started (PID: $daemon_pid, interval: ${MONITORING_INTERVAL}s)" } # Stop monitoring daemon stop_monitoring() { local monitor_pid_file="$LOGS_DIR/.monitor.pid" if [[ -f "$monitor_pid_file" ]]; then local pid=$(cat "$monitor_pid_file") if kill -0 "$pid" 2>/dev/null; then kill "$pid" rm "$monitor_pid_file" success "Monitoring daemon stopped (PID: $pid)" else warn "Monitoring daemon not running (stale PID file)" rm "$monitor_pid_file" fi else warn "Monitoring daemon not running" fi } # Dashboard generation generate_dashboard() { log "Generating operational dashboard..." local dashboard_file="$ANALYTICS_DIR/dashboard_$(date +%Y%m%d_%H%M%S).html" local latest_analysis=$(find "$ANALYTICS_DIR" -name "analysis_*.json" -type f | sort | tail -1) local latest_health=$(find "$LOGS_DIR/health" -name "health_*.json" -type f | sort | tail -1) local latest_performance=$(find "$ANALYTICS_DIR" -name "performance_*.json" -type f | sort | tail -1) cat > "$dashboard_file" << 'EOF' MEV Bot Operations Dashboard

MEV Bot Operations Dashboard

Generated: $(date)

EOF # Add metrics if analysis file exists if [[ -f "$latest_analysis" ]]; then local health_score=$(jq -r '.log_statistics.health_score' "$latest_analysis" 2>/dev/null || echo 0) local error_rate=$(jq -r '.log_statistics.error_rate_percent' "$latest_analysis" 2>/dev/null || echo 0) local opportunities=$(jq -r '.mev_metrics.opportunities_detected' "$latest_analysis" 2>/dev/null || echo 0) cat >> "$dashboard_file" << EOF
System Health Score
80" | bc -l) -eq 1 ] && echo 'good' || echo 'warning')">${health_score}/100
Error Rate
${error_rate}%
MEV Opportunities
${opportunities}
EOF fi # Add recent log entries cat >> "$dashboard_file" << EOF

Recent Log Activity

$(tail -20 "$LOGS_DIR/mev_bot.log" 2>/dev/null | sed 's/&/\&/g; s//\>/g' || echo 'No recent log activity')
EOF success "Dashboard generated: $dashboard_file" echo "$dashboard_file" } # Main command dispatcher main() { case "${1:-help}" in "init") setup_directories init_config success "Log manager initialized" ;; "rotate") init_config setup_directories rotate_logs ;; "analyze") init_config setup_directories analyze_logs ;; "archive") init_config setup_directories advanced_archive ;; "health") init_config setup_directories health_check ;; "monitor") init_config setup_directories monitor_performance ;; "cleanup") init_config setup_directories intelligent_cleanup ;; "start-daemon") init_config setup_directories start_monitoring ;; "stop-daemon") stop_monitoring ;; "dashboard") init_config setup_directories generate_dashboard ;; "full") init_config setup_directories rotate_logs analyze_logs health_check monitor_performance advanced_archive intelligent_cleanup generate_dashboard ;; "status") init_config echo -e "${BOLD}MEV Bot Log Manager Status${NC}" echo "Configuration: $CONFIG_FILE" echo "Monitoring: $([ -f "$LOGS_DIR/.monitor.pid" ] && echo "Running (PID: $(cat "$LOGS_DIR/.monitor.pid"))" || echo "Stopped")" echo "Archives: $(find "$ARCHIVE_DIR" -name "*.tar.gz" 2>/dev/null | wc -l) files" echo "Total archive size: $(du -sh "$ARCHIVE_DIR" 2>/dev/null | cut -f1 || echo "0")" echo "Log directory size: $(du -sh "$LOGS_DIR" | cut -f1)" ;; *) cat << EOF MEV Bot Production Log Manager USAGE: $0 [options] COMMANDS: init Initialize log manager with directories and config rotate Rotate large log files analyze Perform comprehensive log analysis archive Create compressed archive with metadata health Run health checks and corruption detection monitor Generate performance monitoring report cleanup Clean old archives based on retention policy start-daemon Start real-time monitoring daemon stop-daemon Stop monitoring daemon dashboard Generate HTML operations dashboard full Run complete log management cycle status Show current system status EXAMPLES: $0 init # First-time setup $0 full # Complete log management cycle $0 start-daemon # Start background monitoring $0 dashboard # Generate operations dashboard CONFIGURATION: Edit $CONFIG_FILE to customize behavior MONITORING: The daemon provides real-time monitoring with configurable intervals, automatic rotation, health checks, and alerting via email/Slack. EOF ;; esac } # Initialize and run cd "$PROJECT_ROOT" 2>/dev/null || { error "Invalid project root: $PROJECT_ROOT"; exit 1; } main "$@"