想要使用 YAML 设置带有过滤器的记录器。
YAML配置文件config.yaml如下:
version: 1
formatters:
simple:
format: "%(asctime)s %(name)s: %(message)s"
extended:
format: "%(asctime)s %(name)s %(levelname)s: %(message)s"
filters:
noConsoleFilter:
class: noConsoleFilter
handlers:
console:
class: logging.StreamHandler
level: INFO
formatter: simple
filters: [noConsoleFilter]
file_handler:
class: logging.FileHandler
level: INFO
filename: test.log
formatter: extended
root:
handlers: [console, file_handler]
propagate: true
Run Code Online (Sandbox Code Playgroud)
...主程序如下main.py:
import logging.config
import yaml
class noConsoleFilter(logging.Filter):
def filter(self, record):
print("filtering!")
return not (record.levelname == 'INFO') & ('no-console' in record.msg)
with open('config.yaml', 'r') as f:
log_cfg = yaml.safe_load(f.read())
logging.config.dictConfig(log_cfg)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.info("no-console. Should not be in console, but be in test.log!")
logger.info('This is an info message')
logger.error('This is an error message')
Run Code Online (Sandbox Code Playgroud)
控制台中的预期输出没有“no-console”消息:
2020-04-27 18:05:26,936 __main__: This is an info message
2020-04-27 18:05:26,936 __main__: This is an error message
Run Code Online (Sandbox Code Playgroud)
但看起来 class:noConsoleFilter甚至没有被考虑,因为 print 语句也不起作用。
我哪里错了?我该如何修复它?
语法有点奇怪,但它在日志记录文档中的“用户定义对象”下进行了描述,您必须使用 key (),而不是class。就像这样:
filters:
noConsoleFilter:
(): noConsoleFilter
Run Code Online (Sandbox Code Playgroud)
接下来,您需要为类指定一个限定名称。如果您直接运行脚本,而不是作为模块运行,则可以在以下位置引用它__main__:
filters:
noConsoleFilter:
(): __main__.noConsoleFilter
Run Code Online (Sandbox Code Playgroud)
我还建议对类名使用 PEP 8 CapWords 约定。这是一个稍微整理过的、完全独立的示例:
# logging.yml
version: 1
formatters:
simple_formatter:
format: "%(asctime)s %(name)s: %(message)s"
extended_formatter:
format: "%(asctime)s %(name)s %(levelname)s: %(message)s"
filters:
no_console_filter:
(): __main__.NoConsoleFilter
handlers:
console_handler:
class: logging.StreamHandler
level: INFO
formatter: simple_formatter
filters: [no_console_filter]
file_handler:
class: logging.FileHandler
level: INFO
filename: test.log
formatter: extended_formatter
root:
handlers: [console_handler, file_handler]
propagate: true
Run Code Online (Sandbox Code Playgroud)
# script.py
import logging.config
import yaml
class NoConsoleFilter(logging.Filter):
def filter(self, record):
print('filtering!')
return not (record.levelname == 'INFO') & ('no-console' in record.msg)
with open('logging.yml', 'r') as f:
log_cfg = yaml.safe_load(f.read())
logging.config.dictConfig(log_cfg)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.info('no-console. Should not be in console, but be in test.log!')
logger.info('This is an info message')
logger.error('This is an error message')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5334 次 |
| 最近记录: |