comparison src/core/log.py @ 1012:c8771279497e

core(log): standard backend: colors are now checked on a per handler basis
author Goffi <goffi@goffi.org>
date Mon, 05 May 2014 20:16:08 +0200
parents 73a0b7f94674
children 11409a6c16c7
comparison
equal deleted inserted replaced
1011:5a6354ff468c 1012:c8771279497e
371 371
372 372
373 class ConfigureTwisted(ConfigureBasic): 373 class ConfigureTwisted(ConfigureBasic):
374 LOGGER_CLASS = TwistedLogger 374 LOGGER_CLASS = TwistedLogger
375 375
376 def changeObserver(self, observer, can_color=False): 376 def changeObserver(self, observer, can_colors=False):
377 """Install a hook on observer to manage SàT specificities 377 """Install a hook on observer to manage SàT specificities
378 378
379 @param observer: original observer to hook 379 @param observer: original observer to hook
380 @param can_color: True if observer can display ansi colors 380 @param can_colors: True if observer can display ansi colors
381 """ 381 """
382 def observer_hook(event): 382 def observer_hook(event):
383 """redirect non SàT log to twisted_logger, and add colors when possible""" 383 """redirect non SàT log to twisted_logger, and add colors when possible"""
384 if 'sat_logged' in event: # we only want our own logs, other are managed by twistedObserver 384 if 'sat_logged' in event: # we only want our own logs, other are managed by twistedObserver
385 # we add colors if possible 385 # we add colors if possible
386 if (can_color and self.LOGGER_CLASS.colors) or self.LOGGER_CLASS.force_colors: 386 if (can_colors and self.LOGGER_CLASS.colors) or self.LOGGER_CLASS.force_colors:
387 message = event.get('message', tuple()) 387 message = event.get('message', tuple())
388 level = event.get('level', C.LOG_LVL_INFO) 388 level = event.get('level', C.LOG_LVL_INFO)
389 if message: 389 if message:
390 event['message'] = (_ansiColors(level, ''.join(message)),) # must be a tuple 390 event['message'] = (_ansiColors(level, ''.join(message)),) # must be a tuple
391 observer(event) # we can now call the original observer 391 observer(event) # we can now call the original observer
399 @param observer: original observer to hook 399 @param observer: original observer to hook
400 """ 400 """
401 log_obs = observer.__self__ 401 log_obs = observer.__self__
402 log_file = log_obs.write.__self__ 402 log_file = log_obs.write.__self__
403 try: 403 try:
404 can_color = log_file.isatty() 404 can_colors = log_file.isatty()
405 except AttributeError: 405 except AttributeError:
406 can_color = False 406 can_colors = False
407 return self.changeObserver(observer, can_color=can_color) 407 return self.changeObserver(observer, can_colors=can_colors)
408 408
409 def installObserverHook(self, observer): 409 def installObserverHook(self, observer):
410 """Check observer type and install SàT hook when possible 410 """Check observer type and install SàT hook when possible
411 411
412 @param observer: observer to hook 412 @param observer: observer to hook
415 if hasattr(observer, '__self__'): 415 if hasattr(observer, '__self__'):
416 ori = observer 416 ori = observer
417 if isinstance(observer.__self__, self.log.FileLogObserver): 417 if isinstance(observer.__self__, self.log.FileLogObserver):
418 observer = self.changeFileLogObserver(observer) 418 observer = self.changeFileLogObserver(observer)
419 elif isinstance(observer.__self__, self.log.DefaultObserver): 419 elif isinstance(observer.__self__, self.log.DefaultObserver):
420 observer = self.changeObserver(observer, can_color=True) 420 observer = self.changeObserver(observer, can_colors=True)
421 else: 421 else:
422 # we use print because log system is not fully initialized 422 # we use print because log system is not fully initialized
423 print("Unmanaged observer [%s]" % observer) 423 print("Unmanaged observer [%s]" % observer)
424 return observer 424 return observer
425 self.observers[ori] = observer 425 self.observers[ori] = observer
549 level = C.LOG_LVL_DEBUG 549 level = C.LOG_LVL_DEBUG
550 self.level = level 550 self.level = level
551 551
552 def configureFormat(self, fmt): 552 def configureFormat(self, fmt):
553 import logging 553 import logging
554 format_ = fmt
555 554
556 class SatFormatter(logging.Formatter): 555 class SatFormatter(logging.Formatter):
557 u"""Formatter which manage SàT specificities""" 556 u"""Formatter which manage SàT specificities"""
558 557 _format = fmt
559 def __init__(self, fmt=None, datefmt=None): 558
560 super(SatFormatter, self).__init__(fmt, datefmt) 559 def __init__(self, can_colors=False):
560 super(SatFormatter, self).__init__(self._format)
561 self.can_colors = can_colors
561 562
562 def format(self, record): 563 def format(self, record):
563 s = super(SatFormatter, self).format(record) 564 s = super(SatFormatter, self).format(record)
564 if self.with_color: 565 if self.with_colors and (self.can_colors or self.force_colors):
565 s = _ansiColors(record.levelname, s) 566 s = _ansiColors(record.levelname, s)
566 return s 567 return s
567 568
568 self.formatter = SatFormatter(format_) 569 self.formatterClass = SatFormatter
569 570
570 def configureOutput(self, output): 571 def configureOutput(self, output):
571 self.manageOutputs(output) 572 self.manageOutputs(output)
572 573
573 def configureLogger(self, logger): 574 def configureLogger(self, logger):
574 self.name_filter = FilterName(logger) if logger else None 575 self.name_filter = FilterName(logger) if logger else None
575 576
576 def configureColors(self, colors, force_colors): 577 def configureColors(self, colors, force_colors):
577 import sys 578 self.formatterClass.with_colors = colors
578 self.formatter.with_color = colors & (sys.stdout.isatty() or force_colors) 579 self.formatterClass.force_colors = force_colors
579 if not colors and force_colors: 580 if not colors and force_colors:
580 raise ValueError("force_colors can't be used if colors is False") 581 raise ValueError("force_colors can't be used if colors is False")
581 582
582 def _addHandler(self, root_logger, hdlr): 583 def _addHandler(self, root_logger, hdlr, can_colors=False):
583 hdlr.setFormatter(self.formatter) 584 hdlr.setFormatter(self.formatterClass(can_colors))
584 root_logger.addHandler(hdlr) 585 root_logger.addHandler(hdlr)
585 root_logger.setLevel(self.level) 586 root_logger.setLevel(self.level)
586 if self.name_filter is not None: 587 if self.name_filter is not None:
587 hdlr.addFilter(self.name_filter) 588 hdlr.addFilter(self.name_filter)
588 589
591 root_logger = logging.getLogger() 592 root_logger = logging.getLogger()
592 if len(root_logger.handlers) == 0: 593 if len(root_logger.handlers) == 0:
593 for handler, options in _handlers.items(): 594 for handler, options in _handlers.items():
594 if handler == C.LOG_OPT_OUTPUT_DEFAULT: 595 if handler == C.LOG_OPT_OUTPUT_DEFAULT:
595 hdlr = logging.StreamHandler() 596 hdlr = logging.StreamHandler()
596 self._addHandler(root_logger, hdlr) 597 try:
598 can_colors = hdlr.stream.isatty()
599 except AttributeError:
600 can_colors = False
601 self._addHandler(root_logger, hdlr, can_colors=can_colors)
597 elif handler == C.LOG_OPT_OUTPUT_MEMORY: 602 elif handler == C.LOG_OPT_OUTPUT_MEMORY:
598 from logging.handlers import BufferingHandler 603 from logging.handlers import BufferingHandler
599 class SatMemoryHandler(BufferingHandler): 604 class SatMemoryHandler(BufferingHandler):
600 def emit(self, record): 605 def emit(self, record):
601 super(SatMemoryHandler, self).emit(self.format(record)) 606 super(SatMemoryHandler, self).emit(self.format(record))
602 hdlr = SatMemoryHandler(options) 607 hdlr = SatMemoryHandler(options)
603 _handlers[handler] = hdlr # we keep a reference to the handler to read the buffer later 608 _handlers[handler] = hdlr # we keep a reference to the handler to read the buffer later
604 self._addHandler(root_logger, hdlr) 609 self._addHandler(root_logger, hdlr, can_colors=False)
605 elif handler == C.LOG_OPT_OUTPUT_FILE: 610 elif handler == C.LOG_OPT_OUTPUT_FILE:
606 import os.path 611 import os.path
607 for path in options: 612 for path in options:
608 hdlr = logging.FileHandler(os.path.expanduser(path)) 613 hdlr = logging.FileHandler(os.path.expanduser(path))
609 self._addHandler(root_logger, hdlr) 614 self._addHandler(root_logger, hdlr, can_colors=False)
610 else: 615 else:
611 raise ValueError("Unknown handler type") 616 raise ValueError("Unknown handler type")
612 else: 617 else:
613 root_logger.warning(u"Handlers already set on root logger") 618 root_logger.warning(u"Handlers already set on root logger")
614 619