From 20786e44c18d29dad0dafbc614f633363bc2dae5 Mon Sep 17 00:00:00 2001 From: agessaman Date: Wed, 18 Mar 2026 21:55:32 -0700 Subject: [PATCH] Enhance logging configuration to prevent duplicate outputs and manage third-party loggers - Normalized root logger early to avoid duplicate output from dependencies. - Cleared root logger handlers and set logging level explicitly. - Configured third-party loggers (APScheduler and tzlocal) to prevent unformatted console output and manage their logging levels. - Ensured that logger propagation is disabled to avoid duplicate messages. --- modules/core.py | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/modules/core.py b/modules/core.py index e9ee6f6..4283c55 100644 --- a/modules/core.py +++ b/modules/core.py @@ -872,6 +872,13 @@ long_jokes = false datefmt='%Y-%m-%d %H:%M:%S' ) + # Normalize root logger early to avoid duplicate/basicConfig output from dependencies. + # We intentionally keep root handlerless; modules that want logging should attach + # handlers explicitly (MeshCoreBot and meshcore loggers below). + root_logger = logging.getLogger() + root_logger.handlers.clear() + root_logger.setLevel(log_level) + # Setup logger self.logger = logging.getLogger('MeshCoreBot') self.logger.setLevel(log_level) @@ -943,10 +950,32 @@ long_jokes = false handler = logging.StreamHandler() handler.setFormatter(formatter) logger.addHandler(handler) + # Prevent duplicate output if root is later configured elsewhere. + logger.propagate = False - # Configure root logger to prevent other libraries from using DEBUG - root_logger = logging.getLogger() - root_logger.setLevel(log_level) + # Silence noisy third-party loggers that can emit unformatted console output. + # APScheduler: keep INFO (but route through our formatter) and prevent propagation. + # tzlocal: keep WARNING+ (it can be very chatty at DEBUG). + apsched_logger_names = ( + "apscheduler", + "apscheduler.scheduler", + "apscheduler.executors", + "apscheduler.jobstores", + ) + for name in apsched_logger_names: + third = logging.getLogger(name) + third.handlers.clear() + third.setLevel(logging.INFO) + third.propagate = False + if not third.handlers: + handler = logging.StreamHandler() + handler.setFormatter(formatter) + third.addHandler(handler) + + tzlocal_logger = logging.getLogger("tzlocal") + tzlocal_logger.handlers.clear() + tzlocal_logger.setLevel(logging.WARNING) + tzlocal_logger.propagate = False # Log the configuration for debugging mode = 'json' if json_logging else ('colored' if colored_output else 'plain')