Python使用TimedRotatingFileHandler按时间切割日志

陆景行
陆景行
发布时间:2026-10-12| 3人浏览过
原创

本文介绍如何使用Python标准库中的TimedRotatingFileHandler实现按时间自动切割日志文件。通过配置when、backupCount和suffix参数,可以控制日志文件的生成频率、保留数量及命名格式。文章提供了完整的代码示例,展示了如何自定义日志轮转逻辑,并演示了同时输出到控制台和文件的配置方法。

为什么需要日志切割

在Python应用开发中,日志是排查问题和监控系统状态的关键工具。然而,如果不进行日志切割,单一日志文件会随时间推移变得越来越大。这不仅会影响系统的I/O性能,还会导致在查找特定时间点的日志时效率极低。因此,按时间周期(如天、小时、分钟甚至秒)切割日志文件,是保障系统稳定性和可维护性的必要手段。

核心配置参数

TimedRotatingFileHandler 是Python logging 模块中用于实现定时轮转日志的核心类。要正确使用它,需要理解以下几个关键参数:

  • when:定义切割的时间单位。支持的值包括 'S'(秒)、'M'(分钟)、'H'(小时)、'D'(天)、'W0'-'W6'(周一到周日)和 'midnight'(午夜)。默认精度为秒。
  • backupCount:指定保留的旧日志文件数量。当切割产生的文件数量超过此值时,系统会自动删除最旧的日志文件,防止磁盘空间被耗尽。
  • suffix:定义切割后生成的日志文件的命名后缀格式。默认格式为 %Y-%m-%d_%H-%M-%S,通常建议显式指定以包含文件扩展名(如 .log),确保文件能被正确识别。

基础实现示例

以下代码演示了如何创建一个基础的日志切割器。该示例将日志输出到 ./logs/default.log,按秒切割,并保留最近3个日志文件。

import time
import logging
import os
from logging import handlers

def _logging(**kwargs):
    level = kwargs.pop('level', None)
    filename = kwargs.pop('filename', None)
    datefmt = kwargs.pop('datefmt', None)
    format = kwargs.pop('format', None)
    
    # 设置默认值
    if level is None:
        level = logging.DEBUG
    if filename is None:
        filename = 'default.log'
    if datefmt is None:
        datefmt = '%Y-%m-%d %H:%M:%S'
    if format is None:
        format = '%(asctime)s [%(module)s] %(levelname)s [%(lineno)d] %(message)s'
        
    log = logging.getLogger(filename)
    format_str = logging.Formatter(format, datefmt)
    
    # 创建TimedRotatingFileHandler
    # when='S' 表示按秒切割,backupCount=3 表示保留3个备份文件
    th = handlers.TimedRotatingFileHandler(
        filename=filename, 
        when='S', 
        backupCount=3, 
        encoding='utf-8'
    )
    th.setFormatter(format_str)
    th.setLevel(logging.INFO)
    log.addHandler(th)
    log.setLevel(level)
    return log

# 创建日志目录
os.makedirs("./logs", exist_ok=True)
logger = _logging(filename='./logs/default.log')

if __name__ == '__main__':
    while True:
        time.sleep(0.1)
        logger.info('测试日志输出')

进阶配置:自定义命名与控制台输出

默认情况下,TimedRotatingFileHandler 生成的日志文件名可能不符合预期,或者日志文件不会自动放入指定的子目录中。通过自定义 namer 和 suffix,可以精确控制日志文件的命名规则。

自定义日志文件名

可以通过设置 th.namer 属性来自定义日志文件的命名逻辑。例如,以下代码将日志文件名中的 default. 前缀去除,仅保留时间戳部分:

# 自定义namer函数,处理日志文件名
def namer(filename):
    return filename.split('default.')[1]

th.namer = namer
# 设置suffix,指定日志文件的后缀格式
th.suffix = "%Y-%m-%d_%H-%M-%S.log"

同时输出到控制台

为了方便调试,通常需要将日志同时输出到控制台和文件。可以通过添加 StreamHandler 来实现:

# 添加控制台输出
cmd = logging.StreamHandler()
cmd.setFormatter(format_str)
cmd.setLevel(level)
log.addHandler(cmd)

完整实战示例

以下是一个更完整的示例,展示了如何配置按天切割的日志,并区分不同级别的日志输出。该示例将 DEBUG 级别日志输出到 ./debug/ 目录,而 INFO 及以上级别日志输出到根目录。

import logging
import os
from logging import handlers

def _logging(**kwargs):
    level = kwargs.pop('level', None)
    filename = kwargs.pop('filename', None)
    datefmt = kwargs.pop('datefmt', None)
    format = kwargs.pop('format', None)
    
    if level is None:
        level = logging.DEBUG
    if filename is None:
        filename = 'default.log'
    if datefmt is None:
        datefmt = '%Y-%m-%d %H:%M:%S'
    if format is None:
        format = '%(asctime)s [%(module)s] %(levelname)s [%(lineno)d] %(message)s'
        
    log = logging.getLogger(filename)
    format_str = logging.Formatter(format, datefmt)
    
    # 创建DEBUG级别的Handler,按天切割
    os.makedirs("./debug", exist_ok=True)
    th_debug = handlers.TimedRotatingFileHandler(
        filename="./debug/" + filename, 
        when='D', 
        backupCount=3,
        encoding='utf-8'
    )
    th_debug.suffix = "%Y-%m-%d.log"
    th_debug.setFormatter(format_str)
    th_debug.setLevel(logging.DEBUG)
    log.addHandler(th_debug)
    
    # 创建INFO级别的Handler,按天切割
    th = handlers.TimedRotatingFileHandler(
        filename=filename, 
        when='D', 
        backupCount=3, 
        encoding='utf-8'
    )
    th.suffix = "%Y-%m-%d.log"
    th.setFormatter(format_str)
    th.setLevel(logging.INFO)
    log.addHandler(th)
    
    log.setLevel(level)
    return log

os.makedirs('./logs', exist_ok=True)
logger = _logging(filename='./logs/default')

底层删除逻辑说明

TimedRotatingFileHandler 在轮转时会调用 getFilesToDelete 方法来确定需要删除的旧日志文件。该方法会列出当前目录下的所有文件,筛选出符合前缀和正则表达式的文件,并根据 backupCount 的值决定保留哪些文件。理解这一机制有助于更好地管理日志存储。

总结

通过合理配置 TimedRotatingFileHandler 的参数,可以实现高效、自动化的日志管理。这不仅有助于保持系统性能,还能在出现问题时快速定位日志。在实际应用中,建议根据业务需求灵活调整切割频率和保留策略。

以上就是Python通过TimedRotatingFileHandler按时间切割日志的详细内容,更多关于Python日志管理的技术资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。