From 633a30180c8228fad5fce1ad17e7d768fb8d41d5 Mon Sep 17 00:00:00 2001 From: oberon Date: Thu, 12 Feb 2026 22:12:35 +0100 Subject: [PATCH] cleanup for logfiles, added log for info and error, better logviewer in admin panel --- app.py | 131 +++++++++++++++++++++++++++++--------- templates/admin_logs.html | 21 ++++-- 2 files changed, 114 insertions(+), 38 deletions(-) diff --git a/app.py b/app.py index ea3554b..a3c57ae 100644 --- a/app.py +++ b/app.py @@ -2,10 +2,39 @@ import os import json import logging +import shutil from logging.handlers import TimedRotatingFileHandler -from datetime import datetime +from datetime import datetime, timedelta from flask import Flask, render_template, redirect, url_for, send_from_directory, request, jsonify +# ── Cleanup Log-Files ──────────────────────────────────────────────────────────────── +def cleanup_old_log_dirs(max_age_days=90): + """Löscht Monatsordner in logs/, die älter als max_age_days sind""" + if not os.path.exists(LOG_DIR): + return + + cutoff_date = datetime.now() - timedelta(days=max_age_days) + cutoff_str = cutoff_date.strftime('%Y-%m') + + for subdir in os.listdir(LOG_DIR): + subdir_path = os.path.join(LOG_DIR, subdir) + if os.path.isdir(subdir_path): + try: + # subdir ist z. B. "2025-11" + subdir_date = datetime.strptime(subdir, '%Y-%m') + if subdir_date < cutoff_date: + logger.info(f"Lösche alten Log-Ordner: {subdir_path}") + shutil.rmtree(subdir_path) + except ValueError: + # Ungültiges Datumsformat → überspringen + pass + except Exception as e: + logger.error(f"Fehler beim Löschen von {subdir_path}: {e}") + +# Beim Start aufrufen +cleanup_old_log_dirs(90) +logger.info("Alte Log-Ordner bereinigt") + # ── Bluetooth ──────────────────────────────────────────────────────────────── from mkconnect.mouldking.MouldKing import MouldKing from mkconnect.tracer.TracerConsole import TracerConsole @@ -22,36 +51,45 @@ os.makedirs(app.config['CONFIG_DIR'], exist_ok=True) LOG_DIR = 'logs' os.makedirs(LOG_DIR, exist_ok=True) -# Täglich neuer Ordner (z. B. logs/2026-02) +# Täglicher Unterordner today = datetime.now().strftime('%Y-%m') current_log_subdir = os.path.join(LOG_DIR, today) os.makedirs(current_log_subdir, exist_ok=True) -# Log-Datei: z. B. logs/2026-02/12.log -log_filename = os.path.join(current_log_subdir, datetime.now().strftime('%d.log')) +# Basis-Dateiname (ohne Endung) +base_filename = os.path.join(current_log_subdir, datetime.now().strftime('%d')) -# Logging konfigurieren +# Handler für INFO+ +info_handler = logging.FileHandler(f"{base_filename}-info.log") +info_handler.setLevel(logging.INFO) +info_handler.setFormatter(logging.Formatter( + '%(asctime)s | %(levelname)-8s | %(message)s', + datefmt='%Y-%m-%d %H:%M:%S' +)) + +# Handler für WARNING+ (inkl. ERROR, CRITICAL) +error_handler = logging.FileHandler(f"{base_filename}-error.log") +error_handler.setLevel(logging.WARNING) +error_handler.setFormatter(logging.Formatter( + '%(asctime)s | %(levelname)-8s | %(message)s\n%(pathname)s:%(lineno)d\n', + datefmt='%Y-%m-%d %H:%M:%S' +)) + +# Logger konfigurieren logger = logging.getLogger(__name__) -logger.setLevel(logging.INFO) +logger.setLevel(logging.DEBUG) # DEBUG, damit alles durchkommt -# Handler: schreibt in die tagesaktuelle Datei -handler = logging.FileHandler(log_filename) -handler.setLevel(logging.INFO) +logger.handlers.clear() # Alte Handler entfernen +logger.addHandler(info_handler) +logger.addHandler(error_handler) -# Format -formatter = logging.Formatter('%(asctime)s | %(levelname)-8s | %(message)s', datefmt='%Y-%m-%d %H:%M:%S') -handler.setFormatter(formatter) +# Optional: Auch in Konsole +console = logging.StreamHandler() +console.setLevel(logging.INFO) +console.setFormatter(info_handler.formatter) +logger.addHandler(console) -# Alten Handler entfernen (falls schon gesetzt) -logger.handlers.clear() -logger.addHandler(handler) - -# Optional: Auch in Konsole loggen (für Entwicklung) -console_handler = logging.StreamHandler() -console_handler.setFormatter(formatter) -logger.addHandler(console_handler) - -logger.info("Logging neu initialisiert – Tages-Log: " + log_filename) +logger.info("Logging getrennt initialisiert: info.log + error.log") # Bluetooth-Komponenten (einmalig initialisieren) @@ -252,15 +290,38 @@ def admin_delete_config(filename): @app.route('/admin/logs') -def admin_logs(): - log_path = 'app.log' - if os.path.exists(log_path): - with open(log_path, 'r', encoding='utf-8') as f: - logs = f.read() - else: - logs = "Keine Logs vorhanden." +@app.route('/admin/logs/') +def admin_logs(date=None): + if date is None: + date = datetime.now().strftime('%d') - return render_template('admin_logs.html', logs=logs) + today = datetime.now().strftime('%Y-%m') + log_dir = os.path.join(LOG_DIR, today) + + if not os.path.exists(log_dir): + return render_template('admin_logs.html', logs="Keine Logs für diesen Tag.", date=date, dates=[]) + + # Verfügbare Tage (alle .log-Dateien im Monatsordner) + dates = sorted([ + f.split('-')[0] for f in os.listdir(log_dir) + if f.endswith('-info.log') or f.endswith('-error.log') + ], reverse=True) + + # Logs des gewählten Tages laden + info_path = os.path.join(log_dir, f"{date}-info.log") + error_path = os.path.join(log_dir, f"{date}-error.log") + + logs = [] + if os.path.exists(info_path): + with open(info_path, 'r', encoding='utf-8') as f: + logs.append("=== INFO-LOG ===\n" + f.read()) + if os.path.exists(error_path): + with open(error_path, 'r', encoding='utf-8') as f: + logs.append("=== ERROR-LOG ===\n" + f.read()) + + log_content = "\n\n".join(logs) if logs else "Keine Logs für diesen Tag." + + return render_template('admin_logs.html', logs=log_content, date=date, dates=dates) @app.route('/configs/') @@ -451,4 +512,12 @@ def api_reconnect(): if __name__ == '__main__': - app.run(host='0.0.0.0', port=5000, debug=True) \ No newline at end of file + app.run(host='0.0.0.0', port=5000, debug=True) + +def daily_cleanup(): + while True: + cleanup_old_log_dirs(90) + time.sleep(86400) # 24 Stunden + +cleanup_thread = threading.Thread(target=daily_cleanup, daemon=True) +cleanup_thread.start() \ No newline at end of file diff --git a/templates/admin_logs.html b/templates/admin_logs.html index 2005184..7921399 100644 --- a/templates/admin_logs.html +++ b/templates/admin_logs.html @@ -1,17 +1,24 @@ {% extends "base.html" %} -{% block title %}Logs – MK Control{% endblock %} +{% block title %}Logs – {{ date }}. {{ today[:4] }}-{{ today[5:] }}{% endblock %} {% block content %}
-

Log-Datei (app.log)

- -
+  

Logs – {{ date }}. {{ today[:4] }}-{{ today[5:] }}

+ +
+ + +
+ +
 {{ logs | safe }}
   
- + Zurück zum Admin
{% endblock %} \ No newline at end of file