""" SQLAlchemy-backed logging handler. Writes app.* log records to the app_logs table so the web viewer can query, filter, and purge them without touching the log file. Safety rules: - Never raises — all errors are silently swallowed to avoid crashing the app - Reentrancy guard prevents infinite recursion (SQLAlchemy emits its own logs) - Skips sqlalchemy.* and werkzeug loggers to avoid noise / recursion """ import logging import traceback from datetime import datetime _SKIP_PREFIXES = ('sqlalchemy', 'werkzeug', 'urllib3', 'plaid_handler') class DBLogHandler(logging.Handler): _inside_emit = False def emit(self, record): if DBLogHandler._inside_emit: return if any(record.name.startswith(p) for p in _SKIP_PREFIXES): return DBLogHandler._inside_emit = True try: from app.extensions import db from app.models.app_log import AppLog msg = record.getMessage() if record.exc_info: msg += '\n' + ''.join(traceback.format_exception(*record.exc_info)).rstrip() entry = AppLog( timestamp=datetime.utcfromtimestamp(record.created), level=record.levelname, module=record.name, message=msg, ) db.session.add(entry) db.session.commit() except Exception: pass finally: DBLogHandler._inside_emit = False