# -*- coding:utf-8 -*-
import logging
import sys
from logging.handlers import RotatingFileHandler
import os
class InfoFilter(logging.Filter):
def __init__(self, level):
logging.Filter.__init__(self)
self.level = level
def filter(self, record):
return record.levelno == self.level
class Logger(object):
@staticmethod
def get_logger(name, module_name, save_dir="./log/",
max_bytes=20 * 1024 * 1024,
backup_count=20):
if not os.path.exists(save_dir):
os.system("mkdir -p %s" % save_dir)
logger = logging.getLogger(module_name)
if not logger.handlers:
logger.setLevel(level=logging.DEBUG)
# 处理文件输出,输出所有级别
log_file = "%s/%s.log" % (save_dir, name)
formatter = logging.Formatter(
"[%(asctime)s] [%(levelname)s] [%(filename)s %(funcName)s:%(lineno)s]"
" %(message)s")
file_handler = RotatingFileHandler(
log_file, maxBytes=max_bytes, backupCount=backup_count)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
# 标准输出(屏幕)
stdout_formatter = logging.Formatter(
" 33[1;32;40m[%(asctime)s] [%(levelname)s] "
"[%(filename)s %(funcName)s:%(lineno)s] %(message)s 33[0m")
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setLevel(logging.INFO)
stdout_handler.setFormatter(stdout_formatter)
stdout_handler.addFilter(InfoFilter(logging.INFO))
logger.addHandler(stdout_handler)
# 错误输出(屏幕)
stderr_formatter = logging.Formatter(
" 33[1;31;40m[%(asctime)s] [%(levelname)s] "
"[%(filename)s %(funcName)s:%(lineno)s] %(message)s 33[0m")
stderr_handler = logging.StreamHandler(sys.stderr)
stderr_handler.setLevel(logging.WARNING)
stderr_handler.setFormatter(stderr_formatter)
logger.addHandler(stderr_handler)
# propagate 属性为 True(默认值),则它的记录也会传到父 logger。
# 因此,logger 在记录到文件的同时,也会在 stdout 输出日志。
logger.propagate = False
return logger
if __name__ == "__main__":
LOG = Logger().get_logger("log_file_name", __name__)
LOG.info("....... info")
LOG.error("...... error")
LOG.warning(".... warning")
LOG.debug("...... debug")
LOG.critical(".... critical")
LOG.exception("... exception")