Files
stechuhr3/scripts/health-check.sh

211 lines
6.3 KiB
Bash
Executable File

#!/bin/bash
# =============================================================================
# TimeClock v3 - Health-Check Script
# =============================================================================
# Überwacht die Verfügbarkeit des Backend-API und startet bei Bedarf neu
#
# Installation:
# sudo cp health-check.sh /usr/local/bin/
# sudo chmod +x /usr/local/bin/health-check.sh
#
# Cronjob einrichten (alle 5 Minuten):
# crontab -e
# */5 * * * * /usr/local/bin/health-check.sh >> /var/log/timeclock/health-check.log 2>&1
#
# Manuell ausführen:
# /usr/local/bin/health-check.sh
# =============================================================================
set -e
# Konfiguration
API_URL="http://localhost:3010/api/health"
SERVICE_NAME="timeclock-backend"
USE_PM2=true # true für PM2, false für systemd
LOG_FILE="/var/log/timeclock/health-check.log"
MAX_RETRIES=3
RETRY_DELAY=5 # Sekunden zwischen Versuchen
# Datum
DATE=$(date '+%Y-%m-%d %H:%M:%S')
# Logging
log() {
echo "[$DATE] $1" | tee -a "$LOG_FILE"
}
log_error() {
echo "[$DATE] ERROR: $1" | tee -a "$LOG_FILE" >&2
}
# =============================================================================
# Health-Check durchführen
# =============================================================================
check_health() {
# Versuche Health-Endpunkt zu erreichen
if curl -sf "$API_URL" > /dev/null 2>&1; then
return 0 # Erfolg
else
return 1 # Fehler
fi
}
# =============================================================================
# Service neu starten
# =============================================================================
restart_service() {
log "⚠️ Versuche Service neu zu starten..."
if [ "$USE_PM2" = true ]; then
# PM2
if command -v pm2 &> /dev/null; then
if pm2 restart "$SERVICE_NAME" > /dev/null 2>&1; then
log "✅ Service mit PM2 neu gestartet"
return 0
else
log_error "PM2-Neustart fehlgeschlagen!"
return 1
fi
else
log_error "PM2 nicht gefunden!"
return 1
fi
else
# systemd
if sudo systemctl restart "$SERVICE_NAME"; then
log "✅ Service mit systemd neu gestartet"
return 0
else
log_error "systemd-Neustart fehlgeschlagen!"
return 1
fi
fi
}
# =============================================================================
# Benachrichtigung senden
# =============================================================================
send_notification() {
local status=$1
local message=$2
# Optional: E-Mail-Benachrichtigung
SEND_EMAIL=false
EMAIL_TO="admin@tsschulz.de"
if [ "$SEND_EMAIL" = true ] && command -v mail &> /dev/null; then
echo "$message
Zeitpunkt: $DATE
API-URL: $API_URL
Service: $SERVICE_NAME
--
TimeClock v3 Health-Check System
" | mail -s "$status TimeClock Backend" "$EMAIL_TO"
fi
# Optional: Webhook-Benachrichtigung (z.B. Discord, Slack)
WEBHOOK_URL=""
if [ -n "$WEBHOOK_URL" ]; then
curl -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d "{\"content\": \"$status $message\"}" \
> /dev/null 2>&1
fi
}
# =============================================================================
# Hauptlogik
# =============================================================================
# Erstelle Log-Verzeichnis falls nicht vorhanden
mkdir -p "$(dirname $LOG_FILE)"
# Prüfe ob Service läuft
if [ "$USE_PM2" = true ]; then
if ! pm2 list | grep -q "$SERVICE_NAME.*online"; then
log_error "⚠️ Service läuft nicht (PM2)!"
restart_service
sleep 10
fi
else
if ! systemctl is-active --quiet "$SERVICE_NAME"; then
log_error "⚠️ Service läuft nicht (systemd)!"
restart_service
sleep 10
fi
fi
# Health-Check mit Retries
SUCCESS=false
for i in $(seq 1 $MAX_RETRIES); do
if check_health; then
# Nur beim ersten Check des Tages loggen (um Log-Spam zu vermeiden)
CURRENT_HOUR=$(date +%H)
CURRENT_MINUTE=$(date +%M)
if [ "$CURRENT_HOUR" = "00" ] && [ "$CURRENT_MINUTE" -lt 6 ]; then
log "✅ Health-Check erfolgreich"
fi
SUCCESS=true
break
else
if [ $i -lt $MAX_RETRIES ]; then
log "⚠️ Health-Check fehlgeschlagen (Versuch $i/$MAX_RETRIES), warte $RETRY_DELAY Sekunden..."
sleep $RETRY_DELAY
fi
fi
done
# Wenn alle Versuche fehlschlagen
if [ "$SUCCESS" = false ]; then
log_error "❌ Health-Check fehlgeschlagen nach $MAX_RETRIES Versuchen!"
# Service neu starten
if restart_service; then
# Nach Neustart erneut prüfen
sleep 10
if check_health; then
log "✅ Service nach Neustart wieder erreichbar"
send_notification "⚠️ RECOVERED:" "TimeClock Backend wurde neu gestartet und ist wieder erreichbar."
else
log_error "❌ Service auch nach Neustart nicht erreichbar!"
send_notification "🚨 CRITICAL:" "TimeClock Backend ist auch nach Neustart nicht erreichbar! Manuelle Intervention erforderlich."
fi
else
log_error "❌ Service-Neustart fehlgeschlagen!"
send_notification "🚨 CRITICAL:" "TimeClock Backend-Neustart fehlgeschlagen! Manuelle Intervention erforderlich."
fi
fi
# =============================================================================
# Zusätzliche Checks (optional)
# =============================================================================
# CPU & Memory Usage prüfen
if [ "$USE_PM2" = true ] && command -v pm2 &> /dev/null; then
PM2_STATUS=$(pm2 jlist | jq -r ".[] | select(.name==\"$SERVICE_NAME\") | \"CPU: \(.monit.cpu)%, Memory: \(.monit.memory / 1024 / 1024 | floor)MB\"" 2>/dev/null || echo "N/A")
# Nur bei hohem Ressourcenverbrauch loggen
# (Optional: weitere Logik implementieren)
fi
# Disk Space prüfen
DISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$DISK_USAGE" -gt 90 ]; then
log_error "⚠️ Festplattenspeicher kritisch: ${DISK_USAGE}%"
send_notification "⚠️ WARNING:" "Festplattenspeicher auf TimeClock-Server kritisch: ${DISK_USAGE}%"
fi
exit 0