[英]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: 问题:
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? 我对么? 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)。
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: 现在发生的是:
backupCount
is greater than zero, rotate any existing backup files, and then rename the log file to add .1
如果backupCount
大于零,请旋转所有现有的备份文件,然后重命名日志文件以添加.1
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.