Add ColoredFormatter. Add setup.py.
authorRadek Brich <radek.brich@devl.cz>
Thu, 04 Apr 2013 20:24:34 +0200
changeset 2 d3ffa15f5886
parent 1 ee31f1bf17c1
child 3 cc27136cdead
Add ColoredFormatter. Add setup.py.
.hgignore
README
demo/demo_coloredformatter.py
pycolib/__init__.py
pycolib/ansicolor.py
pycolib/coloredformatter.py
setup.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Thu Apr 04 20:24:34 2013 +0200
@@ -0,0 +1,4 @@
+__pycache__
+^\.(pydev)?project$
+^\.settings$
+^build/
--- a/README	Wed Apr 03 20:37:05 2013 +0200
+++ b/README	Thu Apr 04 20:24:34 2013 +0200
@@ -4,6 +4,7 @@
 Pycolib is library of small, mostly one-file, modules with little or not (inter)dependencies.
 
  * ansicolor - change color of text in terminal using ANSI escape sequences
+ * coloredformatter - logging.Formatter which adds ANSI colors to output
  * makeurl - adjust string for using in URL by replacing symbols and combined unicode chars
  * prettysize - print file sizes in human readable form
  * soap - minimal SOAP client
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demo/demo_coloredformatter.py	Thu Apr 04 20:24:34 2013 +0200
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+
+from pycolib.coloredformatter import ColoredFormatter
+
+import logging
+
+
+def prepare_logger(name, level=logging.DEBUG):
+    logger = logging.getLogger(name)
+    logger.setLevel(level)
+    return logger
+
+
+def prepare_console_handler(level=logging.DEBUG):
+    handler = logging.StreamHandler()
+    formatter = ColoredFormatter('%(asctime)s %(levelname)-5s %(message)s', '%H:%M:%S')
+    formatter.set_color('message', 'RECV', 2)
+    formatter.set_color('message', 'SEND', 6)
+    handler.setFormatter(formatter)
+    handler.setLevel(level)
+    return handler
+
+
+def setup():
+    logging.addLevelName(21, 'RECV')
+    logging.addLevelName(22, 'SEND')
+
+    logger_main = prepare_logger('main')
+
+    handler_console = prepare_console_handler()
+    logger_main.addHandler(handler_console)
+
+
+def finish():
+    logging.shutdown()
+
+
+def main():
+    setup()
+    log = logging.getLogger('main')
+
+    log.info('test')
+
+    try:
+        raise Exception('test exception')
+    except:
+        log.exception('test exc')
+
+    log.log(21, 'recv')
+    log.log(22, 'send')
+
+    log.debug('debug')
+
+    finish()
+
+
+if __name__ == '__main__':
+    main()
+
--- a/pycolib/ansicolor.py	Wed Apr 03 20:37:05 2013 +0200
+++ b/pycolib/ansicolor.py	Thu Apr 04 20:24:34 2013 +0200
@@ -9,9 +9,9 @@
 def color(enable, fg=None, bg=None):
     '''
 
-    color(1) -- switch to bold
-    color(1,1) -- red foreground
-    color(1,3,4) -- red on blue
+    color(1) -- switch to bold, keep previous color
+    color(1, RED) -- red foreground
+    color(1, BOLD + YELLOW, BLUE) -- yellow on blue, bold
     color(0) -- reset
 
     '''
@@ -42,7 +42,7 @@
     else:
         return "\033[0m"
 
-def setcolor(enable, fg=None, bg=None):
+def set_color(enable, fg=None, bg=None):
     print(color(enable, fg, bg), end='')
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pycolib/coloredformatter.py	Thu Apr 04 20:24:34 2013 +0200
@@ -0,0 +1,81 @@
+import logging
+from copy import copy
+
+from pycolib.ansicolor import color, BOLD, WHITE, YELLOW, RED
+
+
+class ColoredFormatter(logging.Formatter):
+
+    def __init__(self, fmt, datefmt):
+        logging.Formatter.__init__(self, fmt, datefmt)
+        self._colors = {
+            'message': {
+                'default': (None, None),
+                'exception': (BOLD + YELLOW, RED),
+                },
+            'levelname': {
+                'default': (BOLD + WHITE, None),
+                'debug': (None, None),
+                },
+            'time': {
+                'default': (BOLD + WHITE, None),
+                'debug': (None, None),
+                },
+            }
+
+
+    def formatTime(self, record, datefmt=None):
+        """Override, add color as specified."""
+        formatted = logging.Formatter.formatTime(self, record, datefmt)
+        fg, bg = self.get_color('time', record)
+        if fg or bg:
+            formatted = color(1, fg, bg) + formatted + color(0)
+        return formatted
+
+
+    def format(self, record):
+        """Override, add color as specified."""
+        original_record = copy(record)
+
+        ### message color
+        fg, bg = self.get_color('message', record)
+        if fg or bg:
+            record.msg = color(1, fg, bg) + record.msg + color(0)
+
+        ### levelname color
+        fg, bg = self.get_color('levelname', record)
+        if fg or bg:
+            record.levelname = color(1, fg, bg) + record.levelname + color(0)
+
+        res = logging.Formatter.format(self, record)
+
+        record = original_record
+        return res
+
+
+    def set_color(self, fieldname, levelname, fg=None, bg=None):
+        """Specify color for parts of log message.
+
+        Args:
+            fieldname: Which field to apply: 'message' | 'levelname' | 'time'
+            levelname: Log level to apply, case insensitive: 'debug' | 'info' etc.
+                Custom levels are supported too.
+                Special name 'default' is used for unspecified levels.
+
+        """
+        self._colors[fieldname][levelname.lower()] = (fg, bg)
+
+
+    def get_color(self, fieldname, record):
+        """Get specified color for field levelname (from record)."""
+        colormap = self._colors[fieldname]
+        levelname = record.levelname.lower()
+        fg, bg = colormap['default']
+        if levelname in colormap:
+            fg, bg = colormap[levelname]
+        # exception is not real level, detect it using exc_info
+        if record.levelno == logging.ERROR and record.exc_info is not None \
+        and 'exception' in colormap:
+            fg, bg = colormap['exception']
+        return fg, bg
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/setup.py	Thu Apr 04 20:24:34 2013 +0200
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3.2
+
+from distutils.core import setup
+
+setup(
+    name='pycolib',
+    version='0.0.1',
+    description='Library of small auxiliary modules',
+    author='Radek Brich',
+    author_email='radek.brich@devl.cz',
+    url='http://hg.devl.cz/pycolib',
+    packages=['pycolib'],
+    )
+