207 lines
6.1 KiB
Python
Executable File
207 lines
6.1 KiB
Python
Executable File
#!/usr/bin/env python
|
|
#-*- encoding: gbk -*-
|
|
#
|
|
|
|
import ConfigParser
|
|
import logging
|
|
import time, os
|
|
from logging.handlers import RotatingFileHandler
|
|
import platform
|
|
|
|
#global
|
|
log_msg_root = '_msg_log_'
|
|
|
|
#log_stderr_format = '$RESET$COLOR<%(levelname)-5s><%(name)s:%(process)d:%(threadName)s><%(filename)s:%(lineno)d>%(message)s'
|
|
log_stderr_format = '$COLOR$BOLD<%(levelname)-5s><%(name)s:%(process)d:%(threadName)s>$RESET$COLOR<%(filename)s:%(lineno)d>%(message)s'
|
|
#log_stderr_format = "$COLOR%(levelname)s $RESET %(asctime)s $BOLD$COLOR%(name)s$RESET %(message)s"
|
|
|
|
if platform.system() == 'Windows':
|
|
log_file_format = '<%(levelname)s><%(name)s:%(process)d>%(message)s'
|
|
else:
|
|
log_file_format = '%(asctime)s <%(levelname)-5s><%(name)s:%(process)d:%(threadName)s><%(filename)s:%(lineno)d>%(message)s'
|
|
|
|
|
|
# for colorful stderr output, copy from http://stackoverflow.com/questions/384076/how-can-i-make-the-python-logging-output-to-be-colored
|
|
# by rrt
|
|
|
|
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
|
|
RESET_SEQ = "\033[0m"
|
|
#COLOR_SEQ = "\033[1;%dm" # color & bold
|
|
COLOR_SEQ = "\033[0;%dm" # color only
|
|
BOLD_SEQ = "\033[1m"
|
|
|
|
COLORS={
|
|
'WARNING':WHITE,
|
|
'INFO':YELLOW,
|
|
'DEBUG':GREEN,
|
|
'CRITICAL':YELLOW,
|
|
'ERROR':RED,
|
|
'RED':RED,
|
|
'GREEN':GREEN,
|
|
'YELLOW':YELLOW,
|
|
'BLUE':BLUE,
|
|
'MAGENTA':MAGENTA,
|
|
'CYAN':CYAN,
|
|
'WHITE':WHITE,}
|
|
"""
|
|
COLORS = {
|
|
'INFO': YELLOW,
|
|
'DEBUG': GREEN,
|
|
'ERROR': RED }
|
|
"""
|
|
|
|
class ColoredFormatter(logging.Formatter):
|
|
def __init__(self, *args, **kwargs):
|
|
logging.Formatter.__init__(self, *args, **kwargs)
|
|
|
|
def format(self, record):
|
|
levelname = record.levelname
|
|
color = COLOR_SEQ % (30 + COLORS[levelname])
|
|
message = logging.Formatter.format(self, record)
|
|
#print "1--" + repr(message)
|
|
message = message.replace("$RESET", RESET_SEQ)\
|
|
.replace("$BOLD", BOLD_SEQ)\
|
|
.replace("$COLOR", color)
|
|
#print "2--" + repr(message)
|
|
#for k,v in COLORS.items():
|
|
# message = message.replace("$" + k, COLOR_SEQ % (v+30))\
|
|
# .replace("$BG" + k, COLOR_SEQ % (v+40))\
|
|
# .replace("$BG-" + k, COLOR_SEQ % (v+40))
|
|
#print "3--" + repr(message)
|
|
return message + RESET_SEQ
|
|
|
|
|
|
|
|
#This class copy form liup's blog http://hi.baidu.com/dalier/blog/item/68419d64b98604faf63654e4.html
|
|
#by rrt on 2010-12-3
|
|
|
|
class DateRotatingFileHandler(RotatingFileHandler):
|
|
def __init__(self , filename , mode='a' , maxBytes=0, backupCount=0, encoding=None):
|
|
self.current = time.strftime("%Y%m%d" , time.localtime(time.time()))
|
|
self.path = os.path.dirname(filename)
|
|
self.filename = os.path.basename(filename)
|
|
newdir = os.path.join(self.path , self.current)
|
|
softlink = os.path.join(self.path, 'current')
|
|
if not os.access(newdir , os.X_OK):
|
|
os.mkdir(newdir)
|
|
try:
|
|
os.symlink(newdir ,softlink)
|
|
except:
|
|
os.system("rm -f " + softlink)
|
|
os.symlink(newdir ,softlink)
|
|
newfile = os.path.join(newdir , self.filename)
|
|
RotatingFileHandler.__init__(self, newfile , mode, maxBytes , backupCount , encoding)
|
|
|
|
def doRollover(self):
|
|
#print "doRollover , current=%s , filename=%s"%(self.current , self.baseFilename)
|
|
self.stream.close()
|
|
self.current = time.strftime("%Y%m%d" , time.localtime(time.time()))
|
|
|
|
#Modified by rrt on 2010-12-4 for a log path bug: /'20101204'
|
|
#repr() is not needed , time.strftime() return a string not a integer
|
|
#newdir = os.path.join(self.path , repr(self.current))
|
|
newdir = os.path.join(self.path , self.current)
|
|
if not os.access(newdir , os.X_OK):
|
|
os.mkdir(newdir)
|
|
self.baseFilename = os.path.join(newdir , self.filename)
|
|
|
|
if self.encoding:
|
|
self.stream = codecs.open(self.baseFilename, 'w', self.encoding)
|
|
else:
|
|
self.stream = open(self.baseFilename, 'w')
|
|
|
|
def shouldRollover(self, record):
|
|
if RotatingFileHandler.shouldRollover(self , record):
|
|
RotatingFileHandler.doRollover(self)
|
|
|
|
t = time.strftime("%Y%m%d" , time.localtime(time.time()))
|
|
if (cmp(self.current , t) < 0) :
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
def init_log(prefix, cfg_file, type,level):
|
|
global log_msg_root, log_file_format, log_stderr_format
|
|
|
|
cf = ConfigParser.ConfigParser()
|
|
cf.read(cfg_file)
|
|
config = {}
|
|
|
|
# we can use
|
|
# = cf.get(prefix, 'level').split('#')[0].strip()
|
|
# to enable "#" to comment behind a value string.
|
|
|
|
try:
|
|
config['level'] = cf.get(prefix, 'level')
|
|
except:
|
|
config['level'] = cf.get(log_msg_root, 'level')
|
|
|
|
try:
|
|
config['file'] = cf.get(prefix, 'file')
|
|
except:
|
|
path = cf.get(log_msg_root, 'file')
|
|
path = os.path.dirname(path)
|
|
config['file'] = os.path.join(path, prefix+'.log')
|
|
|
|
try:
|
|
config['stderr'] = cf.getint(prefix, 'stderr')
|
|
except:
|
|
config['stderr'] = cf.getint(log_msg_root, 'stderr')
|
|
|
|
try:
|
|
config['syslog'] = cf.getint(prefix, 'syslog')
|
|
except:
|
|
config['syslog'] = cf.getint(log_msg_root, 'syslog')
|
|
|
|
try:
|
|
config['file_size'] = cf.getint(prefix, 'file_size')
|
|
except:
|
|
config['file_size'] = cf.getint(log_msg_root, 'file_size')
|
|
|
|
try:
|
|
config['file_cnt'] = cf.getint(prefix, 'file_counter')
|
|
except:
|
|
config['file_cnt'] = cf.getint(log_msg_root, 'file_counter')
|
|
|
|
print config
|
|
|
|
#new a root logger
|
|
logger = logging.getLogger(prefix)
|
|
#set root logger level
|
|
if config['level'] == 'debug':
|
|
logger.setLevel(logging.DEBUG)
|
|
elif config['level'] == 'info':
|
|
logger.setLevel(logging.INFO)
|
|
else:
|
|
logger.setLevel(logging.ERROR)
|
|
#new a log file handle
|
|
log_handler = DateRotatingFileHandler(config['file'], mode="a", maxBytes = config['file_size']*1024*1024, backupCount=config['file_cnt'])
|
|
#set log file handle format
|
|
formatter = logging.Formatter(log_file_format, datefmt='%Y-%m-%d %H:%M:%S')# '%F %T') jython not work
|
|
log_handler.setFormatter(formatter)
|
|
#add to root logger
|
|
logger.addHandler(log_handler)
|
|
#new a stderr logger if need
|
|
if not config['stderr']:
|
|
return logger
|
|
else:
|
|
|
|
formatter = ColoredFormatter(log_stderr_format)
|
|
#formatter = logging.Formatter(log_stderr_format)
|
|
log_handler = logging.StreamHandler()
|
|
log_handler.setFormatter(formatter)
|
|
logger.addHandler(log_handler)
|
|
return logger
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
global logger
|
|
|
|
logger = init_log('test_log_lib', 'msg_log.ini', 0, 0)
|
|
logger.debug('debug rrrrrrrrrrrrrrrrrrrrrrrrrrrt')
|
|
logger.info('info rrrrrrrrrrrrrrrrrrrrrrrrrrrt')
|
|
logger.error('error rrrrrrrrrrrrrrrrrrrrrrrrrrrt')
|
|
|