Changeset - a5a3bcc5ee89
[Not reviewed]
default
0 3 1
Marcin Kuzminski - 16 years ago 2010-05-16 15:06:20
marcin@python-works.com
Added colored formatter to project, and configs
4 files changed with 186 insertions and 10 deletions:
0 comments (0 inline, 0 general)
development.ini
Show inline comments
 
################################################################################
 
################################################################################
 
# pylons_app - Pylons environment configuration                                #
 
#                                                                              # 
 
# The %(here)s variable will be replaced with the parent directory of this file#
 
################################################################################
 

	
 
[DEFAULT]
 
debug = true
 
############################################
 
## Uncomment and replace with the address ##
 
## which should receive any error reports ##
 
############################################
 
#email_to = marcin.kuzminski@etelko.pl
 
#smtp_server = mail.etelko.pl
 
#error_email_from = paste_error@localhost
 
#smtp_username = 
 
#smtp_password = 
 
#error_message = 'mercurial crash !'
 

	
 
[server:main]
 
##nr of threads to spawn
 
threadpool_workers = 5
 

	
 
##max request before
 
threadpool_max_requests = 2
 

	
 
##option to use threads of process
 
use_threadpool = true
 

	
 
use = egg:Paste#http
 
host = 127.0.0.1
 
port = 5000
 

	
 
[app:main]
 
use = egg:pylons_app
 
full_stack = true
 
static_files = true
 
lang=en
 
cache_dir = %(here)s/data
 
repos_name = Python-works
 

	
 
####################################
 
###         BEAKER CACHE        ####
 
####################################
 
beaker.cache.data_dir=/tmp/cache/data
 
beaker.cache.lock_dir=/tmp/cache/lock
 
beaker.cache.regions=short_term,long_term
 
beaker.cache.short_term.type=file
 
beaker.cache.short_term.expire=3600
 
beaker.cache.short_term.type=memory
 
beaker.cache.short_term.expire=60
 

	
 
################################################################################
 
## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*  ##
 
## Debug mode will enable the interactive debugging tool, allowing ANYONE to  ##
 
## execute malicious code after an exception is raised.                       ##
 
################################################################################
 
#set debug = false
 

	
 
##################################
 
###       LOGVIEW CONFIG       ###
 
##################################
 
logview.sqlalchemy = #faa
 
logview.pylons.templating = #bfb
 
logview.pylons.util = #eee
 

	
 
#########################################################
 
### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG    ###
 
#########################################################
 
sqlalchemy.db1.url = sqlite:///%(here)s/hg_app.db
 
#sqlalchemy.db1.echo = False
 
#sqlalchemy.db1.pool_recycle = 3600
 
sqlalchemy.convert_unicode = true
 

	
 
################################
 
### LOGGING CONFIGURATION   ####
 
################################
 
[loggers]
 
keys = root, routes, pylons_app, sqlalchemy
 

	
 
[handlers]
 
keys = console
 

	
 
[formatters]
 
keys = generic
 
keys = generic,color_formatter
 

	
 
#############
 
## LOGGERS ##
 
#############
 
[logger_root]
 
level = NOTSET
 
handlers = console
 

	
 
[logger_routes]
 
level = DEBUG
 
handlers = console
 
qualname = routes.middleware
 
# "level = DEBUG" logs the route matched and routing variables.
 

	
 
[logger_pylons_app]
 
level = DEBUG
 
handlers = console
 
qualname = pylons_app
 

	
 
propagate = 0
 

	
 
[logger_sqlalchemy]
 
level = INFO
 
level = ERROR
 
handlers = console
 
qualname = sqlalchemy.engine
 
propagate = 0
 

	
 
##############
 
## HANDLERS ##
 
##############
 

	
 
[handler_console]
 
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
production.ini
Show inline comments
 
@@ -9,121 +9,126 @@
 
debug = true
 
############################################
 
## Uncomment and replace with the address ##
 
## which should receive any error reports ##
 
############################################
 
#email_to = marcin.kuzminski@etelko.pl
 
#smtp_server = mail.etelko.pl
 
#error_email_from = paste_error@localhost
 
#smtp_username = 
 
#smtp_password = 
 
#error_message = 'mercurial crash !'
 

	
 
[server:main]
 
##nr of threads to spawn
 
threadpool_workers = 5
 

	
 
##max request before
 
threadpool_max_requests = 2
 

	
 
##option to use threads of process
 
use_threadpool = true
 

	
 
use = egg:Paste#http
 
host = 127.0.0.1
 
port = 8001
 

	
 
[app:main]
 
use = egg:pylons_app
 
full_stack = true
 
static_files = true
 
lang=en
 
cache_dir = %(here)s/data
 
repos_name = Python-works
 

	
 
####################################
 
###         BEAKER CACHE        ####
 
####################################
 
beaker.cache.data_dir=/tmp/cache/data
 
beaker.cache.lock_dir=/tmp/cache/lock
 
beaker.cache.regions=short_term,long_term
 
beaker.cache.short_term.type=file
 
beaker.cache.short_term.expire=3600
 
beaker.cache.short_term.type=memory
 
beaker.cache.short_term.expire=60
 
    
 
################################################################################
 
## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*  ##
 
## Debug mode will enable the interactive debugging tool, allowing ANYONE to  ##
 
## execute malicious code after an exception is raised.                       ##
 
################################################################################
 
set debug = false
 

	
 
##################################
 
###       LOGVIEW CONFIG       ###
 
##################################
 
logview.sqlalchemy = #faa
 
logview.pylons.templating = #bfb
 
logview.pylons.util = #eee
 

	
 
#########################################################
 
### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG    ###
 
#########################################################
 
sqlalchemy.db1.url = sqlite:///%(here)s/hg_app.db
 
#sqlalchemy.db1.echo = True
 
#sqlalchemy.db1.pool_recycle = 3600
 
sqlalchemy.convert_unicode = true
 

	
 
################################
 
### LOGGING CONFIGURATION   ####
 
################################
 
[loggers]
 
keys = root, routes, pylons_app, sqlalchemy
 

	
 
[handlers]
 
keys = console
 

	
 
[formatters]
 
keys = generic
 

	
 
#############
 
## LOGGERS ##
 
#############
 
[logger_root]
 
level = INFO
 
handlers = console
 

	
 
[logger_routes]
 
level = INFO
 
handlers = console
 
qualname = routes.middleware
 
# "level = DEBUG" logs the route matched and routing variables.
 

	
 
[logger_pylons_app]
 
level = DEBUG
 
handlers = console
 
qualname = pylons_app
 

	
 
propagate = 0
 

	
 
[logger_sqlalchemy]
 
level = DEBUG
 
level = ERROR
 
handlers = console
 
qualname = sqlalchemy.engine
 
propagate = 0
 

	
 
##############
 
## HANDLERS ##
 
##############
 

	
 
[handler_console]
 
class = StreamHandler
 
args = (sys.stderr,)
 
level = NOTSET
 
formatter = generic
 

	
 
################
 
## 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
pylons_app/lib/colored_formatter.py
Show inline comments
 
new file 100644
 
#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
pylons_app/lib/timerproxy.py
Show inline comments
 
from sqlalchemy.interfaces import ConnectionProxy
 
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):
 
        now = time.time()
 
        try:
 
            log.info(">>>>> STARTING QUERY >>>>>")
 
            return execute(cursor, statement, parameters, context)
 
        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)
 

	
 

	
 

	
 

	
0 comments (0 inline, 0 general)