diff --git a/SYS/database.py b/SYS/database.py index 9066b78..f358e9a 100644 --- a/SYS/database.py +++ b/SYS/database.py @@ -2,6 +2,8 @@ from __future__ import annotations import sqlite3 import json +import threading +from queue import Queue from pathlib import Path from typing import Any, Dict, List, Optional from contextlib import contextmanager @@ -158,18 +160,53 @@ class Database: # Singleton instance db = Database() +_LOG_QUEUE: Queue[tuple[str, str, str]] = Queue() +_LOG_THREAD_STARTED = False +_LOG_THREAD_LOCK = threading.Lock() + + +def _log_worker_loop() -> None: + while True: + level, module, message = _LOG_QUEUE.get() + try: + db.execute( + "INSERT INTO logs (level, module, message) VALUES (?, ?, ?)", + (level, module, message) + ) + except Exception: + pass + finally: + try: + _LOG_QUEUE.task_done() + except Exception: + pass + + +def _ensure_log_thread() -> None: + global _LOG_THREAD_STARTED + if _LOG_THREAD_STARTED: + return + with _LOG_THREAD_LOCK: + if _LOG_THREAD_STARTED: + return + thread = threading.Thread( + target=_log_worker_loop, + name="mediosdb-log", + daemon=True + ) + thread.start() + _LOG_THREAD_STARTED = True + def get_db() -> Database: return db def log_to_db(level: str, module: str, message: str): - """Log a message to the database.""" + """Log a message to the database asynchronously.""" try: - db.execute( - "INSERT INTO logs (level, module, message) VALUES (?, ?, ?)", - (level, module, message) - ) + _ensure_log_thread() + _LOG_QUEUE.put((level, module, message)) except Exception: - # Avoid recursive logging errors if DB is locked + # Avoid recursive logging errors if the queue fails pass # Initialize DB logger in the unified logger