Python-logging 模块

本文围绕 Python 的 logging 模块展开,介绍了日志级别,阐述了 logging.basicConfig 用法,讲解了 logging 模块的四种对象及其相关方法和子类。还介绍了日志轮换(按文件大小和时间间隔)、日志回溯、日志继承,以及通过配置字典定义日志的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、日志级别

等级 数值 描述
CRITICAL 50 严重错误,程序不能正常运行。
FATAL 50 同 CRITICAL。
ERROR 40 错误,程序的某些功能不能正常运行。
WARNING 30 警告,表明已经或即将发生的意外(例如:磁盘空间不足),但程序仍按照预期运行。
WARN 30 同 WARNING。
INFO 20 关键信息,程序按照预期运行。
DEBUG 10 详细信息,在我们调试程序时使用。
NOTSET 0 不设置。

默认的级别的WARNING,意味着只会追踪该级别及以上的事件,除非更改日志配置。

二、logging.basicConfig(**kwargs)

参数 描述
filename 指定输出日志的文件名,如果指定了这个参数,实际上会启用FileHandler,而不再是StreamHandler,这样日志就输出到文件,而不输出到控制台了。
filemode 指定文件打开模式,默认模式为“a”。
format 指定日志信息的输出格式,参数说明如下:
%(name)s:Logger的名称,默认为“root”。
%(levelno)s:数字类型的日志级别。
%(levelname)s:文本类型的日志级别。
%(pathname)s:调用日志输出函数的模块的完整路径。
%(filename)s:调用日志输出函数的模块的文件名。
%(module)s:调用日志输出函数的模块名。
%(lineno)d:调用日志输出函数的语句所在的代码行。
%(funcName)s:调用日志输出函数的函数名。
%(created)f:当前时间,用 UNIX 标准的表示时间的浮点数表示。
%(asctime)s:字符串形式的当前时间,默认格式是“2023-08-28 14:02:26,719”,逗号后面的是毫秒。
%(msecs)d:%(asctime)s 的毫秒部分。
%(relativeCreated)d:自 Logger 创建以来的毫秒数。
%(thread)d:线程 ID。
%(threadName)s:线程名称。
%(process)d:进程 ID。
%(processName)s:进程名称。
%(message)s:日志信息。
detefmt 指定日期/时间的输出格式,与 time.strftime()所接受的格式相同。
style Python 3.2 版本新增参数。指定 format 格式字符串的风格。“%”,“{”或“$”分别对应于 printf-stylestr.format()string.Template。默认为“%”。
level 指定日志级别。
stream 指定数据流初始化StreamHandler,例如:sys.stderrsys.stdout或任何file-like对象,默认为sys.stderr。注意此参数与 filename 不兼容,如果两者同时存在,则会引发ValueError
handlers Python 3.3 版本新增参数。指定日志处理时所使用的 Handler,必须是可迭代的对象。注意此参数与 filename 或 stream 不兼容,如果两者同时存在,则会引发ValueError
force Python 3.8 版本新增参数。指定是否删除其它 Handler。
encoding Python 3.9 版本新增参数。指定日志输出文件的编码格式。
errors Python 3.9 版本新增参数。指定编码格式错误的处理方式,默认为“backslashreplace”。

示例:

import logging
import sys


def basic_config():
    # 日志信息的输出格式
    fmt = '%(name)s-%(levelno)s-%(levelname)s-%(pathname)s-%(filename)s-%(module)s-%(lineno)d-%(funcName)s-%(created)f-%(asctime)s-%(msecs)d-%(relativeCreated)d-%(thread)d-%(threadName)s-%(process)d-%(processName)s-%(message)s'
    # 将日志输出到控制台 StreamHandler
    stream_handler = logging.StreamHandler(sys.stdout)
    # 将日志输出到文件 FileHandler
    file_handler = logging.FileHandler('all.log', mode='w', encoding='utf-8')
    # 日志配置
    logging.basicConfig(format=fmt, datefmt='%Y/%m/%d %H:%M:%S', level='INFO', handlers=[stream_handler, file_handler])
    # force 默认为 False,配置信息以上一条为准,force=True 时,配置信息以下面这条为准
    logging.basicConfig(format=fmt, datefmt='%Y/%m/%d %H:%M:%S', level='ERROR', handlers=[stream_handler, file_handler], force=True)
    # 日志信息
    logging.critical('严重错误...')
    logging.error('错误...')
    logging.warning('警告...')
    logging.info('关键信息...')
    logging.debug('详细信息...')


if __name__ == '__main__':
    basic_config()

运行结果:

D:\Python39\python.exe D:/JetBrains/PycharmProjects/python-logging/basicConfig_demo.py
root-50-CRITICAL-D:\JetBrains\PycharmProjects\python-logging\basicConfig_demo.py-basicConfig_demo.py-basicConfig_demo-19-basic_config-1693216745.661029-2023/08/28 17:59:05-661-217-3152-MainThread-18872-MainProcess-严重错误...
root-40-ERROR-D:\JetBrains\PycharmProjects\python-logging\basicConfig_demo.py-basicConfig_demo.py-basicConfig_demo-20-basic_config-1693216745.661029-2023/08/28 17:59:05-661-217-3152-MainThread-18872-MainProcess-错误...

Process finished with exit code 0

三、logging 模块的四种对象

对象 描述
Logger 日志生成器,产生日志的对象。1 个 Logger 对象可以绑定多个 Handler,用以输出至不同位置。
Filter 日志过滤器,过滤日志的对象。
Handler 日志处理器,处理日志的对象。对日志进行格式化,并输出到指定位置。
Formatter 处理日志的格式。

一条日志完整的生命周期:
1.由 Logger 产生日志 -> 2.交给过滤器判断是否被过滤 -> 3.将日志消息分发给绑定的所有处理器 -> 4.处理器按照绑定的格式化对象输出日志

3.1 Logger 对象相关方法

方法 描述
Logger.setLevel() 指定日志级别。
Logger.addFilter() 为 Logger 对象添加一个 Filter 对象。
Logger.removeFilter() 为 Logger 对象移除一个 Filter 对象。
Logger.addHandler() 为 Logger 对象添加一个 Handler 对象。
Logger.removeHandler() 为 Logger 对象移除一个 Handler 对象。
Logger.critical() 创建一条 CRITICAL 级别的日志。
Logger.error() 创建一条 ERROR 级别的日志。
Logger.warning() 创建一条 WARNING 级别的日志。
Logger.info() 创建一条 INFO 级别的日志。
Logger.debug() 创建一条 DEBUG 级别的日志。
Logger.exception() 创建一条类似 ERROR 级别的日志。
Logger.log() 创建一条指定级别的日志。

3.2 Handler 对象相关方法

方法 描述
Handler.setLevel() 指定日志级别。
Handler.setFormatter() 为 Handler 对象设置一个 Formatter 对象。
Handler.addFilter() 为 Handler 对象添加一个 Filter 对象。
Handler.removeFilter() 为 Handler 对象移除一个 Filter 对象。

3.3 Handler 对象相关子类

子类 描述
logging.StreamHandler 将日志输出到数据流,例如:sys.stderrsys.stdout或任何file-like对象,默认为sys.stderr
logging.FileHandler 将日志输出到文件。
logging.NullHandler 不执行任何格式化或输出,它实际上是一个供库开发者使用的“无操作”处理程序。
logging.handlers.RotatingFileHandler 日志按指定的文件大小轮换。
logging.handlers.TimedRotatingFileHandler 日志按指定的时间间隔轮换。
logging.handlers.SocketHandler 将日志输出到网络套接字。基类所使用的是 TCP 套接字。
logging.handlers.DatagramHandler 它继承自SocketHandler,将日志输出到网络套接字。基类所使用的是 UDP 套接字。
logging.handlers.SMTPHandler 将日志发送到邮箱。
logging.handlers.SysLogHandler 将日志发送到远程或本地 Unix syslog。
logging.handlers.MemoryHandler 在内存中缓冲日志,并定期将其刷新到 target 处理程序中。刷新会在缓冲区满的时候,或是在遇到特定或更高严重程度事件的时候发生。
logging.handlers.HTTPHandler 使用GETPOST将日志发送到 Web 服务器。

示例:

import logging
import sys


# 自定义过滤器并设置过滤条件
class CustomFilter(logging.Filter):
    # 忽略包含 test 的日志
    def filter(self, record) -> bool:
        # print(record.getMessage())
        return 'test' not in record.getMessage()


def stream_and_file_handler():
    # 创建日志生成器 Logger
    logger = logging.getLogger('logger')
    # 设置 Logger 对象日志级别
    logger.setLevel(level='DEBUG')
    # 创建日志处理器 StreamHandler 将日志输出到控制台
    stream_handler = logging.StreamHandler(sys.stdout)
    # 创建日志处理器 FileHandler 将日志输出到文件
    file_handler = logging.FileHandler('all.log', mode='w', encoding='utf-8')
    # 设置 Handler 对象日志级别。Handler 对象日志级别应高于 Logger 对象日志级别,否则,设置 Handler 对象日志级别是没有意义的。
    stream_handler.setLevel(level='INFO')
    file_handler.setLevel(level='INFO')
    # 实例化过滤器 Filter
    custom_filter = CustomFilter()
    # 将过滤器添加到处理器
    stream_handler.addFilter(custom_filter)
    file_handler.addFilter(custom_filter)
    # 创建日志格式器 Formatter
    stream_fmt = logging.Formatter(fmt='%(asctime)s-%(levelname)s-%(pathname)s-%(funcName)s-%(lineno)d-%(message)s')
    file_fmt = logging.Formatter(fmt='%(asctime)s-%(name)s-%(levelname)s-%(pathname)s-%(funcName)s-%(lineno)d-%(process)d-%(processName)s-%(thread)d-%(threadName)s-%(message)s')
    # 设置处理器的日志格式
    stream_handler.setFormatter(stream_fmt)
    file_handler.setFormatter(file_fmt)
    # 将处理器添加到 Logger 对象
    logger.addHandler(stream_handler)
    logger.addHandler(file_handler)
    # 输出日志
    logger.critical('严重错误...')
    logger.error('错误...')
    logger.warning('警告...')
    logger.info('关键信息...')
    logger.debug('详细信息...')
    logger.info('test message...')
    logger.info('This is a test message...')


if __name__ == '__main__':
    stream_and_file_handler()

运行结果:

D:\Python39\python.exe D:/JetBrains/PycharmProjects/python-logging/logging_demo.py
2023-08-29 18:27:58,921-CRITICAL-D:\JetBrains\PycharmProjects\python-logging\logging_demo.py-stream_and_file_handler-40-严重错误...
2023-08-29 18:27:58,921-ERROR-D:\JetBrains\PycharmProjects\python-logging\logging_demo.py-stream_and_file_handler-41-错误...
2023-08-29 18:27:58,921-WARNING-D:\JetBrains\PycharmProjects\python-logging\logging_demo.py-stream_and_file_handler-42-警告...
2023-08-29 18:27:58,921-INFO-D:\JetBrains\PycharmProjects\python-logging\logging_demo.py-stream_and_file_handler-43-关键信息...

Process finished with exit code 0

四、日志轮换

4.1 日志按指定的文件大小轮换

logging.handlers.RotatingFileHandler(filename, mode=‘a’, maxBytes=0, backupCount=0, encoding=None, delay=False, errors=None)

参数 描述
filename 指定输出日志的文件名。Python 3.6 以及之后版本除了字符串值,也接受 Path 对象作为 filename 参数。
mode 指定文件打开模式,默认模式为“a”。
maxBytes 指定文件大小,单位为字节。当即将超出指定大小时,将关闭旧文件并打开一个新文件用于输出。
backupCount 指定备份文件数量,多了就会把最旧的那个文件删除。注意如果 maxBytes 或 backupCount 两者之一的值为零,就不会发生轮换。
encoding 指定日志输出文件的编码格式。
delay 如果 delay 为 True,则文件打开会被推迟至第一次调用emit()的时候。默认情况下,文件会无限增长。
errors Python 3.9 版本新增参数。指定编码格式错误的处理方式。

4.2 日志按指定的时间间隔轮换

logging.handlers.TimedRotatingFileHandler(filename, when=‘h’, interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None, errors=None)

参数 描述
filename 指定输出日志的文件名。Python 3.6 以及之后版本除了字符串值,也接受 Path 对象作为 filename 参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值