来自文档:
http://docs.python.org/2.7/library/logging.handlers.html#watchedfilehandler
WatchedFileHandler 类,位于 logging.handlers 模块中,
是一个 FileHandler,它监视它正在记录的文件。如果文件
更改后,它会关闭并使用文件名重新打开。
WatchedFileHandler 适用于 Linux,但不适用于 Windows(因为它没有 inode)。它监视文件 inode 上的更改。如果对该文件进行了任何更改,则会将其关闭并再次打开。
根据 WatchedFileHandler 的实现方式,我认为他们会重复此过程,直到它可以安全地写入文件,但这可能意味着您的进程一直在为日志文件打开/关闭。
更正:它尝试关闭一次,然后再次重新打开文件。我正在寻找另一种解释,说明为什么您没有遇到问题。
到目前为止,我没有找到任何理由来解释为什么您的日志中没有混合行。 WatchedFileHandler 旨在供一个应用程序使用(在发出之前使用 RLock 控制多线程访问,但有一个有价值的例外是支持外部更改,例如日志轮换)。但是查看它的超类的源码,我没有找到任何原因。一个未经检验的理论是:
a) 因为日志总是以附加模式打开
b) 因为它在写入之前检查一次,是否有任何变化
c) 你总是得到一个完整的行,因为你的行小于写入缓冲区。所以你从最后一行的末尾开始,写一个新行,这个过程一次又一次地重复。如果两个进程同时写,它们将从最后一行的末尾开始写新的行。
尝试查找日志行上的异常情况,例如缺少行...如果日志的大小非常规则,则可能难以检查并发问题。我也会在日志的最后一行查找异常情况。
您的系统有多少个处理器?
破解日志的测试程序:
import logging
import logging.handlers
import sys
FORMAT = "%(asctime)-15s %(process)5d %(message)s"
logger = logging.getLogger(__name__)
wfh = logging.handlers.WatchedFileHandler("test.log", "a")
wfh.setFormatter(logging.Formatter(FORMAT))
logger.addHandler(wfh)
logger.setLevel(logging.DEBUG)
n = int(sys.argv[1])
for x in range(1000):
logger.info("%6d %s" % (x, str(n)*(4096+n)))
使用简单的 shell 脚本运行:
python test.py 1 &
python test.py 2 &
python test.py 3 &
python test.py 4 &
python test.py 5 &
python test.py 6 &
python test.py 7 &
python test.py 8 &
python test.py 9 &
在具有 4 个处理器的 CentOS 6.3 上运行,我开始看到线路异常。可以在程序中改变线条的大小,小线条看起来还可以,大线条就不行了。
您可以通过以下方式进行测试:
grep -v ^2013 test.log
如果日志没问题,所有行都以 2013 开头。grep 不会列出混合行,但我可以用 less 轻松找到它们。
因此,它对您有用,因为您的行小于写入缓冲区,或者因为您的进程不经常写入日志,但即使是它们,也不能保证它会一直有效。