Skip to content

Commit 5a29890

Browse files
committed
change: start of cleanup of logging init to only clear/reset root logger handler one time at first init. this is the beginning of broader review and improvements to logging configuration
1 parent 109c8a6 commit 5a29890

1 file changed

Lines changed: 41 additions & 17 deletions

File tree

scitrera_app_framework/core/core.py

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
_VAR_PARAM_MAP = '=|PARAM_MAP|'
2727

2828

29+
class _SAFStreamHandler(logging.StreamHandler):
30+
"""Custom StreamHandler created by the framework."""
31+
pass
32+
33+
2934
def _get_default_vars_instance() -> Variables:
3035
""" Internal function to get/initialize the default variables instance. """
3136
global _default_vars_inst
@@ -116,23 +121,6 @@ def get_logger(v: Variables = None, logger=None, name=None) -> logging.Logger:
116121
return logger
117122

118123

119-
def _init_logging(logger_name, level='INFO', formatter=None, stream=sys.stderr) -> logging.Logger:
120-
""" Internal function to initialize logging """
121-
log_level = logging.getLevelName(level.upper())
122-
logging.root.setLevel(log_level)
123-
# TODO: logging.root manipulation makes sense for container init scenario but not when multiple environments allowed
124-
logging.root.handlers.clear()
125-
if stream is not None:
126-
handler = logging.StreamHandler(stream=stream)
127-
if formatter is not None:
128-
handler.setFormatter(formatter)
129-
handler.setLevel(log_level) # configure handler to use given level
130-
logging.root.addHandler(handler) # TODO: handler should be added to the root logger for the environment/Variables instance
131-
132-
logger = logging.getLogger(logger_name)
133-
return logger
134-
135-
136124
def _log_fmt_json(**static_fields):
137125
""" Internal function to create formatter instance for JSON logs """
138126
try:
@@ -172,6 +160,42 @@ def _log_fmt_json(**static_fields):
172160
return None
173161

174162

163+
def _init_logging(logger_name, level='INFO', formatter=None, stream=sys.stderr) -> logging.Logger:
164+
""" Internal function to initialize logging """
165+
log_level = logging.getLevelName(level.upper())
166+
root_logger = logging.root
167+
root_logger.setLevel(log_level)
168+
169+
# check if a framework-created handler is already present on the root logger.
170+
root_already_initialized = any(isinstance(h, _SAFStreamHandler) for h in root_logger.handlers)
171+
172+
# if first time initialization: clear the default handlers and add our custom handler
173+
if not root_already_initialized and stream is not None:
174+
root_logger.handlers.clear()
175+
# noinspection PyTypeChecker
176+
handler = _SAFStreamHandler(stream=stream)
177+
if formatter is not None:
178+
handler.setFormatter(formatter)
179+
handler.setLevel(log_level)
180+
root_logger.addHandler(handler)
181+
182+
# return base logger for framework
183+
logger = logging.getLogger(logger_name)
184+
return logger
185+
186+
187+
def _set_root_logging_level(level='INFO'):
188+
log_level = logging.getLevelName(level.upper())
189+
root_logger = logging.root
190+
root_logger.setLevel(log_level)
191+
for handler in root_logger.handlers:
192+
if isinstance(handler, _SAFStreamHandler):
193+
handler.setLevel(log_level)
194+
return # job done
195+
196+
raise ValueError('cannot set root logging level before initialization')
197+
198+
175199
def _init_stateful_root(v: Variables, local_name=None, default_stateful_root='./scratch',
176200
default_run_id=None, default_run_serial=None, default_chdir=True):
177201
"""

0 commit comments

Comments
 (0)