Make logging optionally remove global handlers added by (shitty) pip
[python_utils.git] / logging_utils.py
index 278cbf0f14910e25af66e7852d51cb268eeea26c..005761a5cccf3d5e90bd9ff3020543aed6dcc59c 100644 (file)
@@ -143,6 +143,17 @@ cfg.add_argument(
         'module:function, or :function and <level> is a logging level (e.g. INFO, DEBUG...)'
     )
 )
+cfg.add_argument(
+    '--logging_clear_spammy_handlers',
+    action=argparse_utils.ActionNoYes,
+    default=False,
+    help=(
+        'Should logging code clear preexisting global logging handlers and thus insist that is ' +
+        'alone can add handlers.  Use this to work around annoying modules that insert global ' +
+        'handlers with formats and logging levels you might now want.  Caveat emptor, this may ' +
+        'cause you to miss logging messages.'
+    )
+)
 
 
 built_in_print = print
@@ -377,6 +388,12 @@ def initialize_logging(logger=None) -> logging.Logger:
     if logger is None:
         logger = logging.getLogger()       # Root logger
 
+    spammy_handlers = 0
+    if config.config['logging_clear_spammy_handlers']:
+        while logger.hasHandlers():
+            logger.removeHandler(logger.handlers[0])
+            spammy_handlers += 1
+
     if config.config['logging_config_file'] is not None:
         logging.config.fileConfig('logging.conf')
         return logger
@@ -410,7 +427,7 @@ def initialize_logging(logger=None) -> logging.Logger:
             if config.config['logging_syslog_facility']:
                 facility_name = 'LOG_' + config.config['logging_syslog_facility']
             facility = SysLogHandler.__dict__.get(facility_name, SysLogHandler.LOG_USER)
-            handler = SysLogHandler(facility=SysLogHandler.LOG_CRON, address='/dev/log')
+            handler = SysLogHandler(facility=facility, address='/dev/log')
             handler.setFormatter(
                 MillisecondAwareFormatter(
                     fmt=fmt,
@@ -485,6 +502,36 @@ def initialize_logging(logger=None) -> logging.Logger:
             built_in_print(*arg, **kwarg)
         builtins.print = print_and_also_log
 
+    logger.debug(f'Initialized logger; default logging level is {default_logging_level}.')
+    if config.config['logging_clear_spammy_handlers'] and spammy_handlers > 0:
+        logger.warning(
+            'Logging cleared {spammy_handlers} global handlers (--logging_clear_spammy_handlers)'
+        )
+    logger.debug(f'Logging format is "{fmt}"')
+    if config.config['logging_syslog']:
+        logger.debug(f'Logging to syslog as {facility_name} with normal severity mapping')
+    if config.config['logging_filename']:
+        logger.debug(f'Logging to filename {config.config["logging_filename"]} with rotation')
+    if config.config['logging_console']:
+        logger.debug(f'Logging to the console.')
+    if config.config['logging_info_is_print']:
+        logger.debug(
+            'Logging logger.info messages will be repeated on stdout (--logging_info_is_print)'
+        )
+    if config.config['logging_squelch_repeats_enabled']:
+        logger.debug(
+            'Logging code is allowed to request repeated messages be squelched (--logging_squelch_repeats_enabled)'
+        )
+    if config.config['logging_probabilistically_enabled']:
+        logger.debug(
+            'Logging code is allowed to request probabilistic logging (--logging_probabilistically_enabled)'
+        )
+    if config.config['lmodule']:
+        logger.debug(
+            'Logging dynamic per-module logging enabled (--lmodule={config.config["lmodule"]})'
+        )
+    if config.config['logging_captures_prints']:
+        logger.debug('Logging will capture printed messages (--logging_captures_prints)')
     return logger