Python日志模块中RotatingFileHandler中,如果maxBytes 或 backupCount 两者之一的值为零,就不会发生轮换

RotatingFileHandler是Python的logging.handlers模块的一部分,用于管理磁盘日志文件的轮换。当日志文件大小接近maxBytes设定值时,文件会进行轮换,备份文件通过添加.1,.2等扩展名保存,最多备份backupCount个文件。如果backupCount为0,轮换不会发生。示例代码展示了如何配置RotatingFileHandler限制日志文件大小和数量。

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


RotatingFileHandler 类位于 logging.handlers 模块,它支持磁盘日志文件的轮换。

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

返回一个 RotatingFileHandler 类的新实例。 将打开指定的文件并将其用作日志记录流。 如果未指定 mode,则会使用 ‘a’。 如果 encoding 不为 None,则会将其用作打开文件的编码格式。 如果 delay 为真值,则文件打开会被推迟至第一次调用 emit()。 默认情况下,文件会无限增长。 如果提供了 errors,它会被用于确定编码格式错误的处理方式。

执行 rollover 规则:

你可以使用 maxBytes 和 backupCount 值来允许文件以预定的大小执行 rollover。

当即将超出预定大小时,将关闭旧文件并打开一个新文件用于输出。 只要当前日志文件长度接近 maxBytes 就会发生轮换;

当 backupCount 为非零值时,系统将通过为原文件名添加扩展名 ‘.1’, ‘.2’ 等来保存旧日志文件。 例如,当 backupCount 为 5 而基本文件名为 app.log 时,你将得到 app.log, app.log.1, app.log.2 直至 app.log.5。 当前被写入的文件总是 app.log。 当此文件写满时,它会被关闭并重户名为 app.log.1,而如果文件 app.log.1, app.log.2 等存在,则它们会被分别重命名为 app.log.2, app.log.3 等等。子模块(函数)通过logger定义和主模块使用同一个日志模块

容易疏忽的点:

如果 maxBytes 或 backupCount 两者之一的值为零,就不会发生轮换,因此你通常要设置 backupCount 至少为 1,而 maxBytes 不能为零。

同时:如果maxBytes 不为0,backupCount为0时,maxBytes也无法生效,单个文件的大小

也会无限增长。

源码如下:


example:

# myFun.py

# encoding:utf8
import logging
from logging.handlers import RotatingFileHandler

#
# logging模块
# 设置单个日志文件最大3M (3145728字节,*8=位数),最多同时存在200个,总计600M,超过则循环式覆盖
# 当前正在写入的日志名称为Log,其它已达到最大容量的日志名称为 Log.1 .2 .3。。。
#


def myfun():
    # 共享主模块日志配置   [通过设置getLogger中的logger 名称与主模块共用同一个logger]
    logger = logging.getLogger('weilinlin')
    print('========fun========')
    for i in range(50):
        logger.debug("测试日志fun %d", i)
if __name__ == "__main__":
    print('main')
    myfun()
# encoding:utf8
import logging
from logging.handlers import RotatingFileHandler
import myFun

logger = logging.getLogger("weilinlin")  # 不加名称 设置为root logger
# 设置logger等级
logger.setLevel(logging.DEBUG)
# 设置日志格式
formatter = logging.Formatter(
    '%(asctime)s - %(pathname)s - %(name)s - %(levelname)s: - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S')

# 设置日志回滚  # 单个日志文件最大为1k,最多保存3份日志文件(除了当前写入的文件外),日志文件编码格式为utf-8
handler = RotatingFileHandler("Log", maxBytes=10240, backupCount=3, encoding='utf-8')
handler.setFormatter(formatter)

# 设置日志名称(此处的x是默认日志名称Log.1,Log.2等内容,会自动取到文件名,然后重命名为自定义的名称)
handler.namer = lambda x: "测试日志名称." + x.split('.')[-1]

# 给logger添加handler
logger.addHandler(handler)

# 测试主模块
for i in range(50):
    logger.debug("测试日志main %d", i)

# 测试子模块打印日志
myFun.myfun()



 

<think>好的,我现在需要帮助用户了解如何在Python实际项目中使用日志模块(logging module)的最佳实践。首先,我得回顾一下用户提供的引用内容,特别是引用[3],里面提到Python日志的使用方法,包括暴露方法给应用程序代码、根据日志等级过滤和处理日志,以及将日志消息传递给handlers。用户希望知道实际案例和最佳实践,所以我需要结合这些信息给出具体建议。 接下来,我应该整理日志模块的主要组件:Logger、Handler、Filter、Formatter。用户可能需要了解如何配置这些组件,特别是在项目中的实际应用。比如,如何设置不同的日志等级,如何输出到文件和终端,以及如何确保日志格式统一。 然后,我需要考虑实际项目中的常见场景,例如多模块使用日志、配置文件的加载、生产环境与开发环境的区别,以及如何避免常见错误。比如,在引用[3]中提到Logger对象的方法分为配置和消息发送,这可能涉及到如何正确获取Logger实例,避免重复配置等问题。 此外,用户可能关心性能优化,比如使用RotatingFileHandler来分割日志文件,防止单个文件过大。者如何结合第三方服务(如Sentry)进行错误监控,这也是实际项目中常见的需求。 另外,需要确保回答结构清晰,分点说明,每个部分都有示例代码,并遵循用户给出的格式要求,比如行内公式用$...$,代码块用三个反引号包裹,正确引用资料中的内容。例如,在解释日志等级时,可以提到不同的等级对应不同的数,如DEBUG=10,INFO=20等,但可能不需要数学公式,所以这部分可能不需要使用LaTeX。 还要检查是否有必要引用其他资料,比如引用[4]提到的Gin包,但用户的问题是关于日志模块,可能不需要涉及,所以主要参考引用[3]。最后,生成的相关问题需要与日志模块相关,比如如何配置日志文件回滚,如何集成到Web框架,者如何测试日志输出等。 总结步骤: 1. 介绍日志模块的基本使用步骤。 2. 提供实际项目中的配置示例,包括文件和控制台输出。 3. 分点列出最佳实践,如配置分离、等级管理、格式统一等。 4. 给出具体案例,如Flask应用中的日志配置。 5. 生成相关问题,引导用户进一步学习。</think>以下是如何在实际项目中使用Python日志模块(`logging`)的案例与最佳实践,结合代码示例和配置建议: --- ### 一、基础使用步骤 1. **初始化Logger** ```python import logging # 创建Logger实例 logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) # 设置最低日志级别 ``` 2. **配置Handler(输出目标)** ```python # 文件Handler(输出到文件) file_handler = logging.FileHandler('app.log') file_handler.setLevel(logging.WARNING) # 仅记录WARNING及以上级别 # 控制台Handler(输出到终端) console_handler = logging.StreamHandler() console_handler.setLevel(logging.INFO) # 记录INFO及以上级别 ``` 3. **定义日志格式** ```python formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) file_handler.setFormatter(formatter) console_handler.setFormatter(formatter) ``` 4. **添加Handler到Logger** ```python logger.addHandler(file_handler) logger.addHandler(console_handler) ``` --- ### 二、实际项目中的最佳实践 #### 1. **配置与代码分离** - 使用`logging.config.dictConfig`加载YAMLJSON配置文件,便于动态调整日志行为[^3]。 ```python import logging.config logging.config.fileConfig('logging.conf') # 从文件加载配置 ``` #### 2. **多模块统一管理** - 在模块中通过`__name__`获取Logger,确保日志命名空间一致: ```python # module_a.py logger = logging.getLogger(__name__) logger.info("Module A initialized") ``` #### 3. **生产环境与开发环境差异化配置** - **生产环境**:仅记录WARNING及以上级别到文件,使用`RotatingFileHandler`分割日志: ```python from logging.handlers import RotatingFileHandler handler = RotatingFileHandler('app.log', maxBytes=1e6, backupCount=5) ``` - **开发环境**:输出DEBUG级别到控制台,便于调试。 #### 4. **异常捕获与堆栈跟踪** 使用`logger.exception`自动记录异常堆栈: ```python try: risky_operation() except Exception as e: logger.exception("Operation failed: %s", e) # 自动添加堆栈信息 ``` #### 5. **避免日志性能问题** - 使用`if logger.isEnabledFor(logging.DEBUG)`避免高开销的日志参数计算: ```python if logger.isEnabledFor(logging.DEBUG): logger.debug(f"Data: {expensive_data_processing()}") ``` --- ### 三、实际案例:Flask应用日志配置 ```python from flask import Flask import logging from logging.handlers import RotatingFileHandler app = Flask(__name__) # 配置日志 handler = RotatingFileHandler('flask_app.log', maxBytes=1e6, backupCount=3) handler.setFormatter(logging.Formatter( '[%(asctime)s] %(levelname)s in %(module)s: %(message)s' )) app.logger.addHandler(handler) app.logger.setLevel(logging.INFO) @app.route('/') def home(): app.logger.info('Home page accessed') return "Hello, World!" ``` --- ### 四、常见问题规避 1. **重复日志输出**:确保不重复添加Handler,可通过`logger.propagate = False`关闭向上传播。 2. **敏感信息泄露**:避免在日志中记录密码、密钥等敏感数据。 3. **时间格式统一**:使用UTC时间并标准化格式(如ISO 8601)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值