📋 Commit iniziale con: - ✅ Documentazione unificata in docs/ - ✅ Codice Laravel in netgescon-laravel/ - ✅ Script automazione in scripts/ - ✅ Configurazione sync rsync - ✅ Struttura organizzata e pulita 🔄 Versione: 2025.07.19-1644 🎯 Sistema pronto per Git distribuito
411 lines
13 KiB
Bash
411 lines
13 KiB
Bash
#!/bin/bash
|
|
|
|
# NetGescon Sync Monitor
|
|
# Script per monitorare lo stato della sincronizzazione e generare report
|
|
# Versione: 1.0
|
|
# Data: 2025-01-17
|
|
|
|
set -euo pipefail
|
|
|
|
# Configurazione
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
CONFIG_FILE="$SCRIPT_DIR/config/sync-config.conf"
|
|
LOG_FILE="$HOME/netgescon/log/auto-sync.log"
|
|
MONITOR_LOG="$HOME/netgescon/log/sync-monitor.log"
|
|
REPORT_DIR="$HOME/netgescon/reports"
|
|
|
|
# Colori
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
# Carica configurazione se esiste
|
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
source "$CONFIG_FILE"
|
|
fi
|
|
|
|
# Funzioni utility
|
|
log_monitor() {
|
|
local message="$1"
|
|
local level="${2:-INFO}"
|
|
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
|
|
local log_entry="[$timestamp] [$level] $message"
|
|
|
|
mkdir -p "$(dirname "$MONITOR_LOG")"
|
|
echo "$log_entry" >> "$MONITOR_LOG"
|
|
|
|
case "$level" in
|
|
"ERROR")
|
|
echo -e "${RED}$log_entry${NC}" >&2
|
|
;;
|
|
"WARN")
|
|
echo -e "${YELLOW}$log_entry${NC}"
|
|
;;
|
|
"SUCCESS")
|
|
echo -e "${GREEN}$log_entry${NC}"
|
|
;;
|
|
*)
|
|
echo -e "${NC}$log_entry${NC}"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
check_sync_status() {
|
|
local status="UNKNOWN"
|
|
local last_sync="N/A"
|
|
local last_error="N/A"
|
|
|
|
if [[ -f "$LOG_FILE" ]]; then
|
|
# Trova ultima sincronizzazione
|
|
last_sync=$(grep "NetGescon Auto-Sync Completed" "$LOG_FILE" 2>/dev/null | tail -1 | cut -d']' -f1-2 | tr -d '[]' || echo "N/A")
|
|
|
|
# Trova ultimo errore
|
|
last_error=$(grep "ERROR" "$LOG_FILE" 2>/dev/null | tail -1 | cut -d']' -f1-2 | tr -d '[]' || echo "N/A")
|
|
|
|
# Determina stato
|
|
if [[ "$last_sync" != "N/A" ]]; then
|
|
local sync_time=$(date -d "$last_sync" +%s 2>/dev/null || echo "0")
|
|
local error_time=$(date -d "$last_error" +%s 2>/dev/null || echo "0")
|
|
|
|
if [[ "$sync_time" -gt "$error_time" ]]; then
|
|
status="SUCCESS"
|
|
else
|
|
status="ERROR"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo "$status|$last_sync|$last_error"
|
|
}
|
|
|
|
get_sync_stats() {
|
|
local today=$(date +%Y-%m-%d)
|
|
local total_syncs=0
|
|
local successful_syncs=0
|
|
local failed_syncs=0
|
|
|
|
if [[ -f "$LOG_FILE" ]]; then
|
|
total_syncs=$(grep "$today.*NetGescon Auto-Sync Started" "$LOG_FILE" 2>/dev/null | wc -l)
|
|
successful_syncs=$(grep "$today.*NetGescon Auto-Sync Completed" "$LOG_FILE" 2>/dev/null | wc -l)
|
|
failed_syncs=$((total_syncs - successful_syncs))
|
|
fi
|
|
|
|
echo "$total_syncs|$successful_syncs|$failed_syncs"
|
|
}
|
|
|
|
check_system_health() {
|
|
local local_health="OK"
|
|
local remote_health="OK"
|
|
|
|
# Controlla locale
|
|
if [[ ! -d "$LOCAL_PATH" ]]; then
|
|
local_health="ERROR: Local path not found"
|
|
elif [[ ! -w "$LOCAL_PATH" ]]; then
|
|
local_health="ERROR: Local path not writable"
|
|
fi
|
|
|
|
# Controlla remoto
|
|
if ! ssh -o ConnectTimeout=5 -o BatchMode=yes "$REMOTE_USER@$REMOTE_HOST" "test -d $REMOTE_PATH" 2>/dev/null; then
|
|
remote_health="ERROR: Remote connection failed"
|
|
fi
|
|
|
|
echo "$local_health|$remote_health"
|
|
}
|
|
|
|
generate_html_report() {
|
|
local report_file="$REPORT_DIR/sync-dashboard-$(date +%Y%m%d-%H%M%S).html"
|
|
|
|
mkdir -p "$REPORT_DIR"
|
|
|
|
# Raccogli dati
|
|
local sync_status_data=$(check_sync_status)
|
|
local sync_stats_data=$(get_sync_stats)
|
|
local health_data=$(check_system_health)
|
|
|
|
IFS='|' read -r status last_sync last_error <<< "$sync_status_data"
|
|
IFS='|' read -r total_syncs successful_syncs failed_syncs <<< "$sync_stats_data"
|
|
IFS='|' read -r local_health remote_health <<< "$health_data"
|
|
|
|
# Genera HTML
|
|
cat > "$report_file" << EOF
|
|
<!DOCTYPE html>
|
|
<html lang="it">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>NetGescon Sync Dashboard</title>
|
|
<style>
|
|
body {
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
margin: 0;
|
|
padding: 20px;
|
|
background-color: #f5f5f5;
|
|
}
|
|
.dashboard {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
}
|
|
.header {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
padding: 20px;
|
|
border-radius: 10px;
|
|
margin-bottom: 20px;
|
|
text-align: center;
|
|
}
|
|
.cards {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
gap: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
.card {
|
|
background: white;
|
|
padding: 20px;
|
|
border-radius: 10px;
|
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
}
|
|
.card h3 {
|
|
margin-top: 0;
|
|
color: #333;
|
|
}
|
|
.status {
|
|
display: inline-block;
|
|
padding: 5px 10px;
|
|
border-radius: 20px;
|
|
font-weight: bold;
|
|
text-transform: uppercase;
|
|
}
|
|
.status.success { background-color: #d4edda; color: #155724; }
|
|
.status.error { background-color: #f8d7da; color: #721c24; }
|
|
.status.unknown { background-color: #d1ecf1; color: #0c5460; }
|
|
.stats {
|
|
display: flex;
|
|
justify-content: space-around;
|
|
margin-top: 15px;
|
|
}
|
|
.stat {
|
|
text-align: center;
|
|
}
|
|
.stat-value {
|
|
font-size: 2em;
|
|
font-weight: bold;
|
|
color: #667eea;
|
|
}
|
|
.stat-label {
|
|
color: #666;
|
|
font-size: 0.9em;
|
|
}
|
|
.health-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 10px 0;
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
.health-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
.health-ok { color: #28a745; }
|
|
.health-error { color: #dc3545; }
|
|
.logs {
|
|
background: #f8f9fa;
|
|
padding: 15px;
|
|
border-radius: 5px;
|
|
font-family: monospace;
|
|
font-size: 0.9em;
|
|
max-height: 300px;
|
|
overflow-y: auto;
|
|
}
|
|
.timestamp {
|
|
color: #666;
|
|
font-size: 0.9em;
|
|
}
|
|
.footer {
|
|
text-align: center;
|
|
margin-top: 30px;
|
|
color: #666;
|
|
font-size: 0.9em;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="dashboard">
|
|
<div class="header">
|
|
<h1>NetGescon Sync Dashboard</h1>
|
|
<p>Monitoraggio Sincronizzazione Automatica</p>
|
|
<p class="timestamp">Generato il: $(date)</p>
|
|
</div>
|
|
|
|
<div class="cards">
|
|
<div class="card">
|
|
<h3>Stato Sincronizzazione</h3>
|
|
<div class="status $(echo $status | tr '[:upper:]' '[:lower:]')">$status</div>
|
|
<p><strong>Ultima sincronizzazione:</strong> $last_sync</p>
|
|
<p><strong>Ultimo errore:</strong> $last_error</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>Statistiche Oggi</h3>
|
|
<div class="stats">
|
|
<div class="stat">
|
|
<div class="stat-value">$total_syncs</div>
|
|
<div class="stat-label">Totali</div>
|
|
</div>
|
|
<div class="stat">
|
|
<div class="stat-value">$successful_syncs</div>
|
|
<div class="stat-label">Successi</div>
|
|
</div>
|
|
<div class="stat">
|
|
<div class="stat-value">$failed_syncs</div>
|
|
<div class="stat-label">Errori</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>Salute Sistema</h3>
|
|
<div class="health-item">
|
|
<span>Locale:</span>
|
|
<span class="$([ "$local_health" = "OK" ] && echo "health-ok" || echo "health-error")">$local_health</span>
|
|
</div>
|
|
<div class="health-item">
|
|
<span>Remoto:</span>
|
|
<span class="$([ "$remote_health" = "OK" ] && echo "health-ok" || echo "health-error")">$remote_health</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>Log Recenti</h3>
|
|
<div class="logs">
|
|
$(tail -20 "$LOG_FILE" 2>/dev/null | sed 's/&/\&/g; s/</\</g; s/>/\>/g' || echo "Nessun log disponibile")
|
|
</div>
|
|
</div>
|
|
|
|
<div class="footer">
|
|
<p>NetGescon Auto-Sync Monitor v1.0 - $(date)</p>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
EOF
|
|
|
|
echo "$report_file"
|
|
}
|
|
|
|
show_dashboard() {
|
|
clear
|
|
echo -e "${CYAN}╔══════════════════════════════════════════════════════════════╗${NC}"
|
|
echo -e "${CYAN}║ NetGescon Sync Dashboard ║${NC}"
|
|
echo -e "${CYAN}╚══════════════════════════════════════════════════════════════╝${NC}"
|
|
echo
|
|
|
|
# Stato sincronizzazione
|
|
local sync_status_data=$(check_sync_status)
|
|
IFS='|' read -r status last_sync last_error <<< "$sync_status_data"
|
|
|
|
echo -e "${BLUE}📊 STATO SINCRONIZZAZIONE${NC}"
|
|
echo "─────────────────────────────────────────────────────────────"
|
|
case "$status" in
|
|
"SUCCESS")
|
|
echo -e "Stato: ${GREEN}✅ SUCCESSO${NC}"
|
|
;;
|
|
"ERROR")
|
|
echo -e "Stato: ${RED}❌ ERRORE${NC}"
|
|
;;
|
|
*)
|
|
echo -e "Stato: ${YELLOW}❓ SCONOSCIUTO${NC}"
|
|
;;
|
|
esac
|
|
echo "Ultima sincronizzazione: $last_sync"
|
|
echo "Ultimo errore: $last_error"
|
|
echo
|
|
|
|
# Statistiche
|
|
local sync_stats_data=$(get_sync_stats)
|
|
IFS='|' read -r total_syncs successful_syncs failed_syncs <<< "$sync_stats_data"
|
|
|
|
echo -e "${BLUE}📈 STATISTICHE GIORNALIERE${NC}"
|
|
echo "─────────────────────────────────────────────────────────────"
|
|
echo "Sincronizzazioni totali: $total_syncs"
|
|
echo "Successi: $successful_syncs"
|
|
echo "Errori: $failed_syncs"
|
|
echo
|
|
|
|
# Salute sistema
|
|
local health_data=$(check_system_health)
|
|
IFS='|' read -r local_health remote_health <<< "$health_data"
|
|
|
|
echo -e "${BLUE}🏥 SALUTE SISTEMA${NC}"
|
|
echo "─────────────────────────────────────────────────────────────"
|
|
if [[ "$local_health" == "OK" ]]; then
|
|
echo -e "Locale: ${GREEN}✅ $local_health${NC}"
|
|
else
|
|
echo -e "Locale: ${RED}❌ $local_health${NC}"
|
|
fi
|
|
|
|
if [[ "$remote_health" == "OK" ]]; then
|
|
echo -e "Remoto: ${GREEN}✅ $remote_health${NC}"
|
|
else
|
|
echo -e "Remoto: ${RED}❌ $remote_health${NC}"
|
|
fi
|
|
echo
|
|
|
|
# Log recenti
|
|
echo -e "${BLUE}📋 LOG RECENTI${NC}"
|
|
echo "─────────────────────────────────────────────────────────────"
|
|
if [[ -f "$LOG_FILE" ]]; then
|
|
tail -5 "$LOG_FILE" 2>/dev/null || echo "Nessun log disponibile"
|
|
else
|
|
echo "File di log non trovato"
|
|
fi
|
|
echo
|
|
|
|
echo -e "${CYAN}Aggiornato: $(date)${NC}"
|
|
echo -e "${CYAN}Per report HTML: $0 --html${NC}"
|
|
}
|
|
|
|
watch_mode() {
|
|
while true; do
|
|
show_dashboard
|
|
sleep 30
|
|
done
|
|
}
|
|
|
|
main() {
|
|
case "${1:-dashboard}" in
|
|
"dashboard"|"status")
|
|
show_dashboard
|
|
;;
|
|
"watch"|"-w"|"--watch")
|
|
watch_mode
|
|
;;
|
|
"html"|"-h"|"--html")
|
|
local report_file=$(generate_html_report)
|
|
echo "Report HTML generato: $report_file"
|
|
;;
|
|
"help"|"--help")
|
|
echo "NetGescon Sync Monitor"
|
|
echo
|
|
echo "Uso: $0 [COMANDO]"
|
|
echo
|
|
echo "Comandi:"
|
|
echo " dashboard Mostra dashboard testuale (default)"
|
|
echo " watch Modalità watch (aggiorna ogni 30s)"
|
|
echo " html Genera report HTML"
|
|
echo " help Mostra questo aiuto"
|
|
;;
|
|
*)
|
|
echo "Comando non riconosciuto: $1"
|
|
echo "Usa '$0 help' per l'aiuto"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
main "$@"
|