python-3.x 记录到文件和控制台

lyfkaqu1  于 2023-02-10  发布在  Python
关注(0)|答案(1)|浏览(114)

我有一个Python脚本,我想让info方法把消息写到控制台中,但是warning, critical or error把消息写到一个文件中,我该怎么做呢?
我试过这个:

import logging

console_log = logging.getLogger("CONSOLE")
console_log.setLevel(logging.INFO)

stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
console_log.addHandler(stream_handler)

file_log = logging.getLogger("FILE")
file_log.setLevel(logging.WARNING)

file_handler = logging.FileHandler('log.txt')
file_handler.setLevel(logging.WARNING)
file_log.addHandler(file_handler)

def log_to_console(message):
  console_log.info(message)  

def log_to_file(message):
  file_log.warning(message)

log_to_console("THIS SHOULD SHOW ONLY IN CONSOLE")
log_to_file("THIS SHOULD SHOW ONLY IN FILE")

但是应该只存在于文件中的消息也被传送到了控制台,而应该存在于控制台中的消息却被复制了。2我在这里做错了什么呢?

z0qdvdin

z0qdvdin1#

您创建的两个日志记录器将日志向上传播到根日志记录器,根日志记录器默认没有任何处理程序,但如果需要,将使用lastResort处理程序:
通过此属性可以使用“最后手段的处理程序”。这是一个StreamHandler以WARNING级别写入sys.stderr,用于在没有任何日志记录配置的情况下处理日志记录事件。最终结果是仅将消息打印到sys.stderr
来源于Python文档。
在Python源代码中,可以看到调用是在哪里完成的。
因此,要解决您的问题,您可以将console_logfile_log记录器的propagate属性设置为False
另一方面,我认为你应该避免为你的用例示例化多个日志记录器,只要使用一个定制的日志记录器和两个不同的处理程序,每个处理程序将记录到不同的目的地。
创建a custom StreamHandler以仅记录指定级别:

import logging

class MyStreamHandler(logging.StreamHandler):
    def emit(self, record):
        if record.levelno == self.level:
            # this ensures this handler will print only for the specified level
            super().emit(record)

然后,使用它:

my_custom_logger = logging.getLogger("foobar")
my_custom_logger.propagate = False
my_custom_logger.setLevel(logging.INFO)

stream_handler = MyStreamHandler()
stream_handler.setLevel(logging.INFO)

file_handler = logging.FileHandler("log.txt")
file_handler.setLevel(logging.WARNING)

my_custom_logger.addHandler(stream_handler)
my_custom_logger.addHandler(file_handler)

my_custom_logger.info("THIS SHOULD SHOW ONLY IN CONSOLE")
my_custom_logger.warning("THIS SHOULD SHOW ONLY IN FILE")

它的工作没有重复和没有错位的日志。

相关问题