mirror of
https://github.com/acedanger/shell.git
synced 2025-12-06 10:00:11 -08:00
- Created a base HTML template for consistent layout across pages. - Developed a dashboard page to display backup service metrics and statuses. - Implemented a log viewer for detailed log file inspection. - Added error handling page for better user experience during failures. - Introduced service detail page to show specific service metrics and actions. - Enhanced log filtering and viewing capabilities. - Integrated auto-refresh functionality for real-time updates on metrics. - Created integration and unit test scripts for backup metrics functionality.
247 lines
7.8 KiB
Bash
247 lines
7.8 KiB
Bash
#!/bin/bash
|
|
|
|
################################################################################
|
|
# Simplified Unified Backup Metrics Library
|
|
################################################################################
|
|
#
|
|
# Author: Peter Wood <peter@peterwood.dev>
|
|
# 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"
|