logging模块实现自定义的日志打印与保存工具

日志打印工具

完整代码:

import logging
import os.path
import time

"自定义logger对象,继承自logging.Logger,实现文件和控制台的输出"
__author__ = "[email protected]"


class MyLogger(logging.Logger):
    # 首先重建一个logger对象
    logger = None
    level = None
    mode = None

    def __init__(self, name="logger", level=logging.DEBUG, console_level=logging.INFO, mode='a'):
        self.logger = logging.getLogger(name)
        # 设置logger的等级
        super().__init__(name)
        # 等级的设定既可以直接设置大写的英文,也可以设置为logging模块的内置属性,python会自动进行转换判断
        # 这里设置的是全局的level,后面可根据输出到文件和控制台设置相应的level
        # 注意这各会设置最低的等级,后续的设置只能比这个高
        self.logger.setLevel(level)
        # 组织一个带时间戳的字符串作为日志文件的名字,实现每天记录一个日志文件
        date_time = time.strftime("%Y%m%d", time.localtime(time.time()))
        log_path_str = os.path.join(os.path.abspath(os.path.join(os.getcwd(), "")), "logs")
        # python 在创建fileHandler时路径不存在会报FileNotFoundError,这里要新建下路径(而具体文件存不存在都时可以的,python会自动创建文件)
        if not os.path.exists(log_path_str):
            os.makedirs(log_path_str)

        log_name = os.path.join(log_path_str, date_time + '.log')
        # 创建一个logging输出到文件的handler并设置等级和输出格式
        # mode属性用于控制写文件的模式,w模式每次程序运行都会覆盖之前的logger,而默认的是a则每次在文件末尾追加
        fh = logging.FileHandler(log_name, mode)
        fh.setLevel(level)

        formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
        fh.setFormatter(formatter)
        # 给logger对象添加handler
        self.logger.addHandler(fh)

        # 如果需要同时输出到控制台
        ch = logging.StreamHandler()
        ch.setFormatter(formatter)
        ch.setLevel(console_level)
        self.logger.addHandler(ch)

    def getLogger(self):
        return self.logger

    def setLevel(self, level):
        self.logger.level = level

调用:

from util.logger import MyLogger
LOGGER  = MyLogger("test").getLogger()
LOGGER.info("hello world!")

附:python日志等级对照

logging.init.py中定义:

CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

等级的高低等同于int数值的大小

有个值得注意的点是,创建logger对象时必须要传入name属性,当不传入name时,默认得到的时一个RootLogger,此时当创建多个logger对象的时候会出现重复打印的i情况,(其实只要时传入的名字时相同的,均会出现这种情况)解决办法时每次创建logger时最好以文件名作为name传给logger的初始化方法

你可能感兴趣的:(python,python)