限制Python日志文件

时间:2014-06-11 07:42:15

标签: logging python-3.x

我使用Python3(Ubuntu 14.04)写出日志文件。我想限制日志文件的大小,因此选择了RotatingFileHandler。另外,我不想轮换日志文件(.log变成.log.1等等) - 我只想限制日志文件的大小。

我尝试使用RotatingFileHandler这样:

filehandler = logging.handlers.RotatingFileHandler( "app.log", "a", 1000, 0, None, True )
logging.basicConfig( format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s", level = logging.DEBUG, handlers = [ filehandler ] )

我发现的是日志文件继续增长,永远不会被截断或“包裹”#34;在极限。

我原以为设置backupCount = 0会导致在写入之前检查日志文件大小,如果有空间留下日志消息,请写入,否则清空文件并写出消息。

有什么想法吗?

提前致谢,

Bernmeister。

2 个答案:

答案 0 :(得分:5)

如果您查看source code of the RotatingFileHandler,您会看到backupCount为0,然后重新打开日志的流。这是一个修改后的版本,可以执行您想要的操作,丢弃旧文件:

import os
import logging
import logging.handlers


class TruncatedFileHandler(logging.handlers.RotatingFileHandler):
    def __init__(self, filename, mode='a', maxBytes=0, encoding=None, delay=0):
        super(TruncatedFileHandler, self).__init__(
            filename, mode, maxBytes, 0, encoding, delay)

    def doRollover(self):
        """Truncate the file"""
        if self.stream:
            self.stream.close()
        dfn = self.baseFilename + ".1"
        if os.path.exists(dfn):
            os.remove(dfn)
        os.rename(self.baseFilename, dfn)
        os.remove(dfn)
        self.mode = 'w'
        self.stream = self._open()

以下是如何使用它:

filehandler = TruncatedFileHandler("app.log", "w", 1000)
logging.basicConfig(
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    level=logging.DEBUG, handlers=[filehandler])

logger = logging.getLogger('spam_application')

for i in range(100):
    logger.debug("a log line, number: %s", i)

证明它有效

❯❯❯ python3.4 main.py
❯❯❯ cat app.log*
2014-06-11 11:50:44,871 - spam_application - DEBUG - a log line, number: 91
2014-06-11 11:50:44,872 - spam_application - DEBUG - a log line, number: 92
2014-06-11 11:50:44,872 - spam_application - DEBUG - a log line, number: 93
2014-06-11 11:50:44,872 - spam_application - DEBUG - a log line, number: 94
2014-06-11 11:50:44,872 - spam_application - DEBUG - a log line, number: 95
2014-06-11 11:50:44,872 - spam_application - DEBUG - a log line, number: 96
2014-06-11 11:50:44,872 - spam_application - DEBUG - a log line, number: 97
2014-06-11 11:50:44,872 - spam_application - DEBUG - a log line, number: 98
2014-06-11 11:50:44,872 - spam_application - DEBUG - a log line, number: 99

答案 1 :(得分:1)

受到logc的回答的启发,我采取了一种更残酷的方法:我只是删除了日志文件。

class TruncatedFileHandler( logging.handlers.RotatingFileHandler ):
    def __init__( self, filename, mode = "a", maxBytes = 0, encoding = None, delay = 0 ):
        super( TruncatedFileHandler, self ).__init__( filename, mode, maxBytes, 0, encoding, delay )


    def doRollover( self ):
        if self.stream: self.stream.close()

        if os.path.exists( self.baseFilename ): os.remove( self.baseFilename )

        self.mode = "a" # Not sure why but "w" behaves in the same way as "a".
        self.stream = self._open()

我的解决方案和logc的解决方案中有一点是doRollover()被调用,设置self.mode="a"self.mode="w"没有任何区别写入文件。也就是说,我期待" w"开始从文件的开头每次写入但是它没有(它的行为方式与" a"并从它写的最后一个位置写入)。