24

考虑这段代码:

import logging
print "print"
logging.error("log")

我得到:

print
ERROR:root:log

现在,如果我在前面代码的开头包含一个第三方模块并重新运行它,我只会得到:

print

之前有一些关于此的问题,但在这里我无法触摸我正在导入的模块。

第三方模块的代码在这里:http ://atlas-sw.cern.ch/cgi-bin/viewcvs-atlas.cgi/offline/DataManagement/DQ2/dq2.clientapi/lib/dq2/clientapi/DQ2 .py?view=markup,但我的问题更笼统:独立于我要导入的模块,我希望以logging预期的方式进行干净的工作

一些(非工作)建议的解决方案:

from dq2.clientapi.DQ2 import DQ2
import logging
del logging.root.handlers[:]

from dq2.clientapi.DQ2 import DQ2
import logging
logging.disable(logging.NOTSET)

logs = logging.getLogger('root')
logs.error("Some error")

下一个有效,但产生了一些额外的错误:

from dq2.clientapi.DQ2 import DQ2
import logging
reload(logging)

我得到:

print
ERROR:root:log
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/afs/cern.ch/sw/lcg/external/Python/2.6.5/x86_64-slc5-gcc43-    opt/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "/afs/cern.ch/sw/lcg/external/Python/2.6.5/x86_64-slc5-gcc43-opt/lib/python2.6/logging/__init__.py", line 1509, in shutdown
    h.close()
  File "/afs/cern.ch/sw/lcg/external/Python/2.6.5/x86_64-slc5-gcc43-opt/lib/python2.6/logging/__init__.py", line 705, in close
    del _handlers[self]
KeyError: <logging.StreamHandler instance at 0x2aea031f7248>
Error in sys.exitfunc:
Traceback (most recent call last):
  File "/afs/cern.ch/sw/lcg/external/Python/2.6.5/x86_64-slc5-gcc43-opt/lib/python2.6/atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "/afs/cern.ch/sw/lcg/external/Python/2.6.5/x86_64-slc5-gcc43-opt/lib/python2.6/logging/__init__.py", line 1509, in shutdown
    h.close()
  File "/afs/cern.ch/sw/lcg/external/Python/2.6.5/x86_64-slc5-gcc43-opt/lib/python2.6/logging/__init__.py", line 705, in close
    del _handlers[self]
KeyError: <logging.StreamHandler instance at 0x2aea031f7248>

from dq2.clientapi.DQ2 import DQ2
import logging
logger = logging.getLogger(__name__)
ch = logging.StreamHandler()  
logger.addHandler(ch)
logger.error("log")
4

3 回答 3

26

这取决于其他模块在做什么;例如,如果它正在调用,logging.disable那么您可以调用logging.disable(logging.NOTSET)以重置它。

您可以尝试重新加载logging模块:

from importlib import reload
logging.shutdown()
reload(logging)

问题是这会使带有自己副本的第三方模块logging处于不可用状态,因此以后可能会导致更多问题。

于 2012-08-20T08:57:42.523 回答
15

要从根记录器中完全清除现有的日志记录配置,这可能有效:

root = logging.getLogger()
list(map(root.removeHandler, root.handlers))
list(map(root.removeFilter, root.filters))

但是,这不会重置为“默认”,这会清除所有内容。然后你必须添加一个StreamHandler来实现你想要的。

于 2013-06-06T16:08:45.640 回答
4

一个更完整的解决方案,不会使任何记录器失效。应该可以工作,除非某些模块做了一些奇怪的事情,比如持有对过滤器或处理程序的引用。

def reset_logging():
    manager = logging.root.manager
    manager.disabled = logging.NOTSET
    for logger in manager.loggerDict.values():
        if isinstance(logger, logging.Logger):
            logger.setLevel(logging.NOTSET)
            logger.propagate = True
            logger.disabled = False
            logger.filters.clear()
            handlers = logger.handlers.copy()
            for handler in handlers:
                # Copied from `logging.shutdown`.
                try:
                    handler.acquire()
                    handler.flush()
                    handler.close()
                except (OSError, ValueError):
                    pass
                finally:
                    handler.release()
                logger.removeHandler(handler)

不用说,您必须在运行reset_logging()设置日志记录。

于 2019-06-28T16:50:06.643 回答