starcluster.logger

Package starcluster :: Module logger |
[hide private]
[frames] | no frames]

# Source Code for Module starcluster.logger

      1  #!/usr/bin/env python
      2  """
      3  StarCluster logging module
      4  """
      5  import os
      6  import types
      7  import logging
      8  import logging.handlers
      9  import textwrap
     10
     11  from starcluster import static
     12
     13  INFO = logging.INFO
     14  DEBUG = logging.DEBUG
     15  WARN = logging.WARN
     16  ERROR = logging.ERROR
     17  CRITICAL = logging.CRITICAL
     18  FATAL = logging.FATAL
     19
     20  RAW_FORMAT = "%(message)s\n"
     21  INFO_FORMAT = " ".join(['>>>', "%(message)s\n"])
     22  DEBUG_FORMAT = "%(filename)s:%(lineno)d - %(levelname)s - %(message)s\n"
     23  DEBUG_FORMAT_PID = ("PID: %s " % str(static.PID)) + DEBUG_FORMAT
     24  DEFAULT_CONSOLE_FORMAT = "%(levelname)s - %(message)s\n"
     25  ERROR_CONSOLE_FORMAT = " ".join(['!!!', DEFAULT_CONSOLE_FORMAT])
     26  WARN_CONSOLE_FORMAT = " ".join(['***', DEFAULT_CONSOLE_FORMAT])
     27
     28
     29 -class ConsoleLogger(logging.StreamHandler):
     30
     31      formatters = {
     32          INFO: logging.Formatter(INFO_FORMAT),
     33          DEBUG: logging.Formatter(DEBUG_FORMAT),
     34          WARN: logging.Formatter(WARN_CONSOLE_FORMAT),
     35          ERROR: logging.Formatter(ERROR_CONSOLE_FORMAT),
     36          CRITICAL: logging.Formatter(ERROR_CONSOLE_FORMAT),
     37          FATAL: logging.Formatter(ERROR_CONSOLE_FORMAT),
     38          'raw': logging.Formatter(RAW_FORMAT),
     39      }
     40
     41 -    def format(self, record):
     42          if hasattr(record, '__raw__'):
     43              result = self.formatters['raw'].format(record)
     44          else:
     45              result = self.formatters[record.levelno].format(record)
     46          if hasattr(record, '__nonewline__'):
     47              result = result.rstrip()
     48          return result
     49
     50 -    def _wrap(self, msg):
     51          msg = textwrap.wrap(msg, width=60, replace_whitespace=False,
     52                              drop_whitespace=True, break_on_hyphens=False)
     53          return msg or ['']
     54
     55 -    def _emit_textwrap(self, record):
     56          lines = []
     57          for line in record.msg.splitlines():
     58              lines.extend(self._wrap(line))
     59          if hasattr(record, '__nosplitlines__'):
     60              lines = ['\n'.join(lines)]
     61          for line in lines:
     62              record.msg = line
     63              self._emit(record)
     64
     65 -    def _emit(self, record):
     66          msg = self.format(record)
     67          fs = "%s"
     68          if not hasattr(types, "UnicodeType"):
     69               # if no unicode support...
     70              self.stream.write(fs % msg)
     71          else:
     72              try:
     73                  self.stream.write(fs % msg)
     74              except UnicodeError:
     75                  self.stream.write(fs % msg.encode("UTF-8"))
     76          self.flush()
     77
     78 -    def emit(self, record):
     79          try:
     80              if hasattr(record, '__textwrap__'):
     81                  self._emit_textwrap(record)
     82              else:
     83                  self._emit(record)
     84          except (KeyboardInterrupt, SystemExit):
     85              raise
     86          except:
     87              self.handleError(record)
     88
     89
     90 -class NullHandler(logging.Handler):
     91 -    def emit(self, record):
     92          pass
     93
     94
     95 -def get_starcluster_logger():
     96      log = logging.getLogger('starcluster')
     97      log.addHandler(NullHandler())
     98      return log
     99
    100
    101  log = get_starcluster_logger()
    102  console = ConsoleLogger()
    103
    104
    105 -def configure_sc_logging(use_syslog=False):
    106      """
    107      Configure logging for StarCluster *application* code
    108
    109      By default StarCluster's logger has no formatters and a NullHandler so that
    110      other developers using StarCluster as a library can configure logging as
    111      they see fit. This method is used in StarCluster's application code (ie the
    112      'starcluster' command) to toggle StarCluster's application specific
    113      formatters/handlers
    114
    115      use_syslog - enable logging all messages to syslog. currently only works if
    116      /dev/log exists on the system (standard for most Linux distros)
    117      """
    118      log.setLevel(logging.DEBUG)
    119      formatter = logging.Formatter(DEBUG_FORMAT_PID.rstrip())
    120      rfh = logging.handlers.RotatingFileHandler(static.DEBUG_FILE,
    121                                                 maxBytes=1048576,
    122                                                 backupCount=2)
    123      rfh.setLevel(logging.DEBUG)
    124      rfh.setFormatter(formatter)
    125      log.addHandler(rfh)
    126      console.setLevel(logging.INFO)
    127      log.addHandler(console)
    128      syslog_device = '/dev/log'
    129      if use_syslog and os.path.exists(syslog_device):
    130          log.debug("Logging to %s" % syslog_device)
    131          syslog_handler = logging.handlers.SysLogHandler(address=syslog_device)
    132          syslog_handler.setFormatter(formatter)
    133          syslog_handler.setLevel(logging.DEBUG)
    134          log.addHandler(syslog_handler)
    135
    136
    137 -def configure_paramiko_logging():
    138      """
    139      Configure paramiko to log to a file for debug
    140      """
    141      l = logging.getLogger("paramiko")
    142      l.setLevel(logging.DEBUG)
    143      lh = logging.handlers.RotatingFileHandler(static.SSH_DEBUG_FILE,
    144                                                maxBytes=1048576,
    145                                                backupCount=2)
    146      lh.setLevel(logging.DEBUG)
    147      format = (('PID: %s ' % str(static.PID)) + \
    148                '%(levelname)-.3s [%(asctime)s.%(msecs)03d] ' + \
    149                'thr=%(_threadid)-3d %(name)s: %(message)s')
    150      date_format = '%Y%m%d-%H:%M:%S'
    151      lh.setFormatter(logging.Formatter(format, date_format))
    152      l.addHandler(lh)
    153
    154
    155 -def configure_boto_logging():
    156      """
    157      Configure boto to log to a file for debug
    158      """
    159      l = logging.getLogger("boto")
    160      l.setLevel(logging.DEBUG)
    161      lh = logging.handlers.RotatingFileHandler(static.AWS_DEBUG_FILE,
    162                                                maxBytes=1048576,
    163                                                backupCount=2)
    164      lh.setLevel(logging.DEBUG)
    165      format = (('PID: %s ' % str(static.PID)) + \
    166                '%(levelname)-.3s [%(asctime)s.%(msecs)03d] ' + \
    167                '%(name)s: %(message)s')
    168      date_format = '%Y%m%d-%H:%M:%S'
    169      lh.setFormatter(logging.Formatter(format, date_format))
    170      l.addHandler(lh)
    171