rename parsers, better journald integration
[logparse.git] / logparse / __init__.py
index ce4b891fd3c75f0d21b4e8c4bb43bf3a34daca1e..50cc98d03fb898b44af69009618ec920ab8a8ad7 100644 (file)
@@ -1,2 +1,99 @@
-__version__ = '1.0'
+"""
+This file sets up logging for the entire logparse package. Custom log formatter
+and handler classes are specified below and the logger is supplied to all
+subsequent modules, including parsers.
+"""
+
+__version__ = '2.0'
 __name__ = 'logparse'
+
+
+from copy import copy
+import logging
+import logging.handlers
+
+
+# Standard shell escape codes
+ESC = {
+        "reset": "\033[0m",
+        "color": "\033[1;%dm",
+        "bold": "\033[1m",
+        "underlined": "\033[4m"
+    }
+
+# Standard shell colour codes (30..39 are the foreground colors)
+DEFAULT = 39
+BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN = range(30, 37)
+
+# Map colours to log levels (used for level text only)
+COLORS = {
+        10: BLUE,       # debug
+        20: DEFAULT,    # info
+        30: YELLOW,     # warning
+        40: RED,        # error
+        50: RED         # critical
+    }
+
+# Template for formatting log messages
+FORMAT = ("{bold}%(module)-15s{reset}  %(levelname)-18s  %(message)s "
+        "({bold}%(filename)s{reset}:%(lineno)d)")
+
+
+class ColoredFormatter(logging.Formatter):
+    """
+    Custom implementation of a log formatter to apply standard shell colour
+    escape sequences depending on the log level. The original record is copied
+    so as to not interfere with subsequent handlings (i.e. the syslog handler).
+    """
+
+    def __init__(self, msg):
+        logging.Formatter.__init__(self, msg)
+
+    def format(self, record):
+        temprecord = copy(record)
+        levelname = temprecord.levelname
+        if temprecord.levelno in COLORS:
+            levelname_color = ESC["color"] % (COLORS[temprecord.levelno]) \
+                + levelname + ESC["reset"]
+            temprecord.levelname = levelname_color
+        temprecord.name = record.name.replace(__name__ + ".", "")
+        return logging.Formatter.format(self, temprecord)
+
+
+class ColoredLogger(logging.Logger):
+    """
+    Custom implementation of a logger object using the `ColoredFormatter` class
+    above. This class also includes a syslog handler to direct a minimal amount
+    of output to /dev/log.
+    """
+
+    message = FORMAT.format(**ESC)
+
+    def __init__(self, name):
+        """
+        Initialise the logger for the entire package. This is done here so that
+        the configuration is applied to all child modules. A syslog handler
+        is also initialised, with a min level of INFO so that journald doesn't
+        get spammed with debug messages..
+        """
+
+        logging.Logger.__init__(self, name)
+
+        color_formatter = ColoredFormatter(self.message)
+
+        syslog_handler = logging.handlers.SysLogHandler(address = '/dev/log')
+        syslog_handler.setLevel(logging.INFO)
+        syslog_handler.setFormatter(logging.Formatter(
+            fmt='{}[%(process)d]: (%(module)s) %(message)s'.format(__name__)))
+
+        console = logging.StreamHandler()
+        console.setFormatter(color_formatter)
+
+        self.addHandler(console)
+        self.addHandler(syslog_handler)
+        return
+
+
+# Initialise logger object
+logging.setLoggerClass(ColoredLogger)
+logger = logging.getLogger()