log.py: tweak LogTarget list, require explicit LogTarget
Rename log_sink to log_write_func to make it more clear.
Remember the list of log targets as static member LogTarget.all_targets.
Make each LogTarget instance register with the list of targets implicitly.
No longer create a default log target, rather create one explicitly in
osmo-gsm-tester.py.
Change-Id: I5844485eaed536cb34b44bfe23dc635fe1982dcd
diff --git a/selftest/_prep.py b/selftest/_prep.py
index e89c5a7..3ef6e81 100644
--- a/selftest/_prep.py
+++ b/selftest/_prep.py
@@ -9,7 +9,7 @@
from osmo_gsm_tester import log
-log.targets = [ log.TestsTarget() ]
+log.TestsTarget()
log.set_all_levels(log.L_DBG)
if '-v' in sys.argv:
diff --git a/src/osmo-gsm-tester.py b/src/osmo-gsm-tester.py
index fb4a8d7..34e76fa 100755
--- a/src/osmo-gsm-tester.py
+++ b/src/osmo-gsm-tester.py
@@ -104,6 +104,9 @@
print('trials:', repr(args.trial_package))
print('tests:', repr(args.test))
+ # create a default log to stdout
+ log.LogTarget()
+
if args.log_level:
log.set_all_levels(log.LEVEL_STRS.get(args.log_level))
log.style_change(origin_width=32)
diff --git a/src/osmo_gsm_tester/log.py b/src/osmo_gsm_tester/log.py
index b581e2c..0e9b1f6 100644
--- a/src/osmo_gsm_tester/log.py
+++ b/src/osmo_gsm_tester/log.py
@@ -54,6 +54,8 @@
pass
class LogTarget:
+ all_targets = []
+
do_log_time = None
do_log_category = None
do_log_level = None
@@ -68,13 +70,17 @@
get_time_str = lambda self: time.strftime(self.log_time_fmt)
# sink that gets each complete logging line
- log_sink = sys.__stdout__.write
+ log_write_func = None
category_levels = None
- def __init__(self):
+ def __init__(self, log_write_func=None):
+ if log_write_func is None:
+ log_write_func = sys.__stdout__.write
+ self.log_write_func = log_write_func
self.category_levels = {}
self.style()
+ LogTarget.all_targets.append(self)
def style(self, time=True, time_fmt=DATEFMT, category=True, level=True, origin=True, origin_width=0, src=True, trace=False):
'''
@@ -135,8 +141,8 @@
def log(self, origin, category, level, src, messages, named_items):
if category and len(category) != 3:
- self.log_sink('WARNING: INVALID LOG SUBSYSTEM %r\n' % category)
- self.log_sink('origin=%r category=%r level=%r\n' % (origin, category, level));
+ self.log_write_func('WARNING: INVALID LOG SUBSYSTEM %r\n' % category)
+ self.log_write_func('origin=%r category=%r level=%r\n' % (origin, category, level));
if not category:
category = C_DEFAULT
@@ -186,17 +192,15 @@
if not log_str.endswith('\n'):
log_str = log_str + '\n'
- self.log_sink(log_str)
+ self.log_write_func(log_str)
def large_separator(self, *msgs):
msg = ' '.join(msgs)
if not msg:
msg = '------------------------------------------'
- self.log_sink('------------------------------------------\n'
- '%s\n'
- '------------------------------------------\n' % msg)
-
-targets = [ LogTarget() ]
+ self.log_write_func('------------------------------------------\n'
+ '%s\n'
+ '------------------------------------------\n' % msg)
def level_str(level):
if level == L_TRACEBACK:
@@ -208,17 +212,15 @@
return 'ERR'
def _log_all_targets(origin, category, level, src, messages, named_items=None):
- global targets
-
if origin is None:
origin = Origin._global_current_origin
if isinstance(src, int):
src = get_src_from_caller(src + 1)
- for target in targets:
+ for target in LogTarget.all_targets:
target.log(origin, category, level, src, messages, named_items)
def large_separator(*msgs):
- for target in targets:
+ for target in LogTarget.all_targets:
target.large_separator(*msgs)
def get_src_from_caller(levels_up=1):
@@ -481,31 +483,26 @@
def set_all_levels(level):
- global targets
- for target in targets:
+ for target in LogTarget.all_targets:
target.set_all_levels(level)
def set_level(category, level):
- global targets
- for target in targets:
+ for target in LogTarget.all_targets:
target.set_level(category, level)
def style(**kwargs):
- global targets
- for target in targets:
+ for target in LogTarget.all_targets:
target.style(**kwargs)
def style_change(**kwargs):
- global targets
- for target in targets:
+ for target in LogTarget.all_targets:
target.style_change(**kwargs)
class TestsTarget(LogTarget):
'LogTarget producing deterministic results for regression tests'
- def __init__(self, out=sys.stdout):
- super().__init__()
+ def __init__(self, log_write_func=None):
+ super().__init__(log_write_func)
self.style(time=False, src=False)
- self.log_sink = out.write
def run_logging_exceptions(func, *func_args, return_on_failure=None, **func_kwargs):
try: