在 Python 日志记录模块 AKA 日志压缩中抑制具有相同内容的多条消息
Posted
技术标签:
【中文标题】在 Python 日志记录模块 AKA 日志压缩中抑制具有相同内容的多条消息【英文标题】:Suppress multiple messages with same content in Python logging module AKA log compression 【发布时间】:2017-11-25 06:29:14 【问题描述】:根据设计,我的应用程序有时会产生重复的错误,这些错误会填满日志文件并使其阅读起来很烦人。看起来是这样的:
WARNING:__main__:CRON10: clock unset or no wind update received in 60 sec -> supressed rrd update
WARNING:__main__:CRON10: clock unset or no wind update received in 60 sec -> supressed rrd update
WARNING:__main__:CRON10: clock unset or no wind update received in 60 sec -> supressed rrd update
WARNING:__main__:CRON10: clock unset or no wind update received in 60 sec -> supressed rrd update
如何使用 Python 日志记录模块来抑制重复消息并输出更多 rsyslog 样式 (http://www.rsyslog.com/doc/rsconf1_repeatedmsgreduction.html):
WARNING:__main__:CRON10: clock unset or no wind update received in 60 sec -> supressed rrd update
--- The last message repeated 3 times
有没有办法扩展日志记录,还是我必须编写一个完全自己的记录器?
我用于记录的代码是:
logging.basicConfig(format='%(asctime)s %(message)s')
logging.basicConfig(level=logging.info)
logger = logging.getLogger(__name__)
hdlr = logging.FileHandler(LOGFILE)
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
对此有什么想法吗?
【问题讨论】:
How to avoid duplicate outputs using logging module的可能重复 @Anthon:链接的欺骗是关于注册多个处理程序的结果。这不是这里描述的问题。 【参考方案1】:您可以创建一个logging.Filter
,它将跟踪最后记录的记录并过滤掉任何重复(相似)的记录,例如:
import logging
class DuplicateFilter(logging.Filter):
def filter(self, record):
# add other fields if you need more granular comparison, depends on your app
current_log = (record.module, record.levelno, record.msg)
if current_log != getattr(self, "last_log", None):
self.last_log = current_log
return True
return False
然后只需将其添加到您使用的记录器/处理程序(即hdlr.addFilter(DuplicateFilter())
)或根记录器即可过滤所有默认日志。这是一个简单的测试:
import logging
logging.warn("my test")
logging.warn("my repeated test")
logging.warn("my repeated test")
logging.warn("my repeated test")
logging.warn("my other test")
logger = logging.getLogger() # get the root logger
logger.addFilter(DuplicateFilter()) # add the filter to it
logging.warn("my test")
logging.warn("my repeated test")
logging.warn("my repeated test")
logging.warn("my repeated test")
logging.warn("my other test")
这将打印出来:
警告:root:我的测试 警告:root:我的重复测试 警告:root:我的重复测试 警告:root:我的重复测试 警告:root:我的其他测试 警告:root:我的测试 警告:root:我的重复测试 警告:root:我的其他测试
【讨论】:
CAVEAT:如果logging.*()
与格式字符串参数一起使用(例如logging.warn("some error: %s",errstr)
),DuplicateFilter 会将任何此类行视为重复,因为检查了格式字符串 - 而不是打印的字符串。跨度>
这可以通过调用record.getMessage()
来规避以上是关于在 Python 日志记录模块 AKA 日志压缩中抑制具有相同内容的多条消息的主要内容,如果未能解决你的问题,请参考以下文章