added logging
This commit is contained in:
+56
-1
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user