欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自定义配置python logger模块实现日志输出到文件和控制台

程序员文章站 2022-07-15 15:54:19
...

示例代码:

import logging
import os.path
import time
# 首先重建一个logger对象
logger = logging.getLogger("test")
# 设置logger的等级
# 等级的设定既可以直接设置大写的英文,也可以设置为logging模块的内置属性,python会自动进行转换判断
# logger.setLevel("DEBUG")
logger.setLevel(logging.DEBUG)
# 组织一个带时间戳的字符串作为日志文件的名字,实现每天记录一个日志文件
date_time = time.strftime("%Y%m%d",time.localtime(time.time()))
log_path = os.path.dirname(os.getcwd()+'/logs')
log_name = log_path + date_time + '.log'
# 创建一个logging输出到文件的handler并设置等级和输出格式
# mode属性用于控制写文件的模式,w模式每次程序运行都会覆盖之前的logger,而默认的是a则每次在文件末尾追加
fh = logging.FileHandler(log_name,'a')
fh.setLevel(logging.DEBUG)

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

# 如果需要同时输出到控制台
ch = logging.StreamHandler()
ch.setFormatter(formatter)
ch.setLevel("ERROR")
logger.addHandler(ch)
# 完成配置,测试
logger.error("hello logging!")
logger.error("hello koala!")

创建一个logger工具

以上代码经过简单的封装可实现一个简单的logger工具,方便程序其他地方使用

import logging
import os.path
import time


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

    def __init__(self, name):
        self.logger = logging.getLogger(name)
        # 设置logger的等级
        # 等级的设定既可以直接设置大写的英文,也可以设置为logging模块的内置属性,python会自动进行转换判断
        # logger.setLevel("DEBUG")
        super().__init__(name)
        self.logger.setLevel(logging.DEBUG)
        # 组织一个带时间戳的字符串作为日志文件的名字,实现每天记录一个日志文件
        date_time = time.strftime("%Y%m%d", time.localtime(time.time()))
        log_path_str = 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, 'a')
        fh.setLevel(logging.DEBUG)

        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("INFO")
        self.logger.addHandler(ch)

    def getLogger(self):
        return self.logger

则后续代码需要使用logger,就通过下方方式获取上述配置好的logger即可

logger = MyLogger.getLogger(MyLogger("checkService"))

或者更简单的方式:

logger = MyLogger("checkService").logger

附: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的初始化方法