扩展Python日志记录器

3 投票
3 回答
8803 浏览
提问于 2025-04-17 01:08

我想找到一种简单的方法来扩展标准Python库中定义的日志功能。我只想要一个选择,决定我的日志是否也要打印到屏幕上。

举个例子:通常要记录一个警告,你会这样调用:

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s: %(message)s', filename='log.log', filemode='w')
logging.warning("WARNING!!!")

这段代码设置了日志的配置,并把警告信息放进日志里。

我希望能有类似这样的调用:

logging.warning("WARNING!!!", True)

其中的True表示日志是否也打印到标准输出(即屏幕)上。

我见过一些关于重写日志类的实现示例,但我对这门语言还很陌生,不太明白发生了什么,也不知道该如何实现这个想法。任何帮助都将非常感激 :)

3 个回答

1

处理器将日志记录(由记录器创建)发送到合适的目的地。

(来自文档: http://docs.python.org/library/logging.html)

只需为你的日志对象设置多个处理器,一个用来写入文件,另一个用来写入屏幕。

更新

这里有一个示例函数,你可以在你的类中调用它来设置带有处理器的日志记录。

def set_up_logger(self):
    # create logger object
    self.log = logging.getLogger("command")
    self.log.setLevel(logging.DEBUG)

    # create console handler and set min level recorded to debug messages
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)

    # add the handler to the log object        
    self.log.addHandler(ch)

你只需要为文件设置另一个处理器,像已经存在的StreamHandler代码那样,然后将其添加到日志对象中。那行代码 ch.setLevel(logging.DEBUG) 的意思是这个特定的处理器会接收DEBUG级别或更高级别的日志消息。你可能希望将你的设置为WARNING级别或更高,因为你只想把更重要的内容输出到控制台。所以,你的日志记录会像这样工作:

self.log.info("Hello, World!") -> goes to file
self.log.error("OMG!!") -> goes to file AND console
2

你可以通过重写 logging.getLoggerClass() 来给日志记录器添加新的功能。我写了一个简单的类,可以在 stdout(标准输出)上打印绿色的消息。

我代码中最重要的部分是:

class ColorLogger(logging.getLoggerClass()):
    __GREEN = '\033[0;32m%s\033[0m'
    __FORMAT = {
        'fmt': '%(asctime)s %(levelname)s: %(message)s',
        'datefmt': '%Y-%m-%d %H:%M:%S',
    }

    def __init__(self, format=__FORMAT):
        formatter = logging.Formatter(**format)

        self.root.setLevel(logging.INFO)
        self.root.handlers = []

        (...)

        handler = logging.StreamHandler()
        handler.setFormatter(formatter)
        self.root.addHandler(handler)

    def info(self, message):
        self.root.info(message)

    (...)

    def info_green(self, message):
        self.root.info(self.__GREEN, message)

(...)

if __name__ == '__main__':
    logger = ColorLogger()
    logger.info("This message has default color.")
    logger.info_green("This message is green.")
8

Python的日志模块定义了以下几种类:

日志记录器:负责发出日志信息。
处理器:将这些信息发送到指定的地方。
格式化器:负责格式化日志信息。
过滤器:用来筛选日志信息。

一个日志记录器可以有多个处理器。你可以通过调用 addHandler() 方法来添加它们。一个处理器也可以有过滤器格式化器,你同样可以通过调用 addFilter()setFormatter() 方法来添加它们。

它的工作原理是这样的:

import logging

# make a logger
main_logger = logging.getLogger("my logger")
main_logger.setLevel(logging.INFO)

# make some handlers
console_handler = logging.StreamHandler() # by default, sys.stderr
file_handler    = logging.FileHandler("my_log_file.txt")

# set logging levels
console_handler.setLevel(logging.WARNING)
file_handler.setLevel(logging.INFO)

# add handlers to logger
main_logger.addHandler(console_handler)
main_logger.addHandler(file_handler)

现在,你可以像这样使用这个对象:

main_logger.info("logged in the FILE")
main_logger.warning("logged in the FILE and on the CONSOLE")

如果你在你的电脑上运行 python,可以在交互式控制台中输入上面的代码,你应该能看到输出。如果你有权限在当前目录下创建文件,日志文件会在你的当前目录中生成。

希望这对你有帮助!

撰写回答