#!/bin/bash ################################################################################ # Simplified Unified Backup Metrics Library ################################################################################ # # Author: Peter Wood # Description: Lightweight backup metrics tracking for personal backup systems. # Provides essential status tracking without enterprise complexity. # # Features: # - Simple JSON status files (one per service) # - Basic timing and file counting # - Minimal performance overhead # - Easy to debug and maintain # - Web interface ready # # Usage: # source /home/acedanger/shell/lib/unified-backup-metrics-simple.sh # # metrics_backup_start "service-name" "description" "/backup/path" # metrics_update_status "running" "Current operation" # metrics_file_backup_complete "/path/to/file" "1024" "success" # metrics_backup_complete "success" "Backup completed successfully" # ################################################################################ # Configuration METRICS_ROOT="${BACKUP_ROOT:-/mnt/share/media/backups}/metrics" METRICS_DEBUG="${METRICS_DEBUG:-false}" # Global state declare -g METRICS_SERVICE="" declare -g METRICS_START_TIME="" declare -g METRICS_STATUS_FILE="" declare -g METRICS_FILE_COUNT=0 declare -g METRICS_TOTAL_SIZE=0 # Debug function metrics_debug() { if [ "$METRICS_DEBUG" = "true" ]; then echo "[METRICS] $1" >&2 fi } # Initialize metrics for a backup service metrics_backup_start() { local service_name="$1" local description="$2" local backup_path="$3" if [ -z "$service_name" ]; then metrics_debug "Warning: No service name provided to metrics_backup_start" return 1 fi # Set global state METRICS_SERVICE="$service_name" METRICS_START_TIME=$(date +%s) METRICS_FILE_COUNT=0 METRICS_TOTAL_SIZE=0 # Create metrics directory mkdir -p "$METRICS_ROOT" # Set status file path METRICS_STATUS_FILE="$METRICS_ROOT/${service_name}_status.json" # Create initial status cat > "$METRICS_STATUS_FILE" << EOF { "service": "$service_name", "description": "$description", "backup_path": "$backup_path", "status": "running", "start_time": "$(date -d "@$METRICS_START_TIME" --iso-8601=seconds)", "start_timestamp": $METRICS_START_TIME, "current_operation": "Starting backup", "files_processed": 0, "total_size_bytes": 0, "last_updated": "$(date --iso-8601=seconds)", "hostname": "$(hostname)" } EOF metrics_debug "Started metrics tracking for $service_name" return 0 } # Update backup status metrics_update_status() { local status="$1" local operation="$2" if [ -z "$METRICS_STATUS_FILE" ] || [ ! -f "$METRICS_STATUS_FILE" ]; then metrics_debug "Warning: No active metrics session for status update" return 1 fi # Update the status file using jq if available, otherwise simple replacement if command -v jq >/dev/null 2>&1; then local temp_file="${METRICS_STATUS_FILE}.tmp" jq --arg status "$status" \ --arg operation "$operation" \ --arg updated "$(date --iso-8601=seconds)" \ '.status = $status | .current_operation = $operation | .last_updated = $updated' \ "$METRICS_STATUS_FILE" > "$temp_file" && mv "$temp_file" "$METRICS_STATUS_FILE" else # Fallback without jq - just add a simple status line to end of file echo "# Status: $status - $operation ($(date --iso-8601=seconds))" >> "$METRICS_STATUS_FILE" fi metrics_debug "Updated status: $status - $operation" return 0 } # Track individual file backup completion metrics_file_backup_complete() { local file_path="$1" local file_size="$2" local status="$3" # "success", "failed", "skipped" if [ -z "$METRICS_STATUS_FILE" ] || [ ! -f "$METRICS_STATUS_FILE" ]; then metrics_debug "Warning: No active metrics session for file tracking" return 1 fi # Update counters if [ "$status" = "success" ]; then METRICS_FILE_COUNT=$((METRICS_FILE_COUNT + 1)) METRICS_TOTAL_SIZE=$((METRICS_TOTAL_SIZE + ${file_size:-0})) fi # Update status file with new counts if jq is available if command -v jq >/dev/null 2>&1; then local temp_file="${METRICS_STATUS_FILE}.tmp" jq --argjson files "$METRICS_FILE_COUNT" \ --argjson size "$METRICS_TOTAL_SIZE" \ --arg updated "$(date --iso-8601=seconds)" \ '.files_processed = $files | .total_size_bytes = $size | .last_updated = $updated' \ "$METRICS_STATUS_FILE" > "$temp_file" && mv "$temp_file" "$METRICS_STATUS_FILE" fi metrics_debug "File tracked: $(basename "$file_path") ($status, ${file_size:-0} bytes)" return 0 } # Complete backup and finalize metrics metrics_backup_complete() { local final_status="$1" # "success", "failed", "completed_with_errors" local message="$2" if [ -z "$METRICS_STATUS_FILE" ] || [ ! -f "$METRICS_STATUS_FILE" ]; then metrics_debug "Warning: No active metrics session to complete" return 1 fi local end_time=$(date +%s) local duration=$((end_time - METRICS_START_TIME)) # Create final status file if command -v jq >/dev/null 2>&1; then local temp_file="${METRICS_STATUS_FILE}.tmp" jq --arg status "$final_status" \ --arg message "$message" \ --arg end_time "$(date -d "@$end_time" --iso-8601=seconds)" \ --argjson end_timestamp "$end_time" \ --argjson duration "$duration" \ --argjson files "$METRICS_FILE_COUNT" \ --argjson size "$METRICS_TOTAL_SIZE" \ --arg updated "$(date --iso-8601=seconds)" \ '.status = $status | .message = $message | .end_time = $end_time | .end_timestamp = $end_timestamp | .duration_seconds = $duration | .files_processed = $files | .total_size_bytes = $size | .current_operation = "Completed" | .last_updated = $updated' \ "$METRICS_STATUS_FILE" > "$temp_file" && mv "$temp_file" "$METRICS_STATUS_FILE" else # Fallback - append completion info cat >> "$METRICS_STATUS_FILE" << EOF # COMPLETION: $final_status # MESSAGE: $message # END_TIME: $(date -d "@$end_time" --iso-8601=seconds) # DURATION: ${duration}s # FILES: $METRICS_FILE_COUNT # SIZE: $METRICS_TOTAL_SIZE bytes EOF fi metrics_debug "Backup completed: $final_status ($duration seconds, $METRICS_FILE_COUNT files)" # Clear global state METRICS_SERVICE="" METRICS_START_TIME="" METRICS_STATUS_FILE="" METRICS_FILE_COUNT=0 METRICS_TOTAL_SIZE=0 return 0 } # Legacy compatibility functions (for existing integrations) metrics_init() { metrics_backup_start "$1" "${2:-Backup operation}" "${3:-/backup}" } metrics_start_backup() { metrics_update_status "running" "Backup in progress" } metrics_add_file() { metrics_file_backup_complete "$1" "$3" "$2" } metrics_complete_backup() { metrics_backup_complete "$1" "${2:-Backup operation completed}" } # Utility function to get current status metrics_get_status() { local service_name="$1" local status_file="$METRICS_ROOT/${service_name}_status.json" if [ -f "$status_file" ]; then if command -v jq >/dev/null 2>&1; then jq -r '.status' "$status_file" 2>/dev/null || echo "unknown" else echo "available" fi else echo "never_run" fi } # Utility function to list all services with metrics metrics_list_services() { if [ -d "$METRICS_ROOT" ]; then find "$METRICS_ROOT" -name "*_status.json" -exec basename {} \; | sed 's/_status\.json$//' | sort fi } metrics_debug "Simplified unified backup metrics library loaded"