changeset 153:a5a3bcc5ee89

Added colored formatter to project, and configs
author Marcin Kuzminski <marcin@python-works.com>
date Sun, 16 May 2010 15:06:20 +0200
parents 0c00fbaff55a
children 085a937368d9
files development.ini production.ini pylons_app/lib/colored_formatter.py pylons_app/lib/timerproxy.py
diffstat 4 files changed, 186 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/development.ini	Sat May 15 19:53:23 2010 +0200
+++ b/development.ini	Sun May 16 15:06:20 2010 +0200
@@ -83,7 +83,7 @@
 keys = console
 
 [formatters]
-keys = generic
+keys = generic,color_formatter
 
 #############
 ## LOGGERS ##
@@ -102,10 +102,10 @@
 level = DEBUG
 handlers = console
 qualname = pylons_app
-
+propagate = 0
 
 [logger_sqlalchemy]
-level = INFO
+level = ERROR
 handlers = console
 qualname = sqlalchemy.engine
 propagate = 0
@@ -118,13 +118,17 @@
 class = StreamHandler
 args = (sys.stderr,)
 level = NOTSET
-formatter = generic
+formatter = color_formatter
 
 ################
 ## FORMATTERS ##
 ################
 
 [formatter_generic]
-format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
+format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
 datefmt = %Y-%m-%d %H:%M:%S
 
+[formatter_color_formatter]
+class=pylons_app.lib.colored_formatter.ColorFormatter
+format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
+datefmt = %Y-%m-%d %H:%M:%S
\ No newline at end of file
--- a/production.ini	Sat May 15 19:53:23 2010 +0200
+++ b/production.ini	Sun May 16 15:06:20 2010 +0200
@@ -102,12 +102,13 @@
 level = DEBUG
 handlers = console
 qualname = pylons_app
-
+propagate = 0
 
 [logger_sqlalchemy]
-level = DEBUG
+level = ERROR
 handlers = console
 qualname = sqlalchemy.engine
+propagate = 0
 
 ##############
 ## HANDLERS ##
@@ -124,6 +125,10 @@
 ################
 
 [formatter_generic]
-format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
+format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
 datefmt = %Y-%m-%d %H:%M:%S
 
+[formatter_color_formatter]
+class=pylons_app.lib.colored_formatter.ColorFormatter
+format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
+datefmt = %Y-%m-%d %H:%M:%S
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pylons_app/lib/colored_formatter.py	Sun May 16 15:06:20 2010 +0200
@@ -0,0 +1,141 @@
+#import logging
+## now we patch Python code to add color support to logging.StreamHandler
+#def add_coloring_to_emit_windows(fn):
+#        # add methods we need to the class
+#    def _out_handle(self):
+#        import ctypes
+#        return ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
+#    out_handle = property(_out_handle)
+#
+#    def _set_color(self, code):
+#        import ctypes
+#        # Constants from the Windows API
+#        self.STD_OUTPUT_HANDLE = -11
+#        hdl = ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
+#        ctypes.windll.kernel32.SetConsoleTextAttribute(hdl, code)
+#
+#    setattr(logging.StreamHandler, '_set_color', _set_color)
+#
+#    def new(*args):
+#        FOREGROUND_BLUE      = 0x0001 # text color contains blue.
+#        FOREGROUND_GREEN     = 0x0002 # text color contains green.
+#        FOREGROUND_RED       = 0x0004 # text color contains red.
+#        FOREGROUND_INTENSITY = 0x0008 # text color is intensified.
+#        FOREGROUND_WHITE     = FOREGROUND_BLUE|FOREGROUND_GREEN |FOREGROUND_RED
+#       # winbase.h
+#        STD_INPUT_HANDLE = -10
+#        STD_OUTPUT_HANDLE = -11
+#        STD_ERROR_HANDLE = -12
+#
+#        # wincon.h
+#        FOREGROUND_BLACK     = 0x0000
+#        FOREGROUND_BLUE      = 0x0001
+#        FOREGROUND_GREEN     = 0x0002
+#        FOREGROUND_CYAN      = 0x0003
+#        FOREGROUND_RED       = 0x0004
+#        FOREGROUND_MAGENTA   = 0x0005
+#        FOREGROUND_YELLOW    = 0x0006
+#        FOREGROUND_GREY      = 0x0007
+#        FOREGROUND_INTENSITY = 0x0008 # foreground color is intensified.
+#
+#        BACKGROUND_BLACK     = 0x0000
+#        BACKGROUND_BLUE      = 0x0010
+#        BACKGROUND_GREEN     = 0x0020
+#        BACKGROUND_CYAN      = 0x0030
+#        BACKGROUND_RED       = 0x0040
+#        BACKGROUND_MAGENTA   = 0x0050
+#        BACKGROUND_YELLOW    = 0x0060
+#        BACKGROUND_GREY      = 0x0070
+#        BACKGROUND_INTENSITY = 0x0080 # background color is intensified.     
+#
+#        levelno = args[1].levelno
+#        if(levelno>=50):
+#            color = BACKGROUND_YELLOW | FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY 
+#        elif(levelno>=40):
+#            color = FOREGROUND_RED | FOREGROUND_INTENSITY
+#        elif(levelno>=30):
+#            color = FOREGROUND_YELLOW | FOREGROUND_INTENSITY
+#        elif(levelno>=20):
+#            color = FOREGROUND_GREEN
+#        elif(levelno>=10):
+#            color = FOREGROUND_MAGENTA
+#        else:
+#            color =  FOREGROUND_WHITE
+#        args[0]._set_color(color)
+#
+#        ret = fn(*args)
+#        args[0]._set_color( FOREGROUND_WHITE )
+#        #print "after"
+#        return ret
+#    return new
+#
+#def add_coloring_to_emit_ansi(fn):
+#    # add methods we need to the class
+#    def new(*args):
+#        levelno = args[1].levelno
+#        if(levelno>=50):
+#            color = '\x1b[31m' # red
+#        elif(levelno>=40):
+#            color = '\x1b[31m' # red
+#        elif(levelno>=30):
+#            color = '\x1b[33m' # yellow
+#        elif(levelno>=20):
+#            color = '\x1b[32m' # green 
+#        elif(levelno>=10):
+#            color = '\x1b[35m' # pink
+#        else:
+#            color = '\x1b[0m' # normal
+#        args[1].msg = color + args[1].msg +  '\x1b[0m'  # normal
+#        #print "after"
+#        return fn(*args)
+#    return new
+#
+#import platform
+#if platform.system()=='Windows':
+#    # Windows does not support ANSI escapes and we are using API calls to set the console color
+#    logging.StreamHandler.emit = add_coloring_to_emit_windows(logging.StreamHandler.emit)
+#else:
+#    # all non-Windows platforms are supporting ANSI escapes so we use them
+#    logging.StreamHandler.emit = add_coloring_to_emit_ansi(logging.StreamHandler.emit)
+#    #log = logging.getLogger()
+#    #log.addFilter(log_filter())
+#    #//hdlr = logging.StreamHandler()
+#    #//hdlr.setFormatter(formatter())
+
+import logging
+
+BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
+
+# Sequences 
+RESET_SEQ = "\033[0m"
+COLOR_SEQ = "\033[1;%dm"
+BOLD_SEQ = "\033[1m"
+
+COLORS = {
+    'CRITICAL': MAGENTA, # level 50
+    'ERROR': RED, # level 40
+    'WARNING': CYAN, # level 30
+    'INFO': GREEN, # level 20
+    'DEBUG': BLUE, # level 10
+}
+
+class ColorFormatter(logging.Formatter):
+
+    def __init__(self, *args, **kwargs):
+        # can't do super(...) here because Formatter is an old school class
+        logging.Formatter.__init__(self, *args, **kwargs)
+
+    def format(self, record):
+        """
+        Changes record's levelname to use with COLORS enum
+        """
+        
+        levelname = record.levelname
+        start = COLOR_SEQ % (COLORS[levelname])
+        def_record = logging.Formatter.format(self, record)
+        end = RESET_SEQ
+        
+        colored_record = start + def_record + end
+        return colored_record
+
+logging.ColorFormatter = ColorFormatter
--- a/pylons_app/lib/timerproxy.py	Sat May 15 19:53:23 2010 +0200
+++ b/pylons_app/lib/timerproxy.py	Sun May 16 15:06:20 2010 +0200
@@ -2,6 +2,28 @@
 import time
 import logging
 log = logging.getLogger('timerproxy')
+BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
+
+def color_sql(sql):
+    COLOR_SEQ = "\033[1;%dm"
+    COLOR_SQL = YELLOW
+    normal = '\x1b[0m'
+    return COLOR_SEQ % COLOR_SQL + sql + normal 
+
+def format_sql(sql):
+    sql = color_sql(sql)
+    sql = sql.replace('SELECT', '\n    SELECT \n\t')\
+        .replace('FROM', '\n    FROM')\
+        .replace('ORDER BY', '\n    ORDER BY')\
+        .replace('LIMIT', '\n    LIMIT')\
+        .replace('WHERE', '\n    WHERE')\
+        .replace('AND', '\n    AND')\
+        .replace('LEFT', '\n    LEFT')\
+        .replace('INNER', '\n    INNER')\
+        .replace('INSERT', '\n    INSERT')\
+        .replace('DELETE', '\n    DELETE')
+    return sql
+
 
 class TimerProxy(ConnectionProxy):
     def cursor_execute(self, execute, cursor, statement, parameters, context, executemany):
@@ -12,7 +34,11 @@
         finally:
             total = time.time() - now
             try:
-                log.info("Query: %s" % statement % parameters)
+                log.info(format_sql("Query: %s" % statement % parameters))
             except TypeError:
-                log.info("Query: %s %s" % (statement, parameters))
+                log.info(format_sql("Query: %s %s" % (statement, parameters)))
             log.info("<<<<< TOTAL TIME: %f <<<<<" % total)
+
+
+
+