pin_drop当前位置:知识文库 ❯ 图文

TimedRotatingFileHandler详解 - Python按时间轮转日志配置

一、TimedRotatingFileHandler 概述

TimedRotatingFileHandler 是 Python logging 模块中按时间间隔自动轮转的日志处理器。与 RotatingFileHandler 按文件大小轮转不同,TimedRotatingFileHandler 按照指定的时间间隔(秒、分钟、小时、天、周等)创建新的日志文件,旧文件以时间戳命名归档。

这种轮转方式适合需要按时间维度管理日志的场景,如每天一个日志文件、每小时一个日志文件等。在运维和审计中,按时间归档的日志更容易定位特定日期或时间段的问题。

二、语法与参数说明

代码示例

import logging
from logging.handlers import TimedRotatingFileHandler

handler = TimedRotatingFileHandler(
    filename='app.log',
    when='midnight',
    interval=1,
    backupCount=30,
    encoding='utf-8',
    utc=False
)

参数详解

参数 类型 默认值 说明
filename str 必填 日志文件路径
when str 'h' 轮转间隔类型
interval int 1 轮转间隔数值
backupCount int 0 保留备份数量
encoding str None 文件编码
utc bool False 是否使用UTC时间
atTime datetime.time None 指定轮转时间(仅'D'和'W'有效)

when 参数值说明

说明 备份文件后缀
'S' %Y-%m-%d_%H-%M-%S
'M' 分钟 %Y-%m-%d_%H-%M
'H' 小时 %Y-%m-%d_%H
'D' %Y-%m-%d
'midnight' 每天午夜 %Y-%m-%d
'W0'-'W6' 每周指定日(0=周一) %Y-%m-%d

三、代码示例

示例1:按小时轮转

按小时轮转适合开发调试场景,可以快速定位到特定小时段的日志,便于排查问题。

代码示例

import logging
from logging.handlers import TimedRotatingFileHandler

logger = logging.getLogger("hourly")
logger.setLevel(logging.INFO)

# 每小时轮转一次,保留24个备份
handler = TimedRotatingFileHandler(
    'hourly.log',
    when='H',
    interval=1,
    backupCount=24,
    encoding='utf-8'
)
handler.setFormatter(logging.Formatter(
    '%(asctime)s [%(levelname)s] %(message)s'
))
logger.addHandler(handler)

logger.info("按小时轮转的日志系统")
logger.warning("每小时创建一个新文件")
print(f"轮转时间: {handler.when}")
print(f"轮转间隔: {handler.interval}")

输出:

代码示例

轮转时间: H
轮转间隔: 1
按小时轮转的日志系统
每小时创建一个新文件

示例2:每天午夜轮转

每天午夜轮转是生产环境最常见的配置,保留30天的日志,便于按日期查找历史日志。

代码示例

import logging
from logging.handlers import TimedRotatingFileHandler
import time

logger = logging.getLogger("daily")
logger.setLevel(logging.INFO)

# 每天午夜轮转,保留30天
handler = TimedRotatingFileHandler(
    'daily.log',
    when='midnight',
    interval=1,
    backupCount=30,
    encoding='utf-8'
)
handler.setFormatter(logging.Formatter(
    '%(asctime)s [%(levelname)s] %(name)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
))
logger.addHandler(handler)

logger.info("每天午夜轮转的日志")
logger.error("错误示例")

# 查看下次轮转时间
print(f"当前时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"备份文件后缀格式: %Y-%m-%d")

输出:

代码示例

当前时间: 2026-04-11 10:30:00
备份文件后缀格式: %Y-%m-%d
[INFO] 每天午夜轮转的日志
[ERROR] daily - 错误示例

示例3:按周轮转

按周轮转适合低频应用或周报场景,每周一创建新的日志文件,便于按周汇总。

代码示例

import logging
from logging.handlers import TimedRotatingFileHandler

logger = logging.getLogger("weekly")
logger.setLevel(logging.DEBUG)

# 每周一轮转,保留8周
handler = TimedRotatingFileHandler(
    'weekly.log',
    when='W0',  # W0=周一
    interval=1,
    backupCount=8,
    encoding='utf-8'
)
handler.setFormatter(logging.Formatter(
    '%(asctime)s [%(levelname)s] %(message)s',
    datefmt='%Y-%m-%d %H:%M'
))
logger.addHandler(handler)

logger.info("每周一轮转的日志")
logger.debug("调试信息")

# when参数说明
when_types = {
    'S': '秒', 'M': '分钟', 'H': '小时',
    'D': '天', 'midnight': '午夜',
    'W0': '周一', 'W6': '周日'
}
print("when 参数说明:")
for k, v in when_types.items():
    print(f"  {k}: {v}")

输出:

代码示例

when 参数说明:
  S: 秒
  M: 分钟
  H: 小时
  D: 天
  midnight: 午夜
  W0: 周一
  W6: 周日
[INFO] 每周一轮转的日志
[DEBUG] 调试信息

四、实际应用场景

  • 每日日志归档:生产环境最常见的配置是每天午夜轮转,保留 30 天的日志,便于按日期查找历史日志。

  • 审计日志:审计日志需要按时间维度管理,使用 TimedRotatingFileHandler 可以自动按天或按周归档审计记录。

  • 开发调试:开发环境可以按小时轮转,快速定位特定时间段的日志。

五、注意事项

注意1:轮转检查只在日志写入时触发。如果长时间没有日志输出,轮转可能不会按时执行。

注意2backupCount 为 0 时不会删除旧备份文件,磁盘空间可能持续增长。建议设置合理的备份数量。

注意3:与 RotatingFileHandler 相同,多进程写入同一日志文件可能存在竞争条件。

提示:生产环境推荐 when='midnight'backupCount=30,实现每天一个日志文件,保留 30 天。

六、与 RotatingFileHandler 对比

对比项 RotatingFileHandler TimedRotatingFileHandler FileHandler
轮转依据 文件大小 时间间隔
备份命名 .log.1, .log.2 .log.2026-04-11
磁盘控制 精确 近似 不可控
日志查找 按大小 按时间 需搜索
适用场景 高频日志 按时间归档 短期运行

小贴士

在 Windows 系统中,备份文件名称中的冒号(:)会被替换为连字符(-),因此备份文件的命名格式为 app.log.2026-04-11 而非 app.log.2026-04-11 00:00:00,这是为了兼容文件系统的命名规则。

七、常见问题

TimedRotatingFileHandler 和 RotatingFileHandler 有什么区别?

TimedRotatingFileHandler 按照时间间隔(如每天、每小时)轮转日志,备份文件以时间戳命名;而 RotatingFileHandler 按照文件大小轮转,备份文件以序号命名。选择哪个取决于你是想按时间归档还是按大小控制磁盘占用。

backupCount 设置为 0 是什么意思?

backupCount=0 时,Handler 不会删除旧的备份文件,日志文件会无限增长。生产环境务必设置一个合理的备份数量(如 30),避免磁盘空间被占满。

多进程环境下可以使用 TimedRotatingFileHandler 吗?

不建议直接使用。多进程同时写入同一个日志文件可能存在竞争条件,导致日志混乱或轮转失败。多进程场景建议使用 concurrent_log_handler 第三方库,或者每个进程写入独立的日志文件。

为什么我的日志没有按时轮转?

轮转检查只在日志写入时触发。如果应用长时间没有日志输出(如深夜低峰期),轮转不会自动执行,直到下一次有日志写入时才会判断是否需要轮转。这不是 Bug,而是设计如此。如果需要精确的定时轮转,可以考虑使用外部定时任务(如 crontab)配合日志切割。

when='midnight' 和 when='D', interval=1 有什么区别?

两者效果类似,都是每天轮转一次。但 when='midnight' 明确表示在午夜(00:00)轮转,而 when='D' 默认从程序启动时间开始计算 24 小时。如果需要指定具体的轮转时间(如每天凌晨 3 点),可以使用 when='D' 配合 atTime=datetime.time(3, 0) 参数。


标签: Python 日志轮转 logging TimedRotatingFileHandler 日志归档 运维工具

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: Python RotatingFileHandler详解 - 日志自动轮转与磁盘管理 下一篇: logging.config详解 - Python日志dictConfig高级配置

poll相关推荐