Python logging添加布尔过滤器报错:'bool' object is not callable
问题:Python Logger配置出现重复日志及TypeError报错
配置代码
import logging # create and configure main logger logger = logging.getLogger(__name__) # create console handler with a higher log level handler = logging.StreamHandler() handler.setLevel(logging.DEBUG) # create formatter and add it to the handler formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') secret_filter = False#SecretFilter() handler.setFormatter(formatter) # add the handler to the logger handler.addFilter(secret_filter) # prevent logging of secrets for hdlr in logger.handlers[:]: # remove the existing file handlers if isinstance(hdlr, logging.FileHandler): logger.removeHandler(hdlr) logger.addHandler(handler) logger.setLevel(logging.DEBUG)
执行代码
logger.info('setting up logger, done')
报错及现象
控制台重复输出5次日志后抛出错误:
2023-12-18 10:20:45,581 - __main__ - INFO - setting up logger, done 2023-12-18 10:20:45,581 - __main__ - INFO - setting up logger, done 2023-12-18 10:20:45,581 - __main__ - INFO - setting up logger, done 2023-12-18 10:20:45,581 - __main__ - INFO - setting up logger, done 2023-12-18 10:20:45,581 - __main__ - INFO - setting up logger, done Traceback (most recent call last): Cell In[27], line 1 logger.info('setting up logger, done') File ~\AppData\Local\anaconda3\envs\prod-env-shap\Lib\logging\__init__.py:1489 in info self._log(INFO, msg, args, **kwargs) File ~\AppData\Local\anaconda3\envs\prod-env-shap\Lib\logging\__init__.py:1634 in _log self.handle(record) File ~\AppData\Local\anaconda3\envs\prod-env-shap\Lib\logging\__init__.py:1644 in handle self.callHandlers(record) File ~\AppData\Local\anaconda3\envs\prod-env-shap\Lib\logging\__init__.py:1706 in callHandlers hdlr.handle(record) File ~\AppData\Local\anaconda3\envs\prod-env-shap\Lib\logging\__init__.py:974 in handle rv = self.filter(record) File ~\AppData\Local\anaconda3\envs\prod-env-shap\Lib\logging\__init__.py:832 in filter result = f(record) # assume callable - will raise if not TypeError: 'bool' object is not callable
环境版本
python 3.11.5 pandas 2.1.4 holidays 0.29 scikit-learn 1.3.0 jaydebeapi 1.2.3 boto3 1.29.1
解决方案
1. 修复TypeError:bool对象不可调用
handler.addFilter()要求传入可调用对象(比如实现filter方法的类实例,或接收日志记录参数并返回bool值的函数),你传入的secret_filter = False是布尔值,不属于可调用对象,直接触发报错。
两种解决方式:
- 若暂时不需要过滤功能,直接注释掉
handler.addFilter(secret_filter)这一行; - 若需实现SecretFilter,自定义继承
logging.Filter的类,示例:
class SecretFilter(logging.Filter): def filter(self, record): # 自定义过滤逻辑,示例:屏蔽包含"secret"的日志内容 return "secret" not in record.getMessage().lower() # 替换原secret_filter赋值 secret_filter = SecretFilter() handler.addFilter(secret_filter)
2. 修复重复日志输出问题
重复输出是因为每次运行配置代码时,都会给logger新增StreamHandler,但你只移除了FileHandler,旧的StreamHandler未被清理,导致多个handler同时输出日志。
修改代码,在添加新handler前移除所有已有handler:
# 替换原仅移除FileHandler的循环 for hdlr in logger.handlers[:]: logger.removeHandler(hdlr)
最终修正后的完整代码
import logging class SecretFilter(logging.Filter): def filter(self, record): # 自定义过滤逻辑,可根据需求修改 return "secret" not in record.getMessage().lower() # create and configure main logger logger = logging.getLogger(__name__) # 移除所有已有handler,避免重复输出 for hdlr in logger.handlers[:]: logger.removeHandler(hdlr) # create console handler with a higher log level handler = logging.StreamHandler() handler.setLevel(logging.DEBUG) # create formatter and add it to the handler formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) # 添加自定义过滤器(不需要则注释) secret_filter = SecretFilter() handler.addFilter(secret_filter) # add the handler to the logger logger.addHandler(handler) logger.setLevel(logging.DEBUG)
内容的提问来源于stack exchange,提问作者Sade
相关产品推荐
相关产品推荐

