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