日志处理器:如何确保我不制造两个?

5 投票
1 回答
1661 浏览
提问于 2025-04-16 15:31

编辑:我最终解决了我问题的核心部分,这样我就可以有一个正常工作的日志模块了。不过,我还有一个相关的问题。请看我下面的回答。

我正在尝试实现一个日志记录功能,目的是在我所处的操作系统的临时目录中始终记录日志。为此,我写了以下这个函数。

import logging, tempfile, os, sys

def getlog(logname, filename = 'python.log', directory = None):
   '''returns a logger with logname that will print to filename and directoryname.'''
   if directory == None:
      fd, fname = tempfile.mkstemp()
      directory = os.path.dirname(fname)

   fullpath = directory + '/' + filename

   mylog = logging.getLogger(logname)
   hdlr = logging.FileHandler(fullpath)

   formatter = logging.Formatter('L:%(name)s M:%(module)s T:%(asctime)s > %(levelname)s: %(message)s')
   hdlr.setFormatter(formatter)
   mylog.addHandler(hdlr)
   mylog.setLevel(logging.INFO)
   mylog.info('NEW LOGGER STARTED')
   return mylog

if __name__ == '__main__':
   log = getlog('testing')
   log.info('working?')
   log.info('yes, seems to be working')

   log2 = getlog('testing')
   log2.info('still working?')

这是输出结果:

L:testing M:easy_log T:2011-04-11 15:30:14,315 > INFO: NEW LOGGER STARTED
L:testing M:easy_log T:2011-04-11 15:30:14,316 > INFO: working?
L:testing M:easy_log T:2011-04-11 15:30:14,316 > INFO: yes, seems to be working
L:testing M:easy_log T:2011-04-11 15:30:14,316 > INFO: NEW LOGGER STARTED
L:testing M:easy_log T:2011-04-11 15:30:14,316 > INFO: NEW LOGGER STARTED
L:testing M:easy_log T:2011-04-11 15:30:14,316 > INFO: still working?
L:testing M:easy_log T:2011-04-11 15:30:14,316 > INFO: still working?

你可以看到,现在输出的内容是重复的。不过,日志模块有点让人困惑,我不知道怎么判断一个日志是否已经被创建,或者一个日志对象是否已经有了处理器。如果能得到一些帮助,我会很感激。

编辑:为了提供更多细节,我计划在几个模块中调用这个功能,基本上是想替代“logging.getLogger”这个调用。

1 个回答

1

我最后自己解决了这个问题。下面是代码:

global IS_SETUP 
IS_SETUP = False
def setuplogger(filename = 'python.log', directory = None, format = 'L:%(name)s M:%(module)s T:%(asctime)s > %(levelname)s: %(message)s'):
   global IS_SETUP
   if directory == None:
      fd, fname = tempfile.mkstemp()
      directory = os.path.dirname(fname)

   logging.basicConfig(filename = directory + '/' + filename, format = format)
   IS_SETUP = True

def getlog(logname, level = logging.INFO):
   '''returns a logger with logname that will print to filename and directoryname.'''
   if IS_SETUP == False:
      setuplogger()

   mylog = logging.getLogger(logname)

   mylog.setLevel(level)
   mylog.info('NEW LOGGER STARTED')
   return mylog

这样就避免了重复配置。而且,听说基本配置即使被调用多次也能正常工作。

如果有人知道怎么查看一个日志对象上有哪些处理程序,我还是很想知道。感觉这几乎是不可能的事情。

撰写回答