fragment/常用脚本/python/rising_log.py
2021-08-29 00:02:47 +08:00

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')