Python中RotatingFileHandler、TimedRotatingFileHandler函数用法

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️
作者:秋无之地

简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。

欢迎小伙伴们点赞、收藏⭐️、留言

背景

在python开发过程中,经常需要考虑日志的输出,以提高排查问题的效率。其中logging模块作为最常用的日志模块,提供了很多有用的日志处理程序对象,其中比较常用的有:RotatingFileHandler、TimedRotatingFileHandler。

今天就来介绍一下这两个函数的一些用法。

一、RotatingFileHandler 介绍

RotatingFileHandler 是 Python 自带的日志处理器之一,用于将日志写入到指定的文件中,并控制文件大小和数量,可实现日志轮转(即备份旧日志并创建新的日志)。

class logging.handlers.RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=False)

RotatingFileHandler 的各参数解释:

filename:文件名,指定日志文件的路径和名称;
mode:模式,可选值为 ‘a’ 或 ‘w’。当为 ‘a’ 时,表示以追加方式写入日志;当为 ‘w’ 时,表示以覆盖方式写入日志。默认值为 ‘a’;
maxBytes:单个日志文件的最大大小,单位为字节。当日志文件达到该大小时,会自动备份旧日志并创建新的日志文件。默认值为 0,表示不限制日志文件大小。;
backupCount:备份文件数目。当生成的日志文件数量超过该数目时,会自动删除旧的备份日志文件。默认值为 0,表示不备份;
encoding:日志文件的编码格式,默认为 None,表示使用系统默认编码;
delay:是否延时打开文件,可选值为 True 和 False。当为 True 时,表示延时打开文件,即在第一次写入日志时才打开日志文件。当为 False 时,表示在初始化时即打开日志文件。默认值为 False
默认情况下,文件无限增长。您可以指定maxBytes和backupCount的特定值,以允许文件以预定的大小滚动。

需要注意的是,如果指定了为maxBytes指定了>0的值,则mode指定为w是没有意义的,RotatingFileHandler初始化时会自动将mode强制改为a

示例1:

import logging
from logging.handlers import RotatingFileHandler

logger = logging.getLogger('mylogger')
logger.setLevel(logging.INFO)

handler = RotatingFileHandler(filename='tmp.log', maxBytes=4, backupCount=2)

logger.addHandler(handler)

for i in range(5):
    logger.info("OK%d" % i)

输出3个日志文件,文件名及文件内容分别如下:

# tmp.log
OK4

# tmp.log.1
OK3

# tmp.log.2
OK2

解释:

【文件最新内容始终输出在tmp.log基本日志文件中】
tmp.log大小达到设定的maxBytes时,如果再有日志写入,则新生成一个tmp.log,并将原来的tmp.log重命名为tmp.log.1,将原来的tmp.log.1(如果有)重命名为tmp.log.2,将原来的tmp.log.2(如果有)删除(因为只备份2个)

一般情况下,涉及多个日志备份文件的配置可以如下:

# 最多能保存10个大小为10M的日志文件,超过会删除历史旧的文件
log_handler = RotatingFileHandler("./new.log", maxBytes=10485760, backupCount=10)

二、TimedRotatingFileHandler 介绍

TimedRotatingFileHandler 是 Python 自带的日志处理器之一,与 RotatingFileHandler 类似,也用于将日志写入到指定的文件中,并对文件进行切割。不同的是TimedRotatingFileHandler 可以按照时间轮转日志,例如每天或每小时生成一个新的日志文件。

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

TimedRotatingFileHandler 的各参数的详解:

filename:文件名,指定日志文件的路径和名称;
when:日志轮转的时间间隔,可选值为 ‘S’、‘M’、‘H’、‘D’、‘W’ 和 ‘midnight’,分别表示秒、分、时、天、周和每天的午夜;默认值为 ‘midnight’,即每天的午夜轮转,值不区分大小写;
interval:时间间隔的数量,默认为 1;例如,当 when=‘D’ 且 interval=7 时,表示每周轮转一次;
backupCount:备份文件数目;当生成的日志文件数量超过该数目时,会自动删除旧的备份日志文件;默认值为 0,表示不备份;
encoding:日志文件的编码格式,默认为 None,表示使用系统默认编码;
delay:是否延时打开文件,可选值为 True 和 False;当为 True 时,表示延时打开文件,即在第一次写入日志时才打开日志文件;当为 False 时,表示在初始化时即打开日志文件;默认值为 False;
utc:是否使用 UTC 时间,默认为 False,表示使用本地时间
atTime:用来设置轮转时间,格式为 ‘%H:%M:%S’,默认为午夜 12 点;需要注意的是该参数仅在when为W/midnight时有效;
当使用基于星期的轮换时,星期一为 ‘W0’,星期二为 ‘W1’,以此类推直至星期日为 ‘W6’。 在这种情况下,传入的 interval 值不会被使用。

示例1: 日志文件备份规则

import logging
from logging.handlers import TimedRotatingFileHandler
import time

logger = logging.getLogger('mylogger')
logger.setLevel(logging.INFO)

handler = TimedRotatingFileHandler(
    filename="./tmp.log",
    when="S",
    interval=3,
    backupCount=5,
    encoding="utf8"
)

ffmt = logging.Formatter("%(asctime)s - %(message)s")
handler.setFormatter(ffmt)

logger.addHandler(handler)

for i in range(5):
    logger.info("Hello%d" % i)
    logger.info(handler.suffix)
    logger.info(handler.extMatch)
    time.sleep(3)

输出文件内容:

# tmp.log
2023-09-03 22:06:45,635 - Hello4
2023-09-03 22:06:45,635 - %Y-%m-%d_%H-%M-%S
2023-09-03 22:06:45,635 - re.compile('^\\d{4}-\\d{2}-\\d{2}_\\d{2}-\\d{2}-\\d{2}(\\.\\w+)?$', re.ASCII)

解释:

代码中,when='S',interval=3,表示每3s备份一次文件,backupCount=5,表示最多保留5份旧日志数据;
从输出结果来看,每3s备份一次数据,只保留5份旧的数据,符合预期;
另外,按秒切割的日志文件,备份文件是在原日志文件名后添加.%Y-%m-%d_%H-%M-%S的后缀,而删除旧日志文件使用的正则表达式为re.compile('^\\d{4}-\\d{2}-\\d{2}_\\d{2}-\\d{2}-\\d{2}(\\.\\w+)?$', re.ASCII)


示例2: 轮换时间的计算则仅在轮换发生时执行

还是示例1的代码,这里做一个小改动,将最后一行的time.sleep(3)改为`time.sleep(2),将已有日志文件全删除,再次运行代码。

输出文件内容:

# tmp.log
2023-09-03 22:24:16,973 - Hello3
2023-09-03 22:24:16,973 - %Y-%m-%d_%H-%M-%S
2023-09-03 22:24:16,973 - re.compile('^\\d{4}-\\d{2}-\\d{2}_\\d{2}-\\d{2}-\\d{2}(\\.\\w+)?$', re.ASCII)
2023-09-03 22:24:18,984 - Hello4
2023-09-03 22:24:18,984 - %Y-%m-%d_%H-%M-%S
2023-09-03 22:24:18,984 - re.compile('^\\d{4}-\\d{2}-\\d{2}_\\d{2}-\\d{2}-\\d{2}(\\.\\w+)?$', re.ASCII)

解释:

与示例1结果不同的是,备份的日志文件名后添加的后缀时间间隔是4,不是interval=3设置的间隔。这是因为:初始轮换时间的计算是在处理程序被初始化时执行的。 后续轮换时间的计算则仅在轮换发生时执行,而只有当提交输出时轮换才会发生。

例如,如果设置时间间隔为“每分钟”,那并不意味着你总会看到(文件名中)带有间隔一分钟时间的日志文件;如果在应用程序执行期间,日志记录输出的生成频率高于每分钟一次,那么你可以预期看到间隔一分钟时间的日志文件。 但如果日志记录消息每五分钟才输出一次,那么你将看到的是间隔五分钟时间的日志文件。

结尾:

RotatingFileHandler、TimedRotatingFileHandler主要是用来对输出的日志文件进行切割。理解好函数中各参数的含义,就能事半功倍!

创作不易,如果你觉得本文对你有帮助,请给个一键三连吧!万分感谢!

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