CORD-1743: Redo ofcreate_logger API
Change-Id: I5d71f9a56e5fbd3d2242ceaa456bf9c9d9072624
diff --git a/multistructlog.py b/multistructlog.py
index b4aa19b..960b5bf 100644
--- a/multistructlog.py
+++ b/multistructlog.py
@@ -64,9 +64,13 @@
class XOSLoggerFactory:
+ def __init__(self, handlers):
+ self.handlers = handlers
+
def __call__(self):
base_logger = logging.getLogger()
- for h in base_logger.handlers:
+ base_logger.handlers = []
+ for h in self.handlers:
formatter = FormatterFactory(h.__class__.__name__)()
h.setFormatter(formatter)
base_logger.addHandler(h)
@@ -78,62 +82,64 @@
""" We expose the Structlog logging interface directly. This should allow callers to
bind contexts incrementally and configure and use other features of structlog directly
- - config is the root xos configuration
- - overrides override elements of that config, e.g. level=logging.INFO would cause debug messages to be dropped
- - overrides can contain a 'processors' element, which lets you add processors to structlogs chain
- - overrides can also contain force_create = True which returns a previously created logger. Multiple threads
- will overwrite the shared logger.
-
- The use of structlog in Chameleon was used as a reference when writing this code.
+ The use of structlog in Chameleon was used for reference when writing this code.
"""
CURRENT_LOGGER = None
-CURRENT_LOGGER_PARMS = (None, None)
+CURRENT_LOGGER_PARMS = None
-def create_logger(_config, **overrides):
- first_entry_elts = []
+def create_logger(_config=None, extra_processors=[], force_create=False, level=None):
+ """
+ Args:
+ _config (dict): The standard config for Python's logging module
+ extra_processors(dict): Custom structlog processors
+ force_create(bool): Forces creation of the logger
+ level(logging.loglevel): Overrides logging level
+
+ Returns:
+ log: structlog logger
+ """
+
+ first_entry_elts = ['Starting']
"""Inherit base options from config"""
- try:
+ if _config:
logging_config = copy.deepcopy(_config)
- except AttributeError:
+ else:
first_entry_elts.append('Config is empty')
- logging_config = {}
+ logging_config = {'version': 1}
"""Check if a logger with this configuration has already been created, if so, return that logger
instead of creating a new one"""
global CURRENT_LOGGER
global CURRENT_LOGGER_PARMS
-
- if CURRENT_LOGGER and CURRENT_LOGGER_PARMS == (logging_config, overrides) and not overrides.get('force_create'):
+ if CURRENT_LOGGER and CURRENT_LOGGER_PARMS == (logging_config, extra_processors, level) and not force_create:
return CURRENT_LOGGER
- first_entry_elts.append('Starting')
- first_entry_struct = {}
-
- if overrides:
- first_entry_struct['overrides'] = overrides
-
- for k, v in overrides.items():
- logging_config[k] = v
-
- default_handlers = [
- logging.StreamHandler(sys.stdout),
- logstash.LogstashHandler('localhost', 5617, version=1)
- ]
+ if level:
+ try:
+ for k,v in logging_config['loggers'].iteritems():
+ v['level'] = level
+ except KeyError:
+ first_entry_elts.append('Level override failed')
logging.config.dictConfig(logging_config)
- # Processors
- processors = overrides.get('processors', [])
-
+ processors = copy.copy(extra_processors)
processors.extend([
structlog.processors.StackInfoRenderer(),
structlog.processors.format_exc_info,
structlog.stdlib.ProcessorFormatter.wrap_for_formatter
])
+
+ default_handlers = [
+ logging.StreamHandler(sys.stdout),
+ logstash.LogstashHandler('localhost', 5617, version=1)
+ ]
- factory = XOSLoggerFactory()
+ configured_handlers = logging.getLogger().handlers
+ handlers = configured_handlers if configured_handlers else default_handlers
+ factory = XOSLoggerFactory(handlers)
structlog.configure(
processors=processors,
@@ -142,12 +148,12 @@
log = structlog.get_logger()
first_entry = '. '.join(first_entry_elts)
- log.info(first_entry, **first_entry_struct)
+ log.info(first_entry, level_override=level,**logging_config)
CURRENT_LOGGER = log
- CURRENT_LOGGER_PARMS = (logging_config, overrides)
+ CURRENT_LOGGER_PARMS = (logging_config, extra_processors, level)
return log
if __name__ == '__main__':
- l = create_logger({'logging': {'version': 2, 'loggers':{'':{'level': 'INFO'}}}}, level="INFO")
+ l = create_logger({'version': 2, 'loggers':{'':{'level': 'INFO'}}}, level="INFO")
l.info("Test OK")