added logging

This commit is contained in:
2026-08-30 12:01:46 +02:00
parent ea591fc8fb
commit c1d731f85d
6 changed files with 92 additions and 4 deletions
+56 -1
View File
@@ -1,9 +1,13 @@
from __future__ import annotations
import logging
from logging.handlers import RotatingFileHandler
import os
import sys
import threading
from flask import Flask, Response, abort, jsonify, render_template, url_for
from werkzeug.exceptions import HTTPException
from .collector import Collector
from .config import Config
@@ -28,6 +32,49 @@ class PrefixMiddleware:
return [b"Not Found\n"]
def configure_logging(app: Flask) -> None:
log_path = app.config["LOG_FILE"]
log_path.parent.mkdir(parents=True, exist_ok=True)
handler = RotatingFileHandler(
log_path,
maxBytes=app.config["LOG_MAX_BYTES"],
backupCount=app.config["LOG_BACKUP_COUNT"],
encoding="utf-8",
)
handler.setFormatter(logging.Formatter(
"%(asctime)s %(levelname)s %(name)s [%(threadName)s] %(message)s"
))
root = logging.getLogger()
root.setLevel(app.config["LOG_LEVEL"])
# Avoid duplicate handlers when an app factory is called repeatedly in tests.
target = str(log_path)
if not any(
isinstance(item, RotatingFileHandler)
and getattr(item, "baseFilename", None) == target
for item in root.handlers
):
root.addHandler(handler)
else:
handler.close()
def uncaught_exception(exception_type, exception, traceback):
if issubclass(exception_type, KeyboardInterrupt):
return sys.__excepthook__(exception_type, exception, traceback)
logging.getLogger("netatmo_service.uncaught").critical(
"Uncaught Python exception", exc_info=(exception_type, exception, traceback)
)
def uncaught_thread_exception(arguments):
logging.getLogger("netatmo_service.uncaught").critical(
"Uncaught exception in thread %s",
arguments.thread.name if arguments.thread else "unknown",
exc_info=(arguments.exc_type, arguments.exc_value, arguments.exc_traceback),
)
sys.excepthook = uncaught_exception
threading.excepthook = uncaught_thread_exception
def create_app(test_config: dict | None = None) -> Flask:
app = Flask(__name__)
app.config.from_object(Config)
@@ -39,7 +86,8 @@ def create_app(test_config: dict | None = None) -> Flask:
if prefix:
app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix)
logging.basicConfig(level=app.config.get("LOG_LEVEL", "INFO"))
configure_logging(app)
app.logger.info("Starting GetNetatmoData v2 (URL prefix=%s)", prefix or "/")
store = app.config.get("RRD_STORE") or RRDStore(
app.config["RRD_FOLDER"], app.config["GRAPH_WIDTH"], app.config["GRAPH_HEIGHT"]
)
@@ -70,6 +118,13 @@ def create_app(test_config: dict | None = None) -> Flask:
def health():
return jsonify(status="ok", collector_configured=client.configured)
@app.errorhandler(Exception)
def unexpected_error(error):
if isinstance(error, HTTPException):
return error
app.logger.exception("Unhandled Flask request error")
return jsonify(error="Internal server error"), 500
@app.get("/last/<rrd_name>/<data_point>")
def last(rrd_name: str, data_point: str):
try: