mirror of
https://github.com/acedanger/shell.git
synced 2025-12-06 01:10:12 -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:
428
examples/enhanced-plex-backup-with-metrics.sh
Normal file
428
examples/enhanced-plex-backup-with-metrics.sh
Normal file
@@ -0,0 +1,428 @@
|
||||
#!/bin/bash
|
||||
|
||||
################################################################################
|
||||
# Enhanced Plex Backup Script with Real-time JSON Metrics
|
||||
################################################################################
|
||||
#
|
||||
# This example shows how to integrate the unified metrics system into the
|
||||
# existing Plex backup script with minimal changes while maintaining
|
||||
# backward compatibility with the current performance tracking system.
|
||||
#
|
||||
# Key Integration Points:
|
||||
# 1. Initialize metrics at script start
|
||||
# 2. Update status during key operations
|
||||
# 3. Track file-by-file progress
|
||||
# 4. Record performance phases
|
||||
# 5. Complete session with final status
|
||||
#
|
||||
################################################################################
|
||||
|
||||
# Load the unified metrics library
|
||||
source "$(dirname "$(readlink -f "$0")")/lib/unified-backup-metrics.sh"
|
||||
|
||||
# Original script variables (unchanged)
|
||||
BACKUP_ROOT="/mnt/share/media/backups/plex"
|
||||
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
|
||||
LOCAL_LOG_ROOT="${SCRIPT_DIR}/logs"
|
||||
PERFORMANCE_LOG_FILE="${LOCAL_LOG_ROOT}/plex-backup-performance.json"
|
||||
|
||||
# Original Plex files configuration (unchanged)
|
||||
declare -A PLEX_FILES=(
|
||||
["database"]="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db"
|
||||
["blobs"]="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.blobs.db"
|
||||
["preferences"]="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Preferences.xml"
|
||||
)
|
||||
|
||||
# Colors (unchanged)
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Original logging functions (unchanged - metrics run in parallel)
|
||||
log_message() {
|
||||
local message="$1"
|
||||
local timestamp
|
||||
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo -e "${BLUE}[${timestamp}]${NC} ${message}"
|
||||
mkdir -p "$LOCAL_LOG_ROOT"
|
||||
echo "[${timestamp}] $message" >> "${LOCAL_LOG_ROOT}/plex-backup-$(date '+%Y-%m-%d').log" 2>/dev/null || true
|
||||
}
|
||||
|
||||
log_success() {
|
||||
local message="$1"
|
||||
local timestamp
|
||||
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo -e "${GREEN}[${timestamp}] SUCCESS:${NC} ${message}"
|
||||
mkdir -p "$LOCAL_LOG_ROOT"
|
||||
echo "[${timestamp}] SUCCESS: $message" >> "${LOCAL_LOG_ROOT}/plex-backup-$(date '+%Y-%m-%d').log" 2>/dev/null || true
|
||||
}
|
||||
|
||||
log_error() {
|
||||
local message="$1"
|
||||
local timestamp
|
||||
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo -e "${RED}[${timestamp}] ERROR:${NC} ${message}"
|
||||
mkdir -p "$LOCAL_LOG_ROOT"
|
||||
echo "[${timestamp}] ERROR: $message" >> "${LOCAL_LOG_ROOT}/plex-backup-$(date '+%Y-%m-%d').log" 2>/dev/null || true
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
local message="$1"
|
||||
local timestamp
|
||||
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo -e "${YELLOW}[${timestamp}] WARNING:${NC} ${message}"
|
||||
mkdir -p "$LOCAL_LOG_ROOT"
|
||||
echo "[${timestamp}] WARNING: $message" >> "${LOCAL_LOG_ROOT}/plex-backup-$(date '+%Y-%m-%d').log" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Original performance tracking function (unchanged - metrics system integrates)
|
||||
track_performance() {
|
||||
local operation="$1"
|
||||
local start_time="$2"
|
||||
local end_time="${3:-$(date +%s)}"
|
||||
local duration=$((end_time - start_time))
|
||||
|
||||
# Initialize performance log if it doesn't exist
|
||||
if [ ! -f "$PERFORMANCE_LOG_FILE" ]; then
|
||||
mkdir -p "$(dirname "$PERFORMANCE_LOG_FILE")"
|
||||
echo "[]" > "$PERFORMANCE_LOG_FILE"
|
||||
fi
|
||||
|
||||
# Add performance entry
|
||||
local entry
|
||||
entry=$(jq -n \
|
||||
--arg operation "$operation" \
|
||||
--arg duration "$duration" \
|
||||
--arg timestamp "$(date -Iseconds)" \
|
||||
'{
|
||||
operation: $operation,
|
||||
duration_seconds: ($duration | tonumber),
|
||||
timestamp: $timestamp
|
||||
}')
|
||||
|
||||
jq --argjson entry "$entry" '. += [$entry]' "$PERFORMANCE_LOG_FILE" > "${PERFORMANCE_LOG_FILE}.tmp" && \
|
||||
mv "${PERFORMANCE_LOG_FILE}.tmp" "$PERFORMANCE_LOG_FILE"
|
||||
|
||||
log_message "Performance: $operation completed in ${duration}s"
|
||||
}
|
||||
|
||||
# Enhanced service management with metrics integration
|
||||
manage_plex_service() {
|
||||
local action="$1"
|
||||
local operation_start
|
||||
operation_start=$(date +%s)
|
||||
|
||||
log_message "Managing Plex service: $action"
|
||||
|
||||
# Update metrics status
|
||||
metrics_update_status "running" "${action}_service"
|
||||
|
||||
case "$action" in
|
||||
stop)
|
||||
if sudo systemctl stop plexmediaserver.service; then
|
||||
log_success "Plex service stopped"
|
||||
|
||||
# Wait for clean shutdown with progress indicator
|
||||
local wait_time=0
|
||||
local max_wait=15
|
||||
|
||||
while [ $wait_time -lt $max_wait ]; do
|
||||
if ! sudo systemctl is-active --quiet plexmediaserver.service; then
|
||||
log_success "Plex service confirmed stopped (${wait_time}s)"
|
||||
|
||||
# Track performance in both systems
|
||||
track_performance "service_stop" "$operation_start"
|
||||
metrics_time_phase "service_stop" "$operation_start"
|
||||
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
wait_time=$((wait_time + 1))
|
||||
echo -n "."
|
||||
done
|
||||
echo
|
||||
|
||||
log_warning "Plex service may not have stopped cleanly after ${max_wait}s"
|
||||
metrics_warning "Service stop took longer than expected (${max_wait}s)"
|
||||
return 1
|
||||
else
|
||||
log_error "Failed to stop Plex service"
|
||||
metrics_error "Failed to stop Plex service"
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
start)
|
||||
if sudo systemctl start plexmediaserver.service; then
|
||||
log_success "Plex service start command issued"
|
||||
|
||||
# Wait for service to be fully running with progress indicator
|
||||
local wait_time=0
|
||||
local max_wait=30
|
||||
|
||||
while [ $wait_time -lt $max_wait ]; do
|
||||
if sudo systemctl is-active --quiet plexmediaserver.service; then
|
||||
log_success "Plex service confirmed running (${wait_time}s)"
|
||||
|
||||
# Track performance in both systems
|
||||
track_performance "service_start" "$operation_start"
|
||||
metrics_time_phase "service_start" "$operation_start"
|
||||
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
wait_time=$((wait_time + 1))
|
||||
echo -n "."
|
||||
done
|
||||
echo
|
||||
|
||||
log_error "Plex service failed to start within ${max_wait}s"
|
||||
metrics_error "Service failed to start within ${max_wait}s"
|
||||
return 1
|
||||
else
|
||||
log_error "Failed to start Plex service"
|
||||
metrics_error "Failed to start Plex service"
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log_error "Invalid service action: $action"
|
||||
metrics_error "Invalid service action: $action"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Enhanced backup copy with file-by-file tracking
|
||||
backup_file_with_metrics() {
|
||||
local nickname="$1"
|
||||
local source_file="$2"
|
||||
local backup_file="$3"
|
||||
|
||||
log_message "Backing up $(basename "$source_file")..."
|
||||
|
||||
if [ ! -f "$source_file" ]; then
|
||||
log_warning "File not found: $source_file"
|
||||
metrics_add_file "$source_file" "skipped" "0" "" "File not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Get source file size for metrics
|
||||
local file_size
|
||||
file_size=$(stat -c%s "$source_file" 2>/dev/null || echo "0")
|
||||
|
||||
# Copy file
|
||||
if cp "$source_file" "$backup_file"; then
|
||||
# Verify the copy
|
||||
if [ -f "$backup_file" ]; then
|
||||
# Calculate checksum for verification
|
||||
local checksum
|
||||
checksum=$(md5sum "$backup_file" 2>/dev/null | cut -d' ' -f1 || echo "")
|
||||
|
||||
log_success "Backed up: $(basename "$source_file") (${file_size} bytes)"
|
||||
metrics_add_file "$source_file" "success" "$file_size" "$checksum"
|
||||
return 0
|
||||
else
|
||||
log_error "Verification failed: $(basename "$source_file")"
|
||||
metrics_add_file "$source_file" "failed" "0" "" "Verification failed after copy"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log_error "Failed to copy: $(basename "$source_file")"
|
||||
metrics_add_file "$source_file" "failed" "0" "" "Copy operation failed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main backup function with metrics integration
|
||||
main() {
|
||||
local overall_start
|
||||
overall_start=$(date +%s)
|
||||
|
||||
log_message "Starting enhanced Plex backup process at $(date)"
|
||||
|
||||
# Initialize metrics system
|
||||
local session_id="plex_backup_$(date +%Y%m%d_%H%M%S)"
|
||||
if ! metrics_init "plex" "$BACKUP_ROOT" "$session_id"; then
|
||||
log_warning "JSON metrics initialization failed, continuing with legacy tracking only"
|
||||
local metrics_enabled=false
|
||||
else
|
||||
local metrics_enabled=true
|
||||
log_message "JSON metrics enabled - session: $session_id"
|
||||
|
||||
# Set total files count for progress tracking
|
||||
metrics_set_total_files "${#PLEX_FILES[@]}" "0"
|
||||
|
||||
# Start the backup session
|
||||
metrics_start_backup
|
||||
fi
|
||||
|
||||
# Create necessary directories
|
||||
mkdir -p "${BACKUP_ROOT}"
|
||||
mkdir -p "${LOCAL_LOG_ROOT}"
|
||||
|
||||
local backup_errors=0
|
||||
local files_backed_up=0
|
||||
local backed_up_files=()
|
||||
local BACKUP_PATH="${BACKUP_ROOT}"
|
||||
|
||||
# Ensure backup root directory exists
|
||||
mkdir -p "$BACKUP_PATH"
|
||||
|
||||
# Update status: stopping service
|
||||
if [ "$metrics_enabled" = true ]; then
|
||||
metrics_update_status "running" "stopping_service"
|
||||
fi
|
||||
|
||||
# Stop Plex service
|
||||
if ! manage_plex_service stop; then
|
||||
log_error "Failed to stop Plex service, aborting backup"
|
||||
if [ "$metrics_enabled" = true ]; then
|
||||
metrics_complete_backup "failed" "Failed to stop Plex service"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update status: starting backup phase
|
||||
if [ "$metrics_enabled" = true ]; then
|
||||
metrics_update_status "running" "backing_up_files"
|
||||
fi
|
||||
|
||||
# Backup files with individual file tracking
|
||||
local backup_phase_start
|
||||
backup_phase_start=$(date +%s)
|
||||
|
||||
for nickname in "${!PLEX_FILES[@]}"; do
|
||||
local file="${PLEX_FILES[$nickname]}"
|
||||
local backup_file="${BACKUP_PATH}/$(basename "$file")"
|
||||
|
||||
if backup_file_with_metrics "$nickname" "$file" "$backup_file"; then
|
||||
files_backed_up=$((files_backed_up + 1))
|
||||
# Add friendly filename to backed up files list
|
||||
case "$(basename "$file")" in
|
||||
"com.plexapp.plugins.library.db") backed_up_files+=("library.db") ;;
|
||||
"com.plexapp.plugins.library.blobs.db") backed_up_files+=("blobs.db") ;;
|
||||
"Preferences.xml") backed_up_files+=("Preferences.xml") ;;
|
||||
*) backed_up_files+=("$(basename "$file")") ;;
|
||||
esac
|
||||
else
|
||||
backup_errors=$((backup_errors + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
# Track backup phase performance
|
||||
track_performance "backup" "$backup_phase_start"
|
||||
if [ "$metrics_enabled" = true ]; then
|
||||
metrics_time_phase "backup" "$backup_phase_start"
|
||||
fi
|
||||
|
||||
# Update status: creating archive
|
||||
if [ "$metrics_enabled" = true ]; then
|
||||
metrics_update_status "running" "creating_archive"
|
||||
fi
|
||||
|
||||
# Create archive if files were backed up
|
||||
local archive_created=false
|
||||
if [ "$files_backed_up" -gt 0 ]; then
|
||||
local compression_start
|
||||
compression_start=$(date +%s)
|
||||
|
||||
local archive_name="plex-backup-$(date +%Y%m%d_%H%M%S).tar.gz"
|
||||
local archive_path="${BACKUP_ROOT}/${archive_name}"
|
||||
|
||||
log_message "Creating compressed archive: $archive_name"
|
||||
|
||||
if cd "$BACKUP_PATH" && tar -czf "$archive_path" *.db *.xml 2>/dev/null; then
|
||||
log_success "Created archive: $archive_name"
|
||||
archive_created=true
|
||||
|
||||
# Track compression performance
|
||||
track_performance "compression" "$compression_start"
|
||||
if [ "$metrics_enabled" = true ]; then
|
||||
metrics_time_phase "compression" "$compression_start"
|
||||
fi
|
||||
|
||||
# Clean up individual files after successful archive creation
|
||||
rm -f "$BACKUP_PATH"/*.db "$BACKUP_PATH"/*.xml 2>/dev/null || true
|
||||
|
||||
# Get archive information for metrics
|
||||
if [ "$metrics_enabled" = true ]; then
|
||||
local archive_size
|
||||
archive_size=$(stat -c%s "$archive_path" 2>/dev/null || echo "0")
|
||||
local archive_checksum
|
||||
archive_checksum=$(md5sum "$archive_path" 2>/dev/null | cut -d' ' -f1 || echo "")
|
||||
|
||||
metrics_add_file "$archive_path" "success" "$archive_size" "$archive_checksum"
|
||||
fi
|
||||
else
|
||||
log_error "Failed to create archive"
|
||||
backup_errors=$((backup_errors + 1))
|
||||
if [ "$metrics_enabled" = true ]; then
|
||||
metrics_error "Failed to create compressed archive"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Update status: starting service
|
||||
if [ "$metrics_enabled" = true ]; then
|
||||
metrics_update_status "running" "starting_service"
|
||||
fi
|
||||
|
||||
# Start Plex service
|
||||
manage_plex_service start
|
||||
|
||||
# Update status: cleaning up
|
||||
if [ "$metrics_enabled" = true ]; then
|
||||
metrics_update_status "running" "cleaning_up"
|
||||
fi
|
||||
|
||||
# Cleanup old backups
|
||||
local cleanup_start
|
||||
cleanup_start=$(date +%s)
|
||||
|
||||
log_message "Cleaning up old backups..."
|
||||
# [Original cleanup logic here - unchanged]
|
||||
|
||||
track_performance "cleanup" "$cleanup_start"
|
||||
if [ "$metrics_enabled" = true ]; then
|
||||
metrics_time_phase "cleanup" "$cleanup_start"
|
||||
fi
|
||||
|
||||
# Track overall backup performance
|
||||
track_performance "total_script" "$overall_start"
|
||||
|
||||
# Final summary
|
||||
local total_time=$(($(date +%s) - overall_start))
|
||||
log_message "Backup process completed at $(date)"
|
||||
log_message "Total execution time: ${total_time}s"
|
||||
log_message "Files backed up: $files_backed_up"
|
||||
log_message "Errors encountered: $backup_errors"
|
||||
|
||||
# Complete metrics session
|
||||
if [ "$metrics_enabled" = true ]; then
|
||||
local final_status="success"
|
||||
local completion_message="Backup completed successfully"
|
||||
|
||||
if [ "$backup_errors" -gt 0 ]; then
|
||||
final_status="partial"
|
||||
completion_message="Backup completed with $backup_errors errors"
|
||||
elif [ "$files_backed_up" -eq 0 ]; then
|
||||
final_status="failed"
|
||||
completion_message="No files were backed up"
|
||||
fi
|
||||
|
||||
metrics_complete_backup "$final_status" "$completion_message"
|
||||
log_message "JSON metrics session completed: $session_id"
|
||||
fi
|
||||
|
||||
# Exit with appropriate code
|
||||
if [ "$backup_errors" -gt 0 ]; then
|
||||
exit 1
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user