我正在使用记录(import logging
)来记录消息。
在1个单独的模块中,我在调试级别my_logger.debug('msg')
记录消息;
其中一些调试消息来自function_a()
,其他来自function_b()
;我希望能够根据它们来自a还是来自b来启用/禁用日志记录;
我猜我必须使用Logging的过滤机制。
有人可以告诉我下面的代码是如何进行检测以做我想要的吗?
import logging
logger= logging.getLogger( "module_name" )
def function_a( ... ):
logger.debug( "a message" )
def function_b( ... ):
logger.debug( "another message" )
if __name__ == "__main__":
logging.basicConfig( stream=sys.stderr, level=logging.DEBUG )
#don't want function_a()'s noise -> ....
#somehow filter-out function_a's logging
function_a()
#don't want function_b()'s noise -> ....
#somehow filter-out function_b's logging
function_b()
如果我将这个简单的例子扩展到每个模块的更多模块和更多功能,我会关注很多记录器;
我可以将每个模块保持在1个记录器吗?请注意,日志消息是“结构化的”,即如果记录它的函数正在进行一些解析工作,它们都包含前缀logger.debug("parsing: xxx")
- 我可以以某种方式使用单行关闭所有“解析“消息(无论发出消息的模块/功能如何?)
答案 0 :(得分:48)
只需实现logging.Filter
:http://docs.python.org/library/logging.html#filter-objects的子类。它将有一个方法filter(record)
,它检查日志记录并返回True以记录它或False以丢弃它。然后,您可以通过调用Logger
方法在Handler
或addFilter(filter)
上安装过滤器。
示例:
class NoParsingFilter(logging.Filter):
def filter(self, record):
return not record.getMessage().startswith('parsing')
logger.addFilter(NoParsingFilter())
或类似的东西,无论如何。
答案 1 :(得分:17)
不要使用全球。这是一个等待发生的事故。
您可以为记录器添加任何“。” - 对您有意义的分隔名称。
您可以将它们控制为层次结构。如果您有名为a.b.c
的记录器和
a.b.d
,您可以检查a.b
的日志记录级别并更改两个记录器。
你可以拥有任意数量的记录器 - 它们很便宜。
最常见的设计模式是每个模块一个记录器。见Naming Python loggers
这样做。
import logging
logger= logging.getLogger( "module_name" )
logger_a = logger.getLogger( "module_name.function_a" )
logger_b = logger.getLogger( "module_name.function_b" )
def function_a( ... ):
logger_a.debug( "a message" )
def functio_b( ... ):
logger_b.debug( "another message" )
if __name__ == "__main__":
logging.basicConfig( stream=sys.stderr, level=logging.DEBUG )
logger_a.setLevel( logging.DEBUG )
logger_b.setLevel( logging.WARN )
... etc ...
答案 2 :(得分:1)
我发现了一种更简单的方法,该方法可以使用 sshtunel 模块过滤掉以下问题的默认日志记录配置,以取代INFO级消息。
带有前2个不需要的记录的默认报告如下:
2020-11-10 21:53:28,114 INFO paramiko.transport: Connected (version 2.0, client OpenSSH_7.9p1)
2020-11-10 21:53:28,307 INFO paramiko.transport: Authentication (password) successful!
2020-11-10 21:53:28,441 INFO |-->QuerySSH: Query execution successful.
记录器配置更新:
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s %(levelname)-10s %(name)s: %(message)s',
handlers=[
logging.StreamHandler(),
logging.FileHandler(self.logging_handler)
]
)
# Filter paramiko.transport debug and info from basic logging configuration
logger_descope = logging.getLogger('paramiko.transport')
logger_descope.setLevel(logging.WARN)
结果令我满意的是:
2020-11-10 22:00:48,755 INFO |-->QuerySSH: Query execution successful.
答案 3 :(得分:0)
我在您的主脚本中找到了一种使用函数的简单方法:
# rm 2to3 messages
def filter_grammar_messages(record):
if record.funcName == 'load_grammar':
return False
return True
def filter_import_messages(record):
if record.funcName == 'init' and record.msg.startswith('Importing '):
return False
return True
logging.getLogger().addFilter(filter_grammar_messages) # root
logging.getLogger('PIL.Image').addFilter(filter_import_messages)