mirror of
https://github.com/acedanger/shell.git
synced 2025-12-06 02:20:11 -08:00
feat: Add base HTML template and implement dashboard, logs, and service views
- 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.
This commit is contained in:
251
lib/unified-backup-metrics.sh
Normal file
251
lib/unified-backup-metrics.sh
Normal file
@@ -0,0 +1,251 @@
|
||||
#!/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 new_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 "$new_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: $new_status - $operation ($(date --iso-8601=seconds))" >> "$METRICS_STATUS_FILE"
|
||||
fi
|
||||
|
||||
metrics_debug "Updated status: $new_status - $operation"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Track individual file backup completion
|
||||
metrics_file_backup_complete() {
|
||||
local file_path="$1"
|
||||
local file_size="$2"
|
||||
local file_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 [ "$file_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") ($file_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}"
|
||||
}
|
||||
|
||||
# Additional compatibility functions for backup-media.sh
|
||||
metrics_status_update() {
|
||||
metrics_update_status "$1" "$2"
|
||||
}
|
||||
|
||||
# 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"
|
||||
Reference in New Issue
Block a user