Mercurial > libervia-backend
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 |