在不重新启动应用程序的情况下动态更改python中的日志级别

ope*_*eek 55 python logging gevent

是否可以在python中使用fileConfig更改日志级别而无需重新启动应用程序.如果无法通过fileConfig实现,还有其他方法可以获得相同的结果吗?

更新:这是针对在服务器上运行的应用程序,我希望系统管理员能够更改应用程序在运行时选择的配置文件,并动态更改日志级别.我当时正在使用gevent,因此我添加了我的代码作为使用inotify选择配置文件更改的答案之一.

Mar*_*ers 99

fileConfig是一种基于文件为您配置日志级别的机制; 您可以在程序中随时动态更改它.

调用.setLevel()要更改日志级别的日志记录对象.通常你会在root上做到这一点:

logging.getLogger().setLevel(logging.DEBUG)
Run Code Online (Sandbox Code Playgroud)


sfi*_*ens 14

除了接受的答案:根据您初始化记录器的方式,您可能还需要更新记录器的处理程序:

import logging

level = logging.DEBUG
logger = logging.getLogger()
logger.setLevel(level)
for handler in logger.handlers:
    handler.setLevel(level)
Run Code Online (Sandbox Code Playgroud)

  • 有用:如果您使用 dictConfig 来指定记录器、处理程序等,并且您只想在一个特定处理程序上设置级别,则可以在@sfinkens 所示的循环中使用 .get_name() 函数,然后进行确保您只更改您想要的级别。 (2认同)
  • 为什么处理程序需要有日志级别?此外,为什么它们的级别可以独立于拥有它们的记录器来设置?这是非常令人困惑和糟糕的设计。 (2认同)
  • @CodeKid如果您想在调试级别登录到文件,但在不同级别登录到控制台怎么办?您不会附加两个不同级别的处理程序吗? (2认同)

小智 9

扩展sfinken 的 answer和 Starman 的后续评论,您还可以检查处理程序的类型以针对特定输出器 - 例如:

import logging
logger = logging.getLogger()
for handler in logger.handlers:
    if isinstance(handler, type(logging.StreamHandler())):
        handler.setLevel(logging.DEBUG)
        logger.debug('Debug logging enabled')
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你!一个小建议:`isinstance(handler,logging.StreamHandler)` (3认同)

Rol*_*Max 6

这可能是您正在寻找的:

import logging
logging.getLogger().setLevel(logging.INFO)
Run Code Online (Sandbox Code Playgroud)

请注意,getLogger()不带任何参数调用会返回根记录器。


Vin*_*jip 6

当然可以使用动态fileConfig()更改日志记录配置,但是对于简单的更改,Martijn Pieters的回答中建议的编程方法可能是合适的.Logging甚至提供了一个套接字服务器来使用listen()/ stopListening()API 监听配置更改,如此处所述.要使用日志来监听特定端口,请使用

t = logging.config.listen(PORT_NUMBER)
t.start()
Run Code Online (Sandbox Code Playgroud)

并停止听,打电话

logging.config.stopListening()
Run Code Online (Sandbox Code Playgroud)

要将数据发送到服务器,您可以使用例如

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', PORT_NUMBER))
with open(CONFIG_FILE) as f:
    data_to_send = f.read()
s.send(struct.pack('>L', len(data_to_send)))
s.send(data_to_send)
s.close()
Run Code Online (Sandbox Code Playgroud)

更新:由于向后兼容性约束,fileConfig()调用的内部实现意味着您无法disable_existing_loggers=False在调用中指定,这使得此功能在某些情况下不太有用.您可以使用相同的API使用dictConfig架构发送JSON文件,这样可以更好地控制重新配置.这需要Python 2.7/3.2或更高版本(dictConfig()已添加).或者,您可以使用stdlib代码来实现您自己的侦听器,该侦听器以相同的方式工作,但是根据您的特定需求进行定制.