Compare commits

..

12 Commits

Author SHA1 Message Date
Sebastian Serfling a29c6224a6 add succesd Mail - add all Tables to Feedback 2025-03-31 16:07:29 +02:00
Sebastian Serfling ee5d88f936 add succesd Mail - add all Tables to Feedback 2025-03-31 16:06:32 +02:00
Sebastian Serfling f27ea51835 add succesd Mail 2025-03-31 16:04:26 +02:00
Sebastian Serfling 1f282a848a change RAW to history 2025-03-31 16:02:58 +02:00
Sebastian Serfling 32bc04fed8 change RAW to history 2025-03-27 11:11:56 +01:00
Sebastian Serfling ee2a4d211e change mail send all Time 2025-03-25 09:00:32 +01:00
Sebastian Serfling 40989f978e add Pushover 2025-03-24 10:21:30 +01:00
Sebastian Serfling 011d4c5374 change on bash script python -> python3 2025-03-24 10:16:02 +01:00
Sebastian Serfling 0f179e4364 add -*- coding: utf-8 -*- 2025-03-24 10:14:19 +01:00
Sebastian Serfling c87e01acff add BASH to README.md 2025-03-24 10:09:05 +01:00
Sebastian Serfling 9f52cae834 Merge remote-tracking branch 'origin/master' 2025-03-24 10:05:11 +01:00
Sebastian Serfling 02e432e6da add BASH to README.md 2025-03-24 10:05:03 +01:00
3 changed files with 127 additions and 64 deletions
+11 -5
View File
@@ -8,8 +8,8 @@ Das Skript prüft alle Tabellen, die "RAW." im Namen enthalten, und überprüft,
## Hauptfunktionen ## Hauptfunktionen
- Automatische Erkennung aller Tabellen mit dem Präfix "RAW." - Automatische Erkennung aller Tabellen mit "RAW." im Namen
- Überprüfung des letzten Zeitstempels (standardmäßig in der Spalte "add_date") - Überprüfung, ob Zeitstempel von gestern existieren (standardmäßig in der Spalte "add_date")
- E-Mail-Benachrichtigung bei nicht aktuellen Tabellen - E-Mail-Benachrichtigung bei nicht aktuellen Tabellen
- Testmodus zur Simulation ohne E-Mail-Versand - Testmodus zur Simulation ohne E-Mail-Versand
- Konfiguration über .env-Datei oder Kommandozeilenparameter - Konfiguration über .env-Datei oder Kommandozeilenparameter
@@ -92,7 +92,13 @@ python mysql_timestamp_check.py --host=anderer-host --user=anderer-user --passwo
--smtp-password SMTP-Passwort (Standard: aus .env SMTP_PASSWORD) --smtp-password SMTP-Passwort (Standard: aus .env SMTP_PASSWORD)
``` ```
## Automatisierung ## Automatisierung mit Bash-Skript
```bash
chmod +x run_timestamp_check.sh
```
### Cronjob-Einrichtung
Um das Skript täglich automatisch ausführen zu lassen, können Sie einen Cronjob einrichten: Um das Skript täglich automatisch ausführen zu lassen, können Sie einen Cronjob einrichten:
@@ -101,7 +107,7 @@ Um das Skript täglich automatisch ausführen zu lassen, können Sie einen Cronj
crontab -e crontab -e
# Fügen Sie die folgende Zeile hinzu, um das Skript täglich um 8:00 Uhr auszuführen # Fügen Sie die folgende Zeile hinzu, um das Skript täglich um 8:00 Uhr auszuführen
0 8 * * * /usr/bin/python3 /pfad/zu/mysql_timestamp_check.py 0 4 * * * /pfad/zu/run_timestamp_check.sh
``` ```
## Fehlerbehebung ## Fehlerbehebung
@@ -110,7 +116,7 @@ crontab -e
- **Keine Verbindung zur Datenbank möglich**: Überprüfen Sie die Datenbankverbindungsparameter in der .env-Datei. - **Keine Verbindung zur Datenbank möglich**: Überprüfen Sie die Datenbankverbindungsparameter in der .env-Datei.
- **Keine E-Mail wird gesendet**: Stellen Sie sicher, dass die SMTP-Konfiguration korrekt ist. Verwenden Sie den Testmodus `--test`, um die gefundenen Probleme ohne E-Mail-Versand anzuzeigen. - **Keine E-Mail wird gesendet**: Stellen Sie sicher, dass die SMTP-Konfiguration korrekt ist. Verwenden Sie den Testmodus `--test`, um die gefundenen Probleme ohne E-Mail-Versand anzuzeigen.
- **Skript kann keine Tabellen finden**: Stellen Sie sicher, dass Tabellen mit dem Präfix "RAW." in der Datenbank existieren. - **Skript kann keine Tabellen finden**: Stellen Sie sicher, dass Tabellen mit "RAW." im Namen in der Datenbank existieren.
### Debug-Tipps ### Debug-Tipps
+47 -43
View File
@@ -1,7 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-
import mysql.connector import mysql.connector
import datetime import datetime
import smtplib import smtplib
import ssl
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
import argparse import argparse
@@ -12,7 +14,7 @@ from dotenv import load_dotenv
def get_tables_from_db(connection): def get_tables_from_db(connection):
""" """
Holt die Liste der zu überprüfenden Tabellen, die 'RAW.' im Namen enthalten Holt die Liste der zu überprüfenden Tabellen, die 'history.' im Namen enthalten
Returns: Returns:
list: Liste der Tabellennamen list: Liste der Tabellennamen
@@ -25,14 +27,14 @@ def get_tables_from_db(connection):
tables = [] tables = []
for (table,) in cursor.fetchall(): for (table,) in cursor.fetchall():
if 'RAW.' in table: if 'history.' in table:
# Tabellennamen mit Backticks versehen # Tabellennamen mit Backticks versehen
tables.append(f"Kunden.`{table}`") tables.append(f"Kunden.`{table}`")
cursor.close() cursor.close()
if not tables: if not tables:
print("Warnung: Keine Tabellen gefunden, die 'RAW.' enthalten.") print("Warnung: Keine Tabellen gefunden, die 'history.' enthalten.")
else: else:
print(f"Gefundene zu überprüfende Tabellen: {', '.join(tables)}") print(f"Gefundene zu überprüfende Tabellen: {', '.join(tables)}")
@@ -46,7 +48,9 @@ def check_timestamp(connection, tables, timestamp_column, email_config, test_mod
""" """
Überprüft, ob der letzte Zeitstempel in jeder angegebenen Tabelle von gestern ist. Überprüft, ob der letzte Zeitstempel in jeder angegebenen Tabelle von gestern ist.
Sendet eine E-Mail mit den Namen der Tabellen, die nicht aktuell sind oder Sendet eine E-Mail mit den Namen der Tabellen, die nicht aktuell sind oder
gibt die Nachricht auf der Konsole aus, wenn test_mode=True. eine Bestätigungsmail, wenn alle Tabellen aktuell sind. Im Erfolgsfall wird
auch die Liste der geprüften Tabellen mit aufgeführt.
Im Testmodus wird nur auf der Konsole ausgegeben.
""" """
cursor = connection.cursor() cursor = connection.cursor()
@@ -81,36 +85,46 @@ def check_timestamp(connection, tables, timestamp_column, email_config, test_mod
except mysql.connector.Error as err: except mysql.connector.Error as err:
print(f"Fehler beim Überprüfen der Tabelle {table}: {err}") print(f"Fehler beim Überprüfen der Tabelle {table}: {err}")
outdated_tables.append(f"{table} (Fehler: {err}") outdated_tables.append(f"{table} (Fehler: {err})")
# Cursor schließen # Cursor schließen
cursor.close() cursor.close()
# Wenn es nicht aktuelle Tabellen gibt, sende eine E-Mail oder gib Meldung aus # E-Mail Inhalt und Betreff anpassen, je nachdem ob es fehlerhafte Tabellen gibt oder nicht
if outdated_tables: if outdated_tables:
subject = f"Warnung: Nicht aktuelle Tabellen in Datenbank {database}"
body_intro = (
f"Hallo,\n\n"
f"die folgenden Tabellen in der Datenbank '{database}' haben keinen aktuellen Zeitstempel von gestern:\n"
)
body_tables = "\n".join(f"- {table}" for table in outdated_tables)
body_footer = "\n\nBitte überprüfen Sie diese Tabellen.\n\nDies ist eine automatisch generierte Nachricht."
else:
subject = f"Bestätigung: Alle Tabellen in Datenbank {database} sind aktuell"
body_intro = (
f"Hallo,\n\n"
f"alle zu überprüfenden Tabellen in der Datenbank '{database}' enthalten aktuelle Zeitstempel von gestern.\n\n"
"Folgende Tabellen wurden überprüft:\n"
)
body_tables = "\n".join(f"- {table}" for table in tables)
body_footer = "\n\nDies ist eine automatisch generierte Nachricht."
# Wenn Testmodus aktiviert, Ausgabe auf Konsole
if test_mode: if test_mode:
print("\n--- TEST MODUS: E-Mail würde gesendet werden ---") print("\n--- TEST MODUS: E-Mail würde gesendet werden ---")
print(f"Betreff: Warnung: Nicht aktuelle Tabellen in Datenbank {database}") print(f"Betreff: {subject}")
print("Inhalt:") print("Inhalt:")
print("Hallo,") print(body_intro + body_tables + body_footer)
print(
f"\ndie folgenden Tabellen in der Datenbank '{database}' haben keinen aktuellen Zeitstempel von gestern:")
for table in outdated_tables:
print(f"- {table}")
print("\nBitte überprüfen Sie diese Tabellen.")
print("\nDies ist eine automatisch generierte Nachricht.")
print("--- ENDE TEST MODUS ---\n") print("--- ENDE TEST MODUS ---\n")
else: else:
send_email(outdated_tables, database, email_config) send_email(subject, body_intro, body_tables, body_footer, email_config)
return False
else: return not outdated_tables
print("Alle Tabellen sind aktuell.")
return True
def send_email(outdated_tables, database, email_config): def send_email(subject, body_intro, body_tables, body_footer, email_config):
""" """
Sendet eine E-Mail mit der Liste der nicht aktuellen Tabellen. Sendet eine E-Mail mit dem angegebenen Betreff und Inhalt.
""" """
sender_email = email_config["sender"] sender_email = email_config["sender"]
receiver_email = email_config["receiver"] receiver_email = email_config["receiver"]
@@ -123,27 +137,19 @@ def send_email(outdated_tables, database, email_config):
message = MIMEMultipart() message = MIMEMultipart()
message["From"] = sender_email message["From"] = sender_email
message["To"] = receiver_email message["To"] = receiver_email
message["Subject"] = f"Warnung: Nicht aktuelle Tabellen in Datenbank {database}" message["Subject"] = subject
# E-Mail-Inhalt
body = f"""
Hallo,
die folgenden Tabellen in der Datenbank '{database}' haben keinen aktuellen Zeitstempel von gestern:
{chr(10).join('- ' + table for table in outdated_tables)}
Bitte überprüfen Sie diese Tabellen.
Dies ist eine automatisch generierte Nachricht.
"""
# E-Mail-Inhalt zusammenfügen
body = f"{body_intro}{chr(10) if body_tables else ''}{body_tables}{body_footer}"
message.attach(MIMEText(body, "plain")) message.attach(MIMEText(body, "plain"))
try: try:
# Verbindung zum SMTP-Server herstellen # Verbindung zum SMTP-Server herstellen mit TLS
context = ssl.create_default_context()
server = smtplib.SMTP(smtp_server, smtp_port) server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls() # TLS-Verschlüsselung aktivieren server.ehlo()
server.starttls(context=context)
server.ehlo()
# Anmelden (falls erforderlich) # Anmelden (falls erforderlich)
if smtp_password: if smtp_password:
@@ -198,8 +204,7 @@ def main():
# Prüfe, ob erforderliche DB-Parameter vorhanden sind # Prüfe, ob erforderliche DB-Parameter vorhanden sind
if not user or not password or not database: if not user or not password or not database:
print( print("Fehler: MySQL-Benutzer, Passwort und Datenbankname müssen entweder in der .env-Datei oder als Parameter angegeben werden!")
"Fehler: MySQL-Benutzer, Passwort und Datenbankname müssen entweder in der .env-Datei oder als Parameter angegeben werden!")
sys.exit(1) sys.exit(1)
# Verbindung zur Datenbank herstellen # Verbindung zur Datenbank herstellen
@@ -230,12 +235,11 @@ def main():
# Wenn nicht im Testmodus, prüfe ob E-Mail-Parameter angegeben wurden # Wenn nicht im Testmodus, prüfe ob E-Mail-Parameter angegeben wurden
if not test_mode: if not test_mode:
if not email_config["sender"] or not email_config["receiver"]: if not email_config["sender"] or not email_config["receiver"]:
print( print("Fehler: E-Mail-Absender und -Empfänger müssen entweder in der .env-Datei oder als Parameter angegeben werden!")
"Fehler: E-Mail-Absender und -Empfänger müssen entweder in der .env-Datei oder als Parameter angegeben werden!")
connection.close() connection.close()
sys.exit(1) sys.exit(1)
# Tabellen aus der Datenbanktabelle holen # Tabellen aus der Datenbank holen
tables = get_tables_from_db(connection) tables = get_tables_from_db(connection)
if not tables: if not tables:
@@ -247,7 +251,7 @@ def main():
timestamp_column = args.timestamp_column timestamp_column = args.timestamp_column
print(f"Überprüfe Zeitstempel in Spalte: {timestamp_column}") print(f"Überprüfe Zeitstempel in Spalte: {timestamp_column}")
# Timestamp-Überprüfung durchführen # Timestamp-Überprüfung durchführen und entsprechende E-Mail senden
check_timestamp( check_timestamp(
connection, connection,
tables, tables,
+64 -11
View File
@@ -10,13 +10,56 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# Log-Datei # Log-Datei
LOG_FILE="${SCRIPT_DIR}/timestamp_check_$(date +%Y-%m-%d).log" LOG_FILE="${SCRIPT_DIR}/timestamp_check_$(date +%Y-%m-%d).log"
# Python-Umgebung aktivieren (falls eine virtuelle Umgebung verwendet wird) # Pushover-Konfiguration
# Auskommentieren, wenn keine virtuelle Umgebung verwendet wird # Diese Werte sollten in einer separaten Konfigurationsdatei gesetzt oder
# source "${SCRIPT_DIR}/venv/bin/activate" # als Umgebungsvariablen bereitgestellt werden
PUSHOVER_USER_KEY="uo2sf2pmrtjvt8auu786fviabimimr" # Dein User Key
PUSHOVER_API_TOKEN="awe7dpqsh73muuk12qwa4pk5eie99y" # Dein API Token/Application Key
# Funktion zum Senden von Pushover-Benachrichtigungen
send_pushover() {
local title="$1"
local message="$2"
local priority="${3:-0}" # 0 ist normale Priorität, 1 ist hoch, 2 ist Notfall
# Überprüfen, ob CURL installiert ist
if ! command -v curl &> /dev/null; then
echo "WARNUNG: curl ist nicht installiert. Pushover-Benachrichtigung kann nicht gesendet werden." | tee -a "$LOG_FILE"
return 1
fi
# Überprüfen, ob Pushover-Schlüssel konfiguriert sind
if [[ "$PUSHOVER_USER_KEY" == "dein-user-key" || "$PUSHOVER_API_TOKEN" == "dein-api-token" ]]; then
echo "WARNUNG: Pushover-Schlüssel sind nicht konfiguriert. Benachrichtigung nicht gesendet." | tee -a "$LOG_FILE"
return 1
fi
# Senden der Pushover-Benachrichtigung
curl -s \
--form-string "token=$PUSHOVER_API_TOKEN" \
--form-string "user=$PUSHOVER_USER_KEY" \
--form-string "title=$title" \
--form-string "message=$message" \
--form-string "priority=$priority" \
https://api.pushover.net/1/messages.json >/dev/null
local result=$?
if [ $result -eq 0 ]; then
echo "Pushover-Benachrichtigung gesendet: $title" | tee -a "$LOG_FILE"
else
echo "Fehler beim Senden der Pushover-Benachrichtigung (Fehlercode: $result)" | tee -a "$LOG_FILE"
fi
return $result
}
# Start des Skripts loggen # Start des Skripts loggen
echo "$(date +"%Y-%m-%d %H:%M:%S") - Starte MySQL Timestamp Check" | tee -a "$LOG_FILE" echo "$(date +"%Y-%m-%d %H:%M:%S") - Starte MySQL Timestamp Check" | tee -a "$LOG_FILE"
# Python-Umgebung aktivieren (falls eine virtuelle Umgebung verwendet wird)
# Auskommentieren, wenn keine virtuelle Umgebung verwendet wird
# source "${SCRIPT_DIR}/venv/bin/activate"
# Zum Skriptverzeichnis wechseln # Zum Skriptverzeichnis wechseln
cd "$SCRIPT_DIR" cd "$SCRIPT_DIR"
@@ -26,10 +69,7 @@ cd "$SCRIPT_DIR"
# --timestamp-column=spaltenname: falls andere Spalte als add_date verwendet werden soll # --timestamp-column=spaltenname: falls andere Spalte als add_date verwendet werden soll
# Normale Ausführung # Normale Ausführung
python mysql_timestamp_check.py 2>&1 | tee -a "$LOG_FILE" python3 mysql_timestamp_check.py 2>&1 | tee -a "$LOG_FILE"
# Testmodus (auskommentiert)
# python mysql_timestamp_check.py --test 2>&1 | tee -a "$LOG_FILE"
# Exit-Code des Python-Skripts erhalten # Exit-Code des Python-Skripts erhalten
EXIT_CODE=${PIPESTATUS[0]} EXIT_CODE=${PIPESTATUS[0]}
@@ -37,10 +77,23 @@ EXIT_CODE=${PIPESTATUS[0]}
# Ende des Skripts loggen # Ende des Skripts loggen
echo "$(date +"%Y-%m-%d %H:%M:%S") - MySQL Timestamp Check beendet (Exit-Code: $EXIT_CODE)" | tee -a "$LOG_FILE" echo "$(date +"%Y-%m-%d %H:%M:%S") - MySQL Timestamp Check beendet (Exit-Code: $EXIT_CODE)" | tee -a "$LOG_FILE"
# E-Mail bei Fehler im Skript selbst (nicht bei fehlenden Daten, da das Python-Skript dies bereits handhabt) # Benachrichtigung bei Fehlern im Skript selbst oder wenn Python wegen nicht aktueller Tabellen mit Exit-Code 1 beendet wurde
if [ $EXIT_CODE -ne 0 ] && [ $EXIT_CODE -ne 1 ]; then if [ $EXIT_CODE -ne 0 ]; then
# Hier kann optional eine E-Mail für Fehler im Skript selbst gesendet werden # Art des Fehlers ermitteln
echo "Fehler beim Ausführen des Timestamp-Check-Skripts. Bitte überprüfen Sie die Log-Datei $LOG_FILE" | tee -a "$LOG_FILE" if [ $EXIT_CODE -eq 1 ]; then
# Exit-Code 1 = Nicht aktuelle Tabellen gefunden (E-Mail wurde bereits vom Python-Skript gesendet)
PUSHOVER_TITLE="MySQL Timestamp Check: Nicht aktuelle Tabellen"
PUSHOVER_MESSAGE="Einige Tabellen haben keine Daten von gestern. Details wurden per E-Mail gesendet."
PUSHOVER_PRIORITY=1 # Höhere Priorität
else
# Andere Exit-Codes = Fehler im Skript selbst
PUSHOVER_TITLE="MySQL Timestamp Check: Fehler im Skript"
PUSHOVER_MESSAGE="Fehler beim Ausführen des Timestamp-Check-Skripts (Exit-Code: $EXIT_CODE). Bitte überprüfen Sie die Log-Datei."
PUSHOVER_PRIORITY=2 # Notfall-Priorität
fi
# Pushover-Benachrichtigung senden
send_pushover "$PUSHOVER_TITLE" "$PUSHOVER_MESSAGE" "$PUSHOVER_PRIORITY"
fi fi
exit $EXIT_CODE exit $EXIT_CODE