← 中文资源

简体中文版本

Python 标准库日志轮转配置

用 dictConfig 配置标准库日志:按体积轮转保留备份、错误流单独成文件、控制台只出警告以上,多 handler 分级分发。

阅读英文原文

示例说明

dictConfig 把日志拓扑声明成数据:三个 handler 各自绑定文件、级别阈值与轮转策略——主日志十兆五个备份、错误日志更小更久、控制台只要警告以上。root 配置 DEBUG 级意味着任何未单独配置的模块日志都会被收编;per-module 的 getLogger 让每个模块有自己的名字空间,日志行里的 name 字段就是检索键。

技术要点

  • RotatingFileHandler 按体积轮转并保留备份
  • 错误流独立文件便于分级检索
  • dictConfig 以数据描述日志拓扑

代码解读

配置里 formatter 统一时间与字段顺序;extra 参数给单条日志附加业务字段,exc_info 直接携带异常堆栈进错误日志。logger.debug 那行演示级别路由——模块 logger 未配置级别时继承 root 的 DEBUG,但三个 handler 各自的级别阈值决定最终去向。

使用建议

多进程写同一日志文件会轮转冲突,进程模型下改用 QueueHandler 或按进程分文件。日志聚合最终应进集中平台,文件轮转是单机兜底。编码统一 UTF-8 防中文乱码。

代码示例

import logging
import logging.config

CONFIG = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': '%(asctime)s %(levelname)s %(name)s %(message)s',
            'datefmt': '%Y-%m-%dT%H:%M:%S',
        },
    },
    'handlers': {
        'app_file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'logs/app.log',
            'maxBytes': 10 * 1024 * 1024,
            'backupCount': 5,
            'encoding': 'utf-8',
            'formatter': 'standard',
            'level': 'INFO',
        },
        'errors_file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'logs/errors.log',
            'maxBytes': 5 * 1024 * 1024,
            'backupCount': 3,
            'formatter': 'standard',
            'level': 'ERROR',
        },
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'standard',
            'level': 'WARNING',
        },
    },
    'root': {
        'level': 'DEBUG',
        'handlers': ['app_file', 'errors_file', 'console'],
    },
}

logging.config.dictConfig(CONFIG)
logger = logging.getLogger('billing')

logger.info('invoice generated', extra={'invoice_id': 'inv-88'})
logger.warning('payment retry scheduled')
logger.error('gateway rejected settlement', exc_info=RuntimeError('timeout'))
logger.debug('this line only reaches root handlers')