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)