Mise en place d'un journal de connexions

This commit is contained in:
2026-04-21 17:14:16 +02:00
parent b00879cdfa
commit 272ad6d80a
6 changed files with 250 additions and 23 deletions

View File

@@ -57,10 +57,12 @@ TABLES_SET = set(TABLES)
DELAI_MINUTES = 15
RAPPEL_HEURES = 6
SYNOLOGY_CHAT_WEBHOOK_URL = os.getenv("SYNOLOGY_CHAT_WEBHOOK_URL", "").strip()
SYNOLOGY_CHAT_VERIFY_SSL = os.getenv("SYNOLOGY_CHAT_VERIFY_SSL", "true").strip().lower() in (
"1", "true", "yes", "on"
)
def _env_str(name: str, default: str = "") -> str:
return (os.getenv(name, default) or "").strip()
def _env_bool(name: str, default: bool) -> bool:
value = _env_str(name, "1" if default else "0").lower()
return value in ("1", "true", "yes", "on")
# ============================================================
@@ -201,19 +203,33 @@ def should_send_alert(site: str) -> bool:
# NOTIFICATIONS
# ============================================================
def envoyer_chat(titre: str, message: str) -> None:
if not SYNOLOGY_CHAT_WEBHOOK_URL:
logging.warning("Webhook Synology Chat non configuré : notification Chat ignorée.")
def envoyer_chat(site: str, titre: str, message: str) -> None:
webhook = (
_env_str(f"SYNO_CHAT_WEBHOOK_MONITOR_{site}") or
_env_str(f"SYNO_CHAT_WEBHOOK_MONITOR_{site.upper()}") or
_env_str("SYNO_CHAT_WEBHOOK_MONITOR") or
_env_str(f"SYNO_CHAT_WEBHOOK_{site}") or
_env_str(f"SYNO_CHAT_WEBHOOK_{site.upper()}") or
_env_str("SYNO_CHAT_WEBHOOK")
)
if not webhook:
logging.warning(f"Webhook Synology Chat monitor non configuré pour {site} : notification Chat ignorée.")
return
verify_ssl = _env_bool("SYNO_CHAT_VERIFY_SSL", True)
botname = _env_str("SYNO_CHAT_BOTNAME_MONITOR", "Injection données dans tables")
texte = f"{titre}\n{message}"
payload = {"text": texte}
payload: dict[str, str] = {"text": texte}
if botname:
payload["username"] = botname
response = requests.post(
SYNOLOGY_CHAT_WEBHOOK_URL,
webhook,
data={"payload": json.dumps(payload, ensure_ascii=False)},
timeout=10,
verify=SYNOLOGY_CHAT_VERIFY_SSL,
timeout=int(_env_str("SYNO_CHAT_TIMEOUT", "10")),
verify=verify_ssl,
)
response.raise_for_status()
@@ -224,10 +240,10 @@ def envoyer_chat(titre: str, message: str) -> None:
except ValueError:
pass
logging.info("💬 Notification Synology Chat envoyée.")
logging.info("💬 Notification Synology Chat envoyée pour %s.", site)
def envoyer_notifications(sujet: str, message: str) -> None:
def envoyer_notifications(site: str, sujet: str, message: str) -> None:
"""
Envoie mail + chat.
Lève une erreur si au moins un des deux canaux échoue.
@@ -241,7 +257,7 @@ def envoyer_notifications(sujet: str, message: str) -> None:
erreurs.append(f"mail: {e}")
try:
envoyer_chat(sujet, message)
envoyer_chat(site, sujet, message)
except Exception as e:
erreurs.append(f"chat: {e}")
@@ -293,6 +309,7 @@ def traiter_table(cursor, table: str, limite: datetime,
if should_send_alert(table):
try:
envoyer_notifications(
table,
f"⚠️ ALERTE : erreur SQL sur {table}",
f"Erreur SQL détectée sur la table {table}.\n\nDétail :\n{e}"
)
@@ -312,6 +329,7 @@ def traiter_table(cursor, table: str, limite: datetime,
logging.warning(f"⚠️ {table} en défaut (dernier relevé : {last_update})")
try:
envoyer_notifications(
table,
f"⚠️ ALERTE : {table} absence de relevés",
f"Pas de relevés depuis plus de {DELAI_MINUTES} min.\nDernier relevé : {last_update}"
)
@@ -339,6 +357,7 @@ def traiter_table(cursor, table: str, limite: datetime,
message = f"{table} : relevés à nouveau reçus (dernier : {last_update}). Situation normale."
try:
envoyer_notifications(
table,
f"✅ OK : {table} relevés reçus",
message
)
@@ -381,6 +400,7 @@ def main() -> None:
logging.error(f"MySQL KO : {e}")
try:
envoyer_notifications(
"GLOBAL",
"⚠️ ALERTE : Base MySQL inaccessible",
"Connexion MySQL impossible : la surveillance des relevés ne peut pas sexécuter."
)