Skip to content

Instantly share code, notes, and snippets.

@Andrew-liu
Last active October 21, 2017 08:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Andrew-liu/d2eefc85960fb43edc1ac25b5dcb1b4f to your computer and use it in GitHub Desktop.
Save Andrew-liu/d2eefc85960fb43edc1ac25b5dcb1b4f to your computer and use it in GitHub Desktop.
A log tool for python with time rotating
# -*- coding: utf-8 -*-
#!/usr/bin/env python
# @Author: asyncliu
# @Date: 2017-08-12 10:32:58
# @Last Modified by: asyncliu
# @Last Modified time: 2017-10-20 17:40:41
# @Project: 日志工具类
import logging, sys
import logging.handlers
# constant variable
DEFAULT_LEAVE = logging.DEBUG
DEFAULT_EMAIL = "1095511964@qq.com"
DEFAULT_FORMATTER = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
DEFAULT_ROTATING_FMT = "%Y%m%d"
# wrapper logging
class Logger(object):
def __init__(self,
logger=None,
name=__name__,
level=DEFAULT_LEAVE,
fmt=DEFAULT_FORMATTER
):
"""init a Logger class
Args :
logger: transfer a logger
name: set a logger formatter's name
level: set logging level, default is DEBUG
fmt: set formatter's format
"""
if logger is None:
self.logger = logging.getLogger(name)
self.formatter = logging.Formatter(fmt)
self.logger.setLevel(level)
def enable_file_handler(self,
log_file,
level=DEFAULT_LEAVE,
file_encoding="utf-8",
when_type='D', # 按天分割日志
):
# log rotating by time
file_handler = logging.handlers.TimedRotatingFileHandler(log_file, when=when_type, interval=1,
encoding=file_encoding)
file_handler.suffix = DEFAULT_ROTATING_FMT
# file_handler = logging.FileHandler(log_file, mode='a', encoding=file_encoding)
file_handler.setLevel(level)
file_handler.setFormatter(self.formatter)
self.logger.addHandler(file_handler)
def enable_stream_handler(self,
level=DEFAULT_LEAVE):
stream_handler = logging.StreamHandler()
stream_handler.setLevel(level)
stream_handler.setFormatter(self.formatter)
self.logger.addHandler(stream_handler)
def debug(self, msg, *args):
if msg:
self.logger.debug(msg, *args)
def info(self, msg, *args):
if msg:
self.logger.info(msg, *args)
def warning(self, msg, *args):
if msg:
self.logger.warning(msg, *args)
def error(self, msg, *args):
if msg:
self.logger.error(msg, *args)
def critical(self, msg, *args):
if msg:
self.logger.critical(msg, *args)
def exception(self, msg, *args):
if msg:
self.logger.exception(msg, *args)
class SingletonDecorator(object):
def __init__(self, cls):
self._cls = cls
self._inst = None
def __call__(self, *args, **kwargs):
"""Over __call__ method. So the instance of this class
can be called as a function.
"""
if not self._inst:
self._inst = self._cls(*args, **kwargs)
return self._inst
my_logger = SingletonDecorator(Logger)
logger_instance = None
logger_root = None
def setLogger():
global logger_root
logger_root = logging.getLogger()
console = logging.StreamHandler()
formatter = logging.Formatter(DEFAULT_FORMATTER)
console.setFormatter(formatter)
logger_root.addHandler(console)
logger_root.setLevel(DEFAULT_LEAVE)
return logger_root
def getLogger(name=None, formatter=DEFAULT_FORMATTER, level=DEFAULT_LEAVE):
global logger_instance
global logger_root
if logger_instance is not None:
return logger_instance
else:
if name is None:
if logger_root is None:
return setLogger()
else:
return logger_root
else:
logger_instance = Logger(name=name, fmt=formatter, level=level)
return logger_instance
if __name__ == '__main__':
mylogger = getLogger(name='test')
mylogger.enable_stream_handler(logging.DEBUG)
mylogger.enable_file_handler("test.log", level=logging.ERROR)
for i in xrange(0, 1):
mylogger = getLogger(name='test')
mylogger.debug('debug log: %d' % i)
mylogger.info('debug log: %d' % i)
mylogger.warning('debug log: %d' % i)
# mylogger.exception('debug log: %d' % i)
mylogger.error('debug log: %d' % i)
mylogger.critical('debug log: %d' % i)
print "ok"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment