Files
adguard-shield/adguard-shield-watchdog.sh

167 lines
6.0 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
###############################################################################
# AdGuard Shield - Watchdog
# Prüft ob der Hauptservice läuft und startet ihn bei Bedarf neu.
# Wird über adguard-shield-watchdog.timer alle 5 Minuten ausgeführt.
#
# Autor: Patrick Asmus
# E-Mail: support@techniverse.net
# Lizenz: MIT
###############################################################################
set -euo pipefail
INSTALL_DIR="/opt/adguard-shield"
CONFIG_FILE="${INSTALL_DIR}/adguard-shield.conf"
SERVICE_NAME="adguard-shield.service"
LOG_FILE="/var/log/adguard-shield.log"
WATCHDOG_STATE_FILE="/var/lib/adguard-shield/watchdog.state"
# ─── Logging ──────────────────────────────────────────────────────────────────
log() {
local level="$1"
shift
local message="$*"
local timestamp
timestamp="$(date '+%Y-%m-%d %H:%M:%S')"
local log_entry="[$timestamp] [WATCHDOG] [$level] $message"
echo "$log_entry" | tee -a "$LOG_FILE"
}
# ─── Benachrichtigung senden ──────────────────────────────────────────────────
send_watchdog_notification() {
local action="$1" # "recovery" oder "failure"
local detail="$2"
# Konfiguration laden für Benachrichtigungs-Einstellungen
if [[ ! -f "$CONFIG_FILE" ]]; then
return
fi
source "$CONFIG_FILE"
if [[ "${NOTIFY_ENABLED:-false}" != "true" ]]; then
return
fi
local my_hostname
my_hostname=$(hostname)
local title message
if [[ "$action" == "recovery" ]]; then
title="🔄 AdGuard Shield Watchdog"
message="🔄 AdGuard Shield Watchdog auf ${my_hostname}
---
Der Service war ausgefallen und wurde automatisch neu gestartet.
${detail}"
elif [[ "$action" == "failure" ]]; then
title="🚨 AdGuard Shield Watchdog"
message="🚨 AdGuard Shield Watchdog auf ${my_hostname}
---
Der Service konnte NICHT automatisch neu gestartet werden!
Manuelles Eingreifen erforderlich.
${detail}"
fi
case "${NOTIFY_TYPE:-}" in
discord)
local json_payload
json_payload=$(jq -nc --arg msg "$message" '{content: $msg}')
curl -s -H "Content-Type: application/json" \
-d "$json_payload" \
"$NOTIFY_WEBHOOK_URL" &>/dev/null || true
;;
slack)
local json_payload
json_payload=$(jq -nc --arg msg "$message" '{text: $msg}')
curl -s -H "Content-Type: application/json" \
-d "$json_payload" \
"$NOTIFY_WEBHOOK_URL" &>/dev/null || true
;;
gotify)
curl -s -X POST "$NOTIFY_WEBHOOK_URL" \
-F "title=${title}" \
-F "message=${message}" \
-F "priority=5" &>/dev/null || true
;;
ntfy)
if [[ -n "${NTFY_TOPIC:-}" ]]; then
local ntfy_url="${NTFY_SERVER_URL:-https://ntfy.sh}"
local auth_args=()
if [[ -n "${NTFY_TOKEN:-}" ]]; then
auth_args=(-H "Authorization: Bearer ${NTFY_TOKEN}")
fi
curl -s \
-H "Title: ${title}" \
-H "Priority: ${NTFY_PRIORITY:-5}" \
-H "Tags: warning,watchdog" \
"${auth_args[@]}" \
-d "$message" \
"${ntfy_url}/${NTFY_TOPIC}" &>/dev/null || true
fi
;;
generic)
local json_payload
json_payload=$(jq -nc --arg msg "$message" --arg act "watchdog_${action}" \
'{message: $msg, action: $act}')
curl -s -H "Content-Type: application/json" \
-d "$json_payload" \
"$NOTIFY_WEBHOOK_URL" &>/dev/null || true
;;
esac
}
# ─── Hauptlogik ──────────────────────────────────────────────────────────────
main() {
# Verzeichnis für State-Datei sicherstellen
mkdir -p "$(dirname "$WATCHDOG_STATE_FILE")"
# Prüfen ob der Service aktiv ist
if systemctl is-active --quiet "$SERVICE_NAME"; then
# Service läuft falls vorher ausgefallen war, Status zurücksetzen
if [[ -f "$WATCHDOG_STATE_FILE" ]]; then
rm -f "$WATCHDOG_STATE_FILE"
fi
exit 0
fi
# Service läuft NICHT Recovery versuchen
log "WARN" "Service $SERVICE_NAME ist nicht aktiv starte Recovery..."
# Zähler für fehlgeschlagene Recovery-Versuche
local fail_count=0
if [[ -f "$WATCHDOG_STATE_FILE" ]]; then
fail_count=$(cat "$WATCHDOG_STATE_FILE" 2>/dev/null || echo "0")
fi
# systemd reset-failed damit StartLimit zurückgesetzt wird
systemctl reset-failed "$SERVICE_NAME" 2>/dev/null || true
# Service starten
if systemctl start "$SERVICE_NAME" 2>/dev/null; then
# Kurz warten und prüfen ob er auch wirklich läuft
sleep 3
if systemctl is-active --quiet "$SERVICE_NAME"; then
log "INFO" "Service $SERVICE_NAME erfolgreich neu gestartet (Watchdog Recovery)"
send_watchdog_notification "recovery" "Versuch: $((fail_count + 1))"
rm -f "$WATCHDOG_STATE_FILE"
exit 0
fi
fi
# Start fehlgeschlagen
fail_count=$((fail_count + 1))
echo "$fail_count" > "$WATCHDOG_STATE_FILE"
log "ERROR" "Service $SERVICE_NAME konnte nicht gestartet werden (Fehlversuch: $fail_count)"
# Bei jedem 3. Fehlversuch eine Benachrichtigung senden (Spam vermeiden)
if [[ $((fail_count % 3)) -eq 1 ]]; then
send_watchdog_notification "failure" "Fehlversuche: $fail_count
Letzter Fehler: $(systemctl status "$SERVICE_NAME" 2>&1 | tail -5)"
fi
exit 1
}
main