Logging: Automatische Log-Bereinigung nach 7 Tagen implementiert
This commit is contained in:
15
LOGGING.md
15
LOGGING.md
@@ -7,7 +7,8 @@ Das Wordle-Helper Logging-System protokolliert Seitenaufrufe und Suchanfragen oh
|
||||
- **Verzeichnis:** `logs/`
|
||||
- **Datei:** `logs/app.log`
|
||||
- **Format:** UTF-8
|
||||
- **Rotation:** Keine automatische Rotation (manuell oder über externe Tools)
|
||||
- **Rotation:** Automatische Rotation nach 7 Tagen
|
||||
- **Backup:** Komprimierte Backup-Dateien (30 Tage aufbewahrt)
|
||||
- **Verzeichnis:** Wird automatisch erstellt, falls es nicht existiert
|
||||
|
||||
## Protokollierte Ereignisse
|
||||
@@ -50,12 +51,22 @@ logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
logging.FileHandler('app.log', encoding='utf-8'),
|
||||
logging.FileHandler(logs_dir / 'app.log', encoding='utf-8'),
|
||||
logging.StreamHandler()
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Automatische Log-Bereinigung
|
||||
|
||||
Das System bereinigt automatisch alte Log-Dateien:
|
||||
|
||||
- **Rotation:** Nach 7 Tagen wird die aktuelle Log-Datei komprimiert
|
||||
- **Backup:** Komprimierte Dateien werden 30 Tage aufbewahrt
|
||||
- **Format:** Backup-Dateien: `app_YYYYMMDD_HHMMSS.log.gz`
|
||||
- **Trigger:** Bereinigung wird bei jedem Seitenaufruf geprüft
|
||||
- **Fehlerbehandlung:** Fehler bei der Bereinigung werden geloggt
|
||||
|
||||
## Log-Analyse
|
||||
|
||||
Die Log-Datei kann mit Standard-Tools analysiert werden:
|
||||
|
38
app.py
38
app.py
@@ -1,7 +1,8 @@
|
||||
from pathlib import Path
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime
|
||||
import os
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Tuple, Dict, List
|
||||
from flask import Flask, render_template, request, send_from_directory
|
||||
|
||||
@@ -47,6 +48,38 @@ def log_search_query(search_params: dict, user_agent: str = None):
|
||||
|
||||
logger.info(f"SEARCH: pos='{pos_str}' includes='{includes}' excludes='{excludes}' sources={sources} | User-Agent: {user_agent_clean}")
|
||||
|
||||
def cleanup_old_logs():
|
||||
"""Bereinigt Log-Dateien älter als 7 Tage"""
|
||||
try:
|
||||
log_file = logs_dir / 'app.log'
|
||||
if log_file.exists():
|
||||
# Prüfe Datei-Alter
|
||||
file_age = datetime.now() - datetime.fromtimestamp(log_file.stat().st_mtime)
|
||||
if file_age > timedelta(days=7):
|
||||
# Log-Datei komprimieren und umbenennen
|
||||
backup_name = f"app_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log.gz"
|
||||
backup_path = logs_dir / backup_name
|
||||
|
||||
# Komprimiere mit gzip (falls verfügbar)
|
||||
import gzip
|
||||
with open(log_file, 'rb') as f_in:
|
||||
with gzip.open(backup_path, 'wb') as f_out:
|
||||
f_out.writelines(f_in)
|
||||
|
||||
# Lösche alte Log-Datei
|
||||
log_file.unlink()
|
||||
logger.info(f"Log-Datei komprimiert und gesichert: {backup_name}")
|
||||
|
||||
# Lösche alte Backup-Dateien (älter als 30 Tage)
|
||||
for backup_file in logs_dir.glob("app_*.log.gz"):
|
||||
backup_age = datetime.now() - datetime.fromtimestamp(backup_file.stat().st_mtime)
|
||||
if backup_age > timedelta(days=30):
|
||||
backup_file.unlink()
|
||||
logger.info(f"Alte Backup-Datei gelöscht: {backup_file.name}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler bei der Log-Bereinigung: {e}")
|
||||
|
||||
|
||||
def load_words() -> Tuple[List[str], Dict[str, List[str]]]:
|
||||
data_dir = Path(__file__).parent / "data"
|
||||
@@ -92,6 +125,9 @@ def filter_words(words: List[str], position_letters: List[str], includes_text: s
|
||||
|
||||
@app.route("/", methods=["GET", "POST"])
|
||||
def index():
|
||||
# Log-Bereinigung bei jedem Seitenaufruf prüfen (nur alle 24h)
|
||||
cleanup_old_logs()
|
||||
|
||||
# Seitenaufruf protokollieren
|
||||
log_page_view("index", request.headers.get('User-Agent'))
|
||||
|
||||
|
Reference in New Issue
Block a user