python - 将python登录到多个文件目的地的正确方法,从setting.ini文件而不组合级别
问题描述
我正在尝试将 python 登录到 settings.ini 文件中的两个文件,具有不同的级别,但其中一个在两个文件中打印
我需要通过控制台和两个文件显示错误消息:
- 控制台和日志文件的错误级别
- 并且 INFO 级别仅按文件。
我读过这个以前的帖子:
这非常有用。我尝试使用 class=FileHandler 和 args=('log_error','w') 为 ERROR 级别定义第二个记录器和第二个 errorHandler,但结果相同。
我认为我的问题与传播属性有关,根据文档在此处https://docs.python.org/3/library/logging.config.html#configuration-file-format的说明,就像这样说python 记录到多个目的地但我没有找到错误。
我尝试将传播设置为 False/0,但它不起作用。
- 错误在哪里?
- 建议每个级别都使用它自己的每个手柄?
- 我可以做任何其他额外的改进吗?
谢谢你的帮助
这是我的主文件:
from settings import *
def main():
# logger.info("2")
logger.error("4")
if __name__ == "__main__":
main()
这是我的 settings.py 文件:
# -*- coding: utf-8 -*-
import os
import logging
import logging.config
from configparser import RawConfigParser
BASE_DIR = os.getcwd()
config = RawConfigParser()
config.read(BASE_DIR + '/settings.ini')
logging.config.fileConfig(fname=config, disable_existing_loggers=True)
# Create a custom logger
logger = logging.getLogger(__name__)
# Create handlers
handler_info = logging.FileHandler('log_info.log')
handler_error = logging.FileHandler('log_error.log')
handler_info.setLevel(logging.INFO)
handler_error.setLevel(logging.ERROR)
# Create formatters and add it to handlers
format_info = logging.Formatter('%(asctime)s - %(levelname)s - %(module)s : %(message)s')
format_error = logging.Formatter('%(asctime)s - %(levelname)s - %(module)s - %(lineno)d - %(message)s')
handler_info.setFormatter(format_info)
handler_error.setFormatter(format_error)
# Add handlers to the logger
logger.addHandler(handler_info)
logger.addHandler(handler_error)
这是我的 settings.ini 文件:
[loggers]
keys=root
[handlers]
keys=consoleHandler
[formatters]
keys=sampleFormatter
[logger_root]
level=INFO
handlers=consoleHandler
[handler_consoleHandler]
class=StreamHandler
level=ERROR
formatter=sampleFormatter
args=(sys.stdout,)
[formatter_sampleFormatter]
format=%(asctime)s - %(levelname)s - %(message)s
当我打印一条 INFO 消息时,一切正常,但是当打印错误时,它会写入消息 log_error.log 和 log_info.log 以及控制台。如果发生错误,我不需要写入 log_info.log。
解决方案
您可以将自定义过滤器添加到您的处理程序。
import logging
def custom_filter(record):
if record.levelname == 'INFO':
return True
handler = logging.StreamHandler()
handler.addFilter(custom_filter)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
logger.debug('1')
logger.info('2')
logger.error('3')
2
可以阅读日志模块源码,很容易理解,只有custom_filter
返回值才能转换为True,否则日志记录将被忽略。
推荐阅读
- python - jinja2.exceptions.UndefinedError:“消息”未定义
- c++11 - 在此示例中,让 `std::ostreambuf_iterator` 写入字符串而不是 `std::cout`
- javascript - 带有 SSML 的 SpeechSynthesisUtterance 是童话吗?
- javascript - Gatsby/Contentful 将数据从一个组件传递到另一个组件
- unit-testing - 如何在 KMM 上为 SQLDelight 编写单元测试
- java - API 级别 22 中的文本到语音问题
- swiftui - SwiftUI:在 Xcode 12/iOS 14 中使用环境对象(--> 如何/在哪里放置对象在环境中?)
- sql - SQL:使用容量将单行拆分为多行
- c# - 尝试使用 JWT 进行 ASP NET Owin 身份验证时出错?
- python - 电报机器人中未显示回复按钮