Mercurial > libervia-backend
comparison sat/core/log_config.py @ 2624:56f94936df1e
code style reformatting using black
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 27 Jun 2018 20:14:46 +0200 |
parents | 26edcf3a30eb |
children | e55f871fa9db |
comparison
equal
deleted
inserted
replaced
2623:49533de4540b | 2624:56f94936df1e |
---|---|
29 force_colors = False | 29 force_colors = False |
30 | 30 |
31 def __init__(self, *args, **kwargs): | 31 def __init__(self, *args, **kwargs): |
32 super(TwistedLogger, self).__init__(*args, **kwargs) | 32 super(TwistedLogger, self).__init__(*args, **kwargs) |
33 from twisted.python import log as twisted_log | 33 from twisted.python import log as twisted_log |
34 | |
34 self.twisted_log = twisted_log | 35 self.twisted_log = twisted_log |
35 | 36 |
36 def out(self, message, level=None): | 37 def out(self, message, level=None): |
37 """Actually log the message | 38 """Actually log the message |
38 | 39 |
39 @param message: formatted message | 40 @param message: formatted message |
40 """ | 41 """ |
41 self.twisted_log.msg(message.encode('utf-8', 'ignore'), sat_logged=True, level=level) | 42 self.twisted_log.msg( |
43 message.encode("utf-8", "ignore"), sat_logged=True, level=level | |
44 ) | |
42 | 45 |
43 | 46 |
44 class ConfigureBasic(log.ConfigureBase): | 47 class ConfigureBasic(log.ConfigureBase): |
45 | |
46 def configureColors(self, colors, force_colors, levels_taints_dict): | 48 def configureColors(self, colors, force_colors, levels_taints_dict): |
47 super(ConfigureBasic, self).configureColors(colors, force_colors, levels_taints_dict) | 49 super(ConfigureBasic, self).configureColors( |
50 colors, force_colors, levels_taints_dict | |
51 ) | |
48 if colors: | 52 if colors: |
49 import sys | 53 import sys |
54 | |
50 try: | 55 try: |
51 isatty = sys.stdout.isatty() | 56 isatty = sys.stdout.isatty() |
52 except AttributeError: | 57 except AttributeError: |
53 isatty = False | 58 isatty = False |
54 if force_colors or isatty: # FIXME: isatty should be tested on each handler, not globaly | 59 if ( |
60 force_colors or isatty | |
61 ): # FIXME: isatty should be tested on each handler, not globaly | |
55 # we need colors | 62 # we need colors |
56 log.Logger.post_treat = lambda logger, level, message: self.ansiColors(level, message) | 63 log.Logger.post_treat = lambda logger, level, message: self.ansiColors( |
64 level, message | |
65 ) | |
57 elif force_colors: | 66 elif force_colors: |
58 raise ValueError("force_colors can't be used if colors is False") | 67 raise ValueError("force_colors can't be used if colors is False") |
59 | 68 |
60 @staticmethod | 69 @staticmethod |
61 def getProfile(): | 70 def getProfile(): |
62 """Try to find profile value using introspection""" | 71 """Try to find profile value using introspection""" |
63 import inspect | 72 import inspect |
73 | |
64 stack = inspect.stack() | 74 stack = inspect.stack() |
65 current_path = stack[0][1] | 75 current_path = stack[0][1] |
66 for frame_data in stack[:-1]: | 76 for frame_data in stack[:-1]: |
67 if frame_data[1] != current_path: | 77 if frame_data[1] != current_path: |
68 if log.backend == C.LOG_BACKEND_STANDARD and "/logging/__init__.py" in frame_data[1]: | 78 if ( |
79 log.backend == C.LOG_BACKEND_STANDARD | |
80 and "/logging/__init__.py" in frame_data[1] | |
81 ): | |
69 continue | 82 continue |
70 break | 83 break |
71 | 84 |
72 frame = frame_data[0] | 85 frame = frame_data[0] |
73 args = inspect.getargvalues(frame) | 86 args = inspect.getargvalues(frame) |
74 try: | 87 try: |
75 profile = args.locals.get('profile') or args.locals['profile_key'] | 88 profile = args.locals.get("profile") or args.locals["profile_key"] |
76 except (TypeError, KeyError): | 89 except (TypeError, KeyError): |
77 try: | 90 try: |
78 try: | 91 try: |
79 profile = args.locals['self'].profile | 92 profile = args.locals["self"].profile |
80 except AttributeError: | 93 except AttributeError: |
81 try: | 94 try: |
82 profile = args.locals['self'].parent.profile | 95 profile = args.locals["self"].parent.profile |
83 except AttributeError: | 96 except AttributeError: |
84 profile = args.locals['self'].host.profile # used in quick_frontend for single profile configuration | 97 profile = args.locals[ |
98 "self" | |
99 ].host.profile # used in quick_frontend for single profile configuration | |
85 except Exception: | 100 except Exception: |
86 # we can't find profile, we return an empty value | 101 # we can't find profile, we return an empty value |
87 profile = '' | 102 profile = "" |
88 return profile | 103 return profile |
89 | 104 |
90 | 105 |
91 class ConfigureTwisted(ConfigureBasic): | 106 class ConfigureTwisted(ConfigureBasic): |
92 LOGGER_CLASS = TwistedLogger | 107 LOGGER_CLASS = TwistedLogger |
95 """Install a hook on observer to manage SàT specificities | 110 """Install a hook on observer to manage SàT specificities |
96 | 111 |
97 @param observer: original observer to hook | 112 @param observer: original observer to hook |
98 @param can_colors: True if observer can display ansi colors | 113 @param can_colors: True if observer can display ansi colors |
99 """ | 114 """ |
115 | |
100 def observer_hook(event): | 116 def observer_hook(event): |
101 """redirect non SàT log to twisted_logger, and add colors when possible""" | 117 """redirect non SàT log to twisted_logger, and add colors when possible""" |
102 if 'sat_logged' in event: # we only want our own logs, other are managed by twistedObserver | 118 if ( |
119 "sat_logged" in event | |
120 ): # we only want our own logs, other are managed by twistedObserver | |
103 # we add colors if possible | 121 # we add colors if possible |
104 if (can_colors and self.LOGGER_CLASS.colors) or self.LOGGER_CLASS.force_colors: | 122 if ( |
105 message = event.get('message', tuple()) | 123 can_colors and self.LOGGER_CLASS.colors |
106 level = event.get('level', C.LOG_LVL_INFO) | 124 ) or self.LOGGER_CLASS.force_colors: |
125 message = event.get("message", tuple()) | |
126 level = event.get("level", C.LOG_LVL_INFO) | |
107 if message: | 127 if message: |
108 event['message'] = (self.ansiColors(level, ''.join(message)),) # must be a tuple | 128 event["message"] = ( |
109 observer(event) # we can now call the original observer | 129 self.ansiColors(level, "".join(message)), |
130 ) # must be a tuple | |
131 observer(event) # we can now call the original observer | |
110 | 132 |
111 return observer_hook | 133 return observer_hook |
112 | 134 |
113 def changeFileLogObserver(self, observer): | 135 def changeFileLogObserver(self, observer): |
114 """Install SàT hook for FileLogObserver | 136 """Install SàT hook for FileLogObserver |
128 """Check observer type and install SàT hook when possible | 150 """Check observer type and install SàT hook when possible |
129 | 151 |
130 @param observer: observer to hook | 152 @param observer: observer to hook |
131 @return: hooked observer or original one | 153 @return: hooked observer or original one |
132 """ | 154 """ |
133 if hasattr(observer, '__self__'): | 155 if hasattr(observer, "__self__"): |
134 ori = observer | 156 ori = observer |
135 if isinstance(observer.__self__, self.twisted_log.FileLogObserver): | 157 if isinstance(observer.__self__, self.twisted_log.FileLogObserver): |
136 observer = self.changeFileLogObserver(observer) | 158 observer = self.changeFileLogObserver(observer) |
137 elif isinstance(observer.__self__, self.twisted_log.DefaultObserver): | 159 elif isinstance(observer.__self__, self.twisted_log.DefaultObserver): |
138 observer = self.changeObserver(observer, can_colors=True) | 160 observer = self.changeObserver(observer, can_colors=True) |
145 | 167 |
146 def preTreatment(self): | 168 def preTreatment(self): |
147 """initialise needed attributes, and install observers hooks""" | 169 """initialise needed attributes, and install observers hooks""" |
148 self.observers = {} | 170 self.observers = {} |
149 from twisted.python import log as twisted_log | 171 from twisted.python import log as twisted_log |
172 | |
150 self.twisted_log = twisted_log | 173 self.twisted_log = twisted_log |
151 self.log_publisher = twisted_log.msg.__self__ | 174 self.log_publisher = twisted_log.msg.__self__ |
175 | |
152 def addObserverObserver(self_logpub, other): | 176 def addObserverObserver(self_logpub, other): |
153 """Install hook so we know when a new observer is added""" | 177 """Install hook so we know when a new observer is added""" |
154 other = self.installObserverHook(other) | 178 other = self.installObserverHook(other) |
155 return self_logpub._originalAddObserver(other) | 179 return self_logpub._originalAddObserver(other) |
180 | |
156 def removeObserverObserver(self_logpub, ori): | 181 def removeObserverObserver(self_logpub, ori): |
157 """removeObserver hook fix | 182 """removeObserver hook fix |
158 | 183 |
159 As we wrap the original observer, the original removeObserver may want to remove the original object instead of the wrapper, this method fix this | 184 As we wrap the original observer, the original removeObserver may want to remove the original object instead of the wrapper, this method fix this |
160 """ | 185 """ |
168 ori in self.cleared_observers | 193 ori in self.cleared_observers |
169 except AttributeError: | 194 except AttributeError: |
170 raise ValueError("Unknown observer") | 195 raise ValueError("Unknown observer") |
171 | 196 |
172 # we replace addObserver/removeObserver by our own | 197 # we replace addObserver/removeObserver by our own |
173 twisted_log.LogPublisher._originalAddObserver = twisted_log.LogPublisher.addObserver | 198 twisted_log.LogPublisher._originalAddObserver = ( |
174 twisted_log.LogPublisher._originalRemoveObserver = twisted_log.LogPublisher.removeObserver | 199 twisted_log.LogPublisher.addObserver |
175 import types # see https://stackoverflow.com/a/4267590 (thx Chris Morgan/aaronasterling) | 200 ) |
176 twisted_log.addObserver = types.MethodType(addObserverObserver, self.log_publisher, twisted_log.LogPublisher) | 201 twisted_log.LogPublisher._originalRemoveObserver = ( |
177 twisted_log.removeObserver = types.MethodType(removeObserverObserver, self.log_publisher, twisted_log.LogPublisher) | 202 twisted_log.LogPublisher.removeObserver |
203 ) | |
204 import types # see https://stackoverflow.com/a/4267590 (thx Chris Morgan/aaronasterling) | |
205 | |
206 twisted_log.addObserver = types.MethodType( | |
207 addObserverObserver, self.log_publisher, twisted_log.LogPublisher | |
208 ) | |
209 twisted_log.removeObserver = types.MethodType( | |
210 removeObserverObserver, self.log_publisher, twisted_log.LogPublisher | |
211 ) | |
178 | 212 |
179 # we now change existing observers | 213 # we now change existing observers |
180 for idx, observer in enumerate(self.log_publisher.observers): | 214 for idx, observer in enumerate(self.log_publisher.observers): |
181 self.log_publisher.observers[idx] = self.installObserverHook(observer) | 215 self.log_publisher.observers[idx] = self.installObserverHook(observer) |
182 | 216 |
184 self.LOGGER_CLASS.level = level | 218 self.LOGGER_CLASS.level = level |
185 super(ConfigureTwisted, self).configureLevel(level) | 219 super(ConfigureTwisted, self).configureLevel(level) |
186 | 220 |
187 def configureOutput(self, output): | 221 def configureOutput(self, output): |
188 import sys | 222 import sys |
223 | |
189 if output is None: | 224 if output is None: |
190 output = C.LOG_OPT_OUTPUT_SEP + C.LOG_OPT_OUTPUT_DEFAULT | 225 output = C.LOG_OPT_OUTPUT_SEP + C.LOG_OPT_OUTPUT_DEFAULT |
191 self.manageOutputs(output) | 226 self.manageOutputs(output) |
192 addObserver = self.twisted_log.addObserver | 227 addObserver = self.twisted_log.addObserver |
193 | 228 |
194 if C.LOG_OPT_OUTPUT_DEFAULT in log.handlers: | 229 if C.LOG_OPT_OUTPUT_DEFAULT in log.handlers: |
195 # default output is already managed, we just add output to stdout if we are in debug or nodaemon mode | 230 # default output is already managed, we just add output to stdout if we are in debug or nodaemon mode |
196 if self.backend_data is None: | 231 if self.backend_data is None: |
197 raise ValueError("You must pass options as backend_data with Twisted backend") | 232 raise ValueError( |
233 "You must pass options as backend_data with Twisted backend" | |
234 ) | |
198 options = self.backend_data | 235 options = self.backend_data |
199 if options.get('nodaemon', False) or options.get('debug', False): | 236 if options.get("nodaemon", False) or options.get("debug", False): |
200 addObserver(self.twisted_log.FileLogObserver(sys.stdout).emit) | 237 addObserver(self.twisted_log.FileLogObserver(sys.stdout).emit) |
201 else: | 238 else: |
202 # \\default is not in the output, so we remove current observers | 239 # \\default is not in the output, so we remove current observers |
203 self.cleared_observers = self.log_publisher.observers | 240 self.cleared_observers = self.log_publisher.observers |
204 self.observers.clear() | 241 self.observers.clear() |
206 # and we forbid twistd to add any observer | 243 # and we forbid twistd to add any observer |
207 self.twisted_log.addObserver = lambda other: None | 244 self.twisted_log.addObserver = lambda other: None |
208 | 245 |
209 if C.LOG_OPT_OUTPUT_FILE in log.handlers: | 246 if C.LOG_OPT_OUTPUT_FILE in log.handlers: |
210 from twisted.python import logfile | 247 from twisted.python import logfile |
248 | |
211 for path in log.handlers[C.LOG_OPT_OUTPUT_FILE]: | 249 for path in log.handlers[C.LOG_OPT_OUTPUT_FILE]: |
212 log_file = sys.stdout if path == '-' else logfile.LogFile.fromFullPath(path) | 250 log_file = ( |
251 sys.stdout if path == "-" else logfile.LogFile.fromFullPath(path) | |
252 ) | |
213 addObserver(self.twisted_log.FileLogObserver(log_file).emit) | 253 addObserver(self.twisted_log.FileLogObserver(log_file).emit) |
214 | 254 |
215 if C.LOG_OPT_OUTPUT_MEMORY in log.handlers: | 255 if C.LOG_OPT_OUTPUT_MEMORY in log.handlers: |
216 raise NotImplementedError("Memory observer is not implemented in Twisted backend") | 256 raise NotImplementedError( |
257 "Memory observer is not implemented in Twisted backend" | |
258 ) | |
217 | 259 |
218 def configureColors(self, colors, force_colors, levels_taints_dict): | 260 def configureColors(self, colors, force_colors, levels_taints_dict): |
219 super(ConfigureTwisted, self).configureColors(colors, force_colors, levels_taints_dict) | 261 super(ConfigureTwisted, self).configureColors( |
262 colors, force_colors, levels_taints_dict | |
263 ) | |
220 self.LOGGER_CLASS.colors = colors | 264 self.LOGGER_CLASS.colors = colors |
221 self.LOGGER_CLASS.force_colors = force_colors | 265 self.LOGGER_CLASS.force_colors = force_colors |
222 if force_colors and not colors: | 266 if force_colors and not colors: |
223 raise ValueError('colors must be True if force_colors is True') | 267 raise ValueError("colors must be True if force_colors is True") |
224 | 268 |
225 def postTreatment(self): | 269 def postTreatment(self): |
226 """Install twistedObserver which manage non SàT logs""" | 270 """Install twistedObserver which manage non SàT logs""" |
271 | |
227 def twistedObserver(event): | 272 def twistedObserver(event): |
228 """Observer which redirect log message not produced by SàT to SàT logging system""" | 273 """Observer which redirect log message not produced by SàT to SàT logging system""" |
229 if not 'sat_logged' in event: | 274 if not "sat_logged" in event: |
230 # this log was not produced by SàT | 275 # this log was not produced by SàT |
231 from twisted.python import log as twisted_log | 276 from twisted.python import log as twisted_log |
277 | |
232 text = twisted_log.textFromEventDict(event) | 278 text = twisted_log.textFromEventDict(event) |
233 if text is None: | 279 if text is None: |
234 return | 280 return |
235 twisted_logger = log.getLogger(C.LOG_TWISTED_LOGGER) | 281 twisted_logger = log.getLogger(C.LOG_TWISTED_LOGGER) |
236 log_method = twisted_logger.error if event.get('isError', False) else twisted_logger.info | 282 log_method = ( |
237 log_method(text.decode('utf-8')) | 283 twisted_logger.error |
284 if event.get("isError", False) | |
285 else twisted_logger.info | |
286 ) | |
287 log_method(text.decode("utf-8")) | |
238 | 288 |
239 self.log_publisher._originalAddObserver(twistedObserver) | 289 self.log_publisher._originalAddObserver(twistedObserver) |
240 | 290 |
241 | 291 |
242 class ConfigureStandard(ConfigureBasic): | 292 class ConfigureStandard(ConfigureBasic): |
243 | 293 def __init__( |
244 def __init__(self, level=None, fmt=None, output=None, logger=None, colors=False, levels_taints_dict=None, force_colors=False, backend_data=None): | 294 self, |
295 level=None, | |
296 fmt=None, | |
297 output=None, | |
298 logger=None, | |
299 colors=False, | |
300 levels_taints_dict=None, | |
301 force_colors=False, | |
302 backend_data=None, | |
303 ): | |
245 if fmt is None: | 304 if fmt is None: |
246 fmt = C.LOG_OPT_FORMAT[1] | 305 fmt = C.LOG_OPT_FORMAT[1] |
247 if output is None: | 306 if output is None: |
248 output = C.LOG_OPT_OUTPUT[1] | 307 output = C.LOG_OPT_OUTPUT[1] |
249 super(ConfigureStandard, self).__init__(level, fmt, output, logger, colors, levels_taints_dict, force_colors, backend_data) | 308 super(ConfigureStandard, self).__init__( |
309 level, | |
310 fmt, | |
311 output, | |
312 logger, | |
313 colors, | |
314 levels_taints_dict, | |
315 force_colors, | |
316 backend_data, | |
317 ) | |
250 | 318 |
251 def preTreatment(self): | 319 def preTreatment(self): |
252 """We use logging methods directly, instead of using Logger""" | 320 """We use logging methods directly, instead of using Logger""" |
253 import logging | 321 import logging |
322 | |
254 log.getLogger = logging.getLogger | 323 log.getLogger = logging.getLogger |
255 log.debug = logging.debug | 324 log.debug = logging.debug |
256 log.info = logging.info | 325 log.info = logging.info |
257 log.warning = logging.warning | 326 log.warning = logging.warning |
258 log.error = logging.error | 327 log.error = logging.error |
269 import sys | 338 import sys |
270 | 339 |
271 class SatFormatter(logging.Formatter): | 340 class SatFormatter(logging.Formatter): |
272 u"""Formatter which manage SàT specificities""" | 341 u"""Formatter which manage SàT specificities""" |
273 _format = fmt | 342 _format = fmt |
274 _with_profile = '%(profile)s' in fmt | 343 _with_profile = "%(profile)s" in fmt |
275 | 344 |
276 def __init__(self, can_colors=False): | 345 def __init__(self, can_colors=False): |
277 super(SatFormatter, self).__init__(self._format) | 346 super(SatFormatter, self).__init__(self._format) |
278 self.can_colors = can_colors | 347 self.can_colors = can_colors |
279 | 348 |
286 # as formatting is handled in ansiColors in this case | 355 # as formatting is handled in ansiColors in this case |
287 if do_color: | 356 if do_color: |
288 record.color_start = log.COLOR_START | 357 record.color_start = log.COLOR_START |
289 record.color_end = log.COLOR_END | 358 record.color_end = log.COLOR_END |
290 else: | 359 else: |
291 record.color_start = record.color_end = '' | 360 record.color_start = record.color_end = "" |
292 s = super(SatFormatter, self).format(record) | 361 s = super(SatFormatter, self).format(record) |
293 if do_color: | 362 if do_color: |
294 s = ConfigureStandard.ansiColors(record.levelname, s) | 363 s = ConfigureStandard.ansiColors(record.levelname, s) |
295 if sys.platform == "android": | 364 if sys.platform == "android": |
296 # FIXME: dirty hack to workaround android encoding issue on log | 365 # FIXME: dirty hack to workaround android encoding issue on log |
297 # need to be fixed properly | 366 # need to be fixed properly |
298 return s.encode('ascii', 'ignore') | 367 return s.encode("ascii", "ignore") |
299 else: | 368 else: |
300 return s | 369 return s |
301 | 370 |
302 self.formatterClass = SatFormatter | 371 self.formatterClass = SatFormatter |
303 | 372 |
306 | 375 |
307 def configureLogger(self, logger): | 376 def configureLogger(self, logger): |
308 self.name_filter = log.FilterName(logger) if logger else None | 377 self.name_filter = log.FilterName(logger) if logger else None |
309 | 378 |
310 def configureColors(self, colors, force_colors, levels_taints_dict): | 379 def configureColors(self, colors, force_colors, levels_taints_dict): |
311 super(ConfigureStandard, self).configureColors(colors, force_colors, levels_taints_dict) | 380 super(ConfigureStandard, self).configureColors( |
381 colors, force_colors, levels_taints_dict | |
382 ) | |
312 self.formatterClass.with_colors = colors | 383 self.formatterClass.with_colors = colors |
313 self.formatterClass.force_colors = force_colors | 384 self.formatterClass.force_colors = force_colors |
314 if not colors and force_colors: | 385 if not colors and force_colors: |
315 raise ValueError("force_colors can't be used if colors is False") | 386 raise ValueError("force_colors can't be used if colors is False") |
316 | 387 |
321 if self.name_filter is not None: | 392 if self.name_filter is not None: |
322 hdlr.addFilter(self.name_filter) | 393 hdlr.addFilter(self.name_filter) |
323 | 394 |
324 def postTreatment(self): | 395 def postTreatment(self): |
325 import logging | 396 import logging |
397 | |
326 root_logger = logging.getLogger() | 398 root_logger = logging.getLogger() |
327 if len(root_logger.handlers) == 0: | 399 if len(root_logger.handlers) == 0: |
328 for handler, options in log.handlers.items(): | 400 for handler, options in log.handlers.items(): |
329 if handler == C.LOG_OPT_OUTPUT_DEFAULT: | 401 if handler == C.LOG_OPT_OUTPUT_DEFAULT: |
330 hdlr = logging.StreamHandler() | 402 hdlr = logging.StreamHandler() |
333 except AttributeError: | 405 except AttributeError: |
334 can_colors = False | 406 can_colors = False |
335 self._addHandler(root_logger, hdlr, can_colors=can_colors) | 407 self._addHandler(root_logger, hdlr, can_colors=can_colors) |
336 elif handler == C.LOG_OPT_OUTPUT_MEMORY: | 408 elif handler == C.LOG_OPT_OUTPUT_MEMORY: |
337 from logging.handlers import BufferingHandler | 409 from logging.handlers import BufferingHandler |
410 | |
338 class SatMemoryHandler(BufferingHandler): | 411 class SatMemoryHandler(BufferingHandler): |
339 def emit(self, record): | 412 def emit(self, record): |
340 super(SatMemoryHandler, self).emit(self.format(record)) | 413 super(SatMemoryHandler, self).emit(self.format(record)) |
414 | |
341 hdlr = SatMemoryHandler(options) | 415 hdlr = SatMemoryHandler(options) |
342 log.handlers[handler] = hdlr # we keep a reference to the handler to read the buffer later | 416 log.handlers[ |
417 handler | |
418 ] = ( | |
419 hdlr | |
420 ) # we keep a reference to the handler to read the buffer later | |
343 self._addHandler(root_logger, hdlr, can_colors=False) | 421 self._addHandler(root_logger, hdlr, can_colors=False) |
344 elif handler == C.LOG_OPT_OUTPUT_FILE: | 422 elif handler == C.LOG_OPT_OUTPUT_FILE: |
345 import os.path | 423 import os.path |
424 | |
346 for path in options: | 425 for path in options: |
347 hdlr = logging.FileHandler(os.path.expanduser(path)) | 426 hdlr = logging.FileHandler(os.path.expanduser(path)) |
348 self._addHandler(root_logger, hdlr, can_colors=False) | 427 self._addHandler(root_logger, hdlr, can_colors=False) |
349 else: | 428 else: |
350 raise ValueError("Unknown handler type") | 429 raise ValueError("Unknown handler type") |
356 """Return buffered logs | 435 """Return buffered logs |
357 | 436 |
358 @param size: number of logs to return | 437 @param size: number of logs to return |
359 """ | 438 """ |
360 mem_handler = log.handlers[C.LOG_OPT_OUTPUT_MEMORY] | 439 mem_handler = log.handlers[C.LOG_OPT_OUTPUT_MEMORY] |
361 return (log_msg for log_msg in mem_handler.buffer[size if size is None else -size:]) | 440 return ( |
441 log_msg for log_msg in mem_handler.buffer[size if size is None else -size :] | |
442 ) | |
362 | 443 |
363 | 444 |
364 log.configure_cls[C.LOG_BACKEND_BASIC] = ConfigureBasic | 445 log.configure_cls[C.LOG_BACKEND_BASIC] = ConfigureBasic |
365 log.configure_cls[C.LOG_BACKEND_TWISTED] = ConfigureTwisted | 446 log.configure_cls[C.LOG_BACKEND_TWISTED] = ConfigureTwisted |
366 log.configure_cls[C.LOG_BACKEND_STANDARD] = ConfigureStandard | 447 log.configure_cls[C.LOG_BACKEND_STANDARD] = ConfigureStandard |
448 | |
367 | 449 |
368 def configure(backend, **options): | 450 def configure(backend, **options): |
369 """Configure logging behaviour | 451 """Configure logging behaviour |
370 @param backend: can be: | 452 @param backend: can be: |
371 C.LOG_BACKEND_STANDARD: use standard logging module | 453 C.LOG_BACKEND_STANDARD: use standard logging module |
373 C.LOG_BACKEND_BASIC: use a basic print based logging | 455 C.LOG_BACKEND_BASIC: use a basic print based logging |
374 C.LOG_BACKEND_CUSTOM: use a given Logger subclass | 456 C.LOG_BACKEND_CUSTOM: use a given Logger subclass |
375 """ | 457 """ |
376 return log.configure(backend, **options) | 458 return log.configure(backend, **options) |
377 | 459 |
460 | |
378 def _parseOptions(options): | 461 def _parseOptions(options): |
379 """Parse string options as given in conf or environment variable, and return expected python value | 462 """Parse string options as given in conf or environment variable, and return expected python value |
380 | 463 |
381 @param options (dict): options with (key: name, value: string value) | 464 @param options (dict): options with (key: name, value: string value) |
382 """ | 465 """ |
383 COLORS = C.LOG_OPT_COLORS[0] | 466 COLORS = C.LOG_OPT_COLORS[0] |
384 LEVEL = C.LOG_OPT_LEVEL[0] | 467 LEVEL = C.LOG_OPT_LEVEL[0] |
385 | 468 |
386 if COLORS in options: | 469 if COLORS in options: |
387 if options[COLORS].lower() in ('1', 'true'): | 470 if options[COLORS].lower() in ("1", "true"): |
388 options[COLORS] = True | 471 options[COLORS] = True |
389 elif options[COLORS] == 'force': | 472 elif options[COLORS] == "force": |
390 options[COLORS] = True | 473 options[COLORS] = True |
391 options['force_colors'] = True | 474 options["force_colors"] = True |
392 else: | 475 else: |
393 options[COLORS] = False | 476 options[COLORS] = False |
394 if LEVEL in options: | 477 if LEVEL in options: |
395 level = options[LEVEL].upper() | 478 level = options[LEVEL].upper() |
396 if level not in C.LOG_LEVELS: | 479 if level not in C.LOG_LEVELS: |
397 level = C.LOG_LVL_INFO | 480 level = C.LOG_LVL_INFO |
398 options[LEVEL] = level | 481 options[LEVEL] = level |
482 | |
399 | 483 |
400 def satConfigure(backend=C.LOG_BACKEND_STANDARD, const=None, backend_data=None): | 484 def satConfigure(backend=C.LOG_BACKEND_STANDARD, const=None, backend_data=None): |
401 """Configure logging system for SàT, can be used by frontends | 485 """Configure logging system for SàT, can be used by frontends |
402 | 486 |
403 logs conf is read in SàT conf, then in environment variables. It must be done before Memory init | 487 logs conf is read in SàT conf, then in environment variables. It must be done before Memory init |
411 global C | 495 global C |
412 C = const | 496 C = const |
413 log.C = const | 497 log.C = const |
414 from sat.tools import config | 498 from sat.tools import config |
415 import os | 499 import os |
500 | |
416 log_conf = {} | 501 log_conf = {} |
417 sat_conf = config.parseMainConf() | 502 sat_conf = config.parseMainConf() |
418 for opt_name, opt_default in C.LOG_OPTIONS(): | 503 for opt_name, opt_default in C.LOG_OPTIONS(): |
419 try: | 504 try: |
420 log_conf[opt_name] = os.environ[''.join((C.ENV_PREFIX, C.LOG_OPT_PREFIX.upper(), opt_name.upper()))] | 505 log_conf[opt_name] = os.environ[ |
506 "".join((C.ENV_PREFIX, C.LOG_OPT_PREFIX.upper(), opt_name.upper())) | |
507 ] | |
421 except KeyError: | 508 except KeyError: |
422 log_conf[opt_name] = config.getConfig(sat_conf, C.LOG_OPT_SECTION, C.LOG_OPT_PREFIX + opt_name, opt_default) | 509 log_conf[opt_name] = config.getConfig( |
510 sat_conf, C.LOG_OPT_SECTION, C.LOG_OPT_PREFIX + opt_name, opt_default | |
511 ) | |
423 | 512 |
424 _parseOptions(log_conf) | 513 _parseOptions(log_conf) |
425 configure(backend, backend_data=backend_data, **log_conf) | 514 configure(backend, backend_data=backend_data, **log_conf) |