API与应用程序(Python)的日志机制差异

4 投票
3 回答
3192 浏览
提问于 2025-04-15 21:33

我现在正在写一个API和一个使用这个API的应用程序。有些人建议我在应用程序中使用处理器来进行日志记录,并在API中使用一个“logger”对象来记录日志。

根据我收到的建议,下面的实现方式是否正确呢?

class test:
    def __init__(self, verbose):
        self.logger = logging.getLogger("test")
        self.logger.setLevel(verbose)
    
    def do_something(self):
        # do something
        self.logger.log("something")
        # by doing this i get the error message "No handlers could be found for logger "test"

我想的实现方式如下:

 #!/usr/bin/python

 """ 
 ....
 ....
 create a logger with a handler 
 ....
 ....

 """

 myobject = test()
 try:
     myobject.do_something()
 except SomeError:
     logger.log("cant do something")

我想打好基础,如果你能推荐一些我可以查阅的代码或提供帮助,我会非常感激。

谢谢!

3 个回答

1

我通常会这样做:

import logging
import logging.config
logging.config.fileConfig('log.congig')

# for one line log records 
G_LOG = logging.getLogger(__name__)
# for records with stacktraces
ST_LOG = logging.getLogger('stacktrace.' + __name__)


try:
    # some code
    G_LOG.info('some message %s %s', param1, param2)
except (StandardError,):
    message = 'some message'
    G_LOG.error(message)
    # exc_info appends stacktrace to the log message
    ST_LOG.error(message, exc_info=True)

配置文件的格式可以在Python手册中查看。

4

你在考虑的这种做法有个危险,就是你可能会把错误藏起来,只是把它们记录在日志里。其实很多错误是应该让程序崩溃的,因为它们代表了需要修复的问题。通常来说,使用调试工具深入代码去找出错误的原因会更有帮助。

当然,如果有些错误是你预料之中的,并且不会影响程序的稳定性或正确性,那么只记录到日志里也是可以的。但在使用这种方法时,一定要非常小心。

18

你的问题是关于如何使用日志记录,还是关于记录异常的具体情况,这一点不是很清楚。不过如果是后者,我同意Adam Crossland的看法,"记录并忽略"这种做法是应该避免的。

关于日志记录的具体操作,我有以下几点观察:

  1. 你不需要把日志记录器作为实例成员。更自然的做法是在模块级别声明日志记录器,使用 logger = logging.getLogger(__name__),这样在子包中也能正常工作。
  2. 你调用 logger.log("message") 可能会失败,因为日志方法的第一个参数应该是级别,而不是消息。

你应该声明处理器,如果你的使用场景比较简单,可以在你的主方法或者 if __name__ == '__main__': 这个条件下添加,比如:

logging.basicConfig(filename='/tmp/myapp.log', level=logging.DEBUG, 
                    format='%(asctime)s %(levelname)s %(name)s %(message)s')

然后在你的代码的其他地方,只需在每个需要使用日志记录的模块顶部做一次,比如:

import logging
logger = logging.getLogger(__name__)

然后在你的代码中随时需要的地方使用。

logger.debug('message with %s', 'arguments') # or .info, .warning, .error etc.

撰写回答