简体   繁体   English

Python RotatingFileHandler似乎没有旋转日志

[英]Python RotatingFileHandler doesn't seem to be rotating the logs

I had setup a logger with the following code: 我用以下代码设置了记录器:

log = logging.getLogger('base')
logfilename =  <path to logfile>
logFile = logging.FileHandler(logfilename)
log.setLevel(debug)
logFile.setFormatter(logging.Formatter('[%(asctime)s]: [%(filename)s:%(lineno)d:%(funcName)s]: %(levelname)s :: %(message)s', datefmt='%m-%d-%Y %H:%M:%S'))
log.addHandler(logFile)

Since the log files were large, I wanted to create a rotating log file. 由于日志文件很大,因此我想创建一个旋转日志文件。 Hence I made the following change: 因此,我进行了以下更改:

# logFile = logging.FileHandler(logfilename)
logFile = RotatingFileHandler(logfilename, maxBytes=1024)  # maxBytes=1024 only for testing

However, the resulting log file isn't rotated. 但是,结果日志文件不会旋转。 I still get logs that are few MBs large. 我仍然收到几MB大的日志。 I have cleared all the .pyc files. 我已经清除了所有.pyc文件。

Questions: 问题:

  1. Is it necessary to specify the backup count (I need to retain all logs! Hence if this is mandatory, I have to give some insanely large number). 是否有必要指定备份计数(我需要保留所有日志!因此,如果这是强制性的,我必须提供一些疯狂的数字)。
  2. By maxBytes I assume it is actual Bytes (so in my case log should be rotated every 1 kB) and nothing else. 通过maxBytes我假设它是实际的Bytes(因此,在我的情况下,日志应每1 kB旋转一次),除此之外别无其他。 Am I correct? 我对么?
  3. Is there a minimum number for maxBytes below which rotating is ineffective? maxBytes是否有最小数量,低于此数量则无效? (I suppose not) (我想不是)

I work with Python 2.7.14 (Anaconda) and 3.6.4 (Anaconda). 我使用Python 2.7.14(Anaconda)和3.6.4(Anaconda)。

From the docs : 文档

if either of maxBytes or backupCount is zero, rollover never occurs, so you generally want to set backupCount to at least 1, and have a non-zero maxBytes. 如果maxBytes或backupCount中的任何一个为零,则永远不会发生过渡,因此通常需要将backupCount设置为至少1,并且maxBytes为非零。

Which means that without setting backupCount (the default value is 0) you don't get any rollover functionality 这意味着如果不设置backupCount (默认值为0),您将不会获得任何过渡功能

I need to retain all logs! 我需要保留所有日志! Hence if this is mandatory, I have to give some insanely large number 因此,如果这是强制性的,我必须给一些疯狂的数字

Yes! 是! Set some insanely large number, and maybe add another script to backup old files every once in a while 设置一些疯狂的数字,也许不时添加另一个脚本来备份旧文件

You need to set a backupCount value, or change the file mode from appending to truncating on open. 您需要设置一个backupCount值, 将文件模式从追加更改为打开时截断。

The log file is closed, but then re-opened again for appending , so you never actually see a difference. 日志文件关闭,但随后又重新打开以进行追加 ,因此您从未真正看到任何区别。

What happens now is: 现在发生的是:

  • The handler tests if the current file length plus the message pushes the file length over the maximum. 处理程序测试当前文件长度和消息是否将文件长度推到最大。
    • If the length is over the maximum, close the file 如果长度超过最大长度,请关闭文件
    • If backupCount is greater than zero, rotate any existing backup files, and then rename the log file to add .1 如果backupCount大于零,请旋转所有现有的备份文件,然后重命名日志文件以添加.1
    • Open the logfile for appending. 打开日志文件进行追加。 If there already is a file there with the same name, then that file is re-opened. 如果已经有一个同名文件,则重新打开该文件。
  • Write the message to the open log file. 将消息写入打开的日志文件。

Apart from setting backupCount to a number higher than 0, you could also change the mode parameter to 'w' , at which point you'll find that the file is truncated each time it would get too large: 除了将backupCount设置为大于0的数字之外,还可以将mode参数更改为'w' ,这时您会发现文件每次变得太大时都会被截断

# 'rotate' logfile by truncating:
logFile = RotatingFileHandler(logfilename, mode='w', maxBytes=1024)

Note that the file can still become larger than maxBytes , if the new message itself is greater than 1024 bytes long. 请注意,如果新消息本身的长度大于1024字节,则文件仍可以大于maxBytes

There is no option to retain all rotated files. 没有保留所有旋转文件的选项。 You'd indeed have to use an insanely high number, or use a different file rotation strategy. 实际上,您确实必须使用极高的数字, 或者使用其他文件轮换策略。 For example, the TimedRotatingFileHandler rotates files after a given interval, and if you leave backupCount at zero, it'll never delete rotated backups. 例如, TimedRotatingFileHandler在给定间隔后旋转文件,并且如果将backupCount保持为零,则它将永远不会删除旋转的备份。

You could also subclass RotatingFileHandler() to implement your own renaming strategy, providing your own doRollover() method. 您还可以提供RotatingFileHandler()子类来实现自己的重命名策略,并提供自己的doRollover()方法。 You need to generate unique names if you want to retain all backups; 如果要保留所有备份,则需要生成唯一的名称。 you could add a UUID to ensure this (together with the date): 您可以添加一个UUID来确保这一点(连同日期):

import uuid
from datetime import datetime
from logging import RotatingFileHandler

class InfiniteRotatingFileHandler(RotatingFileHandler):
    def doRollover(self):
        if self.stream:
            self.stream.close()
            self.stream = None
        new_name = '{}.{:%Y%m%d%H%M%S}.{}'.format(
            self.baseFilename, datetime.now(), uuid.uuid4())
        self.rotate(self.baseFilename, new_name)
        if not self.delay:
            self.stream = self._open()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM