Commit 1e920d61d0ad284f70309f46ba4485c25a3b1133

Authored by Christian Herdtweck
1 parent cdede5b1

log_helper: Use stdout for all json logging

Logging uses the default StreamHandler, which per default sends its
output to sys.stderr. However, the surrounding '[', ']' are printed
to stdout. Fix that.
oletools/common/log_helper/log_helper.py
@@ -45,6 +45,7 @@ General logging helpers @@ -45,6 +45,7 @@ General logging helpers
45 # TODO: 45 # TODO:
46 46
47 47
  48 +from __future__ import print_function
48 from ._json_formatter import JsonFormatter 49 from ._json_formatter import JsonFormatter
49 from ._logger_adapter import OletoolsLoggerAdapter 50 from ._logger_adapter import OletoolsLoggerAdapter
50 from . import _root_logger_wrapper 51 from . import _root_logger_wrapper
@@ -70,6 +71,7 @@ class LogHelper: @@ -70,6 +71,7 @@ class LogHelper:
70 self._all_names = set() # set so we do not have duplicates 71 self._all_names = set() # set so we do not have duplicates
71 self._use_json = False 72 self._use_json = False
72 self._is_enabled = False 73 self._is_enabled = False
  74 + self._target_stream = None
73 75
74 def get_or_create_silent_logger(self, name=DEFAULT_LOGGER_NAME, level=logging.CRITICAL + 1): 76 def get_or_create_silent_logger(self, name=DEFAULT_LOGGER_NAME, level=logging.CRITICAL + 1):
75 """ 77 """
@@ -95,17 +97,25 @@ class LogHelper: @@ -95,17 +97,25 @@ class LogHelper:
95 Since the root logger is the one doing the work, when using JSON we set its formatter 97 Since the root logger is the one doing the work, when using JSON we set its formatter
96 so that every message logged is JSON-compatible. 98 so that every message logged is JSON-compatible.
97 99
98 - If other code also creates json output, that other code should output the  
99 - first logging line and tell us via `other_logger_has_first_line`. 100 + If other code also creates json output, all items should be pre-pended
  101 + with a comma like the `JsonFormatter` does. Except the first; use param
  102 + `other_logger_has_first_line` to clarify whether our logger or the
  103 + other code will produce the first json item.
100 """ 104 """
101 if self._is_enabled: 105 if self._is_enabled:
102 raise ValueError('re-enabling logging. Not sure whether that is ok...') 106 raise ValueError('re-enabling logging. Not sure whether that is ok...')
103 107
104 - if stream in (None, sys.stdout): 108 + if stream is None:
  109 + self.target_stream = sys.stdout
  110 + else:
  111 + self.target_stream = stream
  112 +
  113 + if self.target_stream == sys.stdout:
105 ensure_stdout_handles_unicode() 114 ensure_stdout_handles_unicode()
106 115
107 log_level = LOG_LEVELS[level] 116 log_level = LOG_LEVELS[level]
108 - logging.basicConfig(level=log_level, format=log_format, stream=stream) 117 + logging.basicConfig(level=log_level, format=log_format,
  118 + stream=self.target_stream)
109 self._is_enabled = True 119 self._is_enabled = True
110 120
111 self._use_json = use_json 121 self._use_json = use_json
@@ -120,7 +130,7 @@ class LogHelper: @@ -120,7 +130,7 @@ class LogHelper:
120 # add a JSON formatter to the root logger, which will be used by every logger 130 # add a JSON formatter to the root logger, which will be used by every logger
121 if self._use_json: 131 if self._use_json:
122 _root_logger_wrapper.set_formatter(JsonFormatter(other_logger_has_first_line)) 132 _root_logger_wrapper.set_formatter(JsonFormatter(other_logger_has_first_line))
123 - print('[') 133 + print('[', file=self.target_stream)
124 134
125 def end_logging(self): 135 def end_logging(self):
126 """ 136 """
@@ -137,7 +147,7 @@ class LogHelper: @@ -137,7 +147,7 @@ class LogHelper:
137 147
138 # end json list 148 # end json list
139 if self._use_json: 149 if self._use_json:
140 - print(']') 150 + print(']', file=self.target_stream)
141 self._use_json = False 151 self._use_json = False
142 152
143 def _get_except_hook(self, old_hook): 153 def _get_except_hook(self, old_hook):