【问题标题】:python-daemon and logging: set logging level interactivelypython-daemon 和日志记录:以交互方式设置日志记录级别
【发布时间】:2018-08-05 20:49:03
【问题描述】:

我有一个 python-daemon 进程,它通过 ThreadedTCPServer 记录到一个文件(受食谱示例的启发:https://docs.python.org/2/howto/logging-cookbook.html#sending-and-receiving-logging-events-across-a-network,因为我将有许多这样的进程写入同一个文件)。我正在使用 ipython 控制台中的 subprocess.Popen 控制守护进程的生成,这就是应用程序的运行方式。我能够从主 ipython 进程和守护进程成功写入日志文件,但我无法通过简单地设置 ipython 中的根记录器的级别来更改两者的级别。这应该是可能的吗?还是需要自定义功能来单独设置守护进程的 logging.level?

编辑:根据要求,这里尝试提供一个伪代码示例来说明我想要实现的目标。我希望这是一个足够的描述。

daemon_script.py

import logging
import daemon 
from other_module import function_to_run_as_daemon

class daemon(object):
    def __init__(self):
         self.daemon_name = __name__
         logging.basicConfig()  # <--- required, or I don't get any log messages
         self.logger = logging.getLogger(self.daemon_name)
         self.logger.debug( "Created logger successfully" )

    def run(self):
        with daemon.daemonContext( files_preserve = [self.logger.handlers[0].stream] )
            self.logger.debug( "Daemonised successfully - about to enter function" )
            function_to_run_as_daemon()

if __name__ == "__main__":
    d = daemon()
    d.run()

然后在 ipython 中我会运行类似的东西

>>> import logging
>>> rootlogger = logging.getLogger()
>>> rootlogger.info( "test" )
INFO:root:"test"
>>> subprocess.Popen( ["python" , "daemon_script.py"] )
DEBUG:__main__:"Created logger successfully"
DEBUG:__main__:"Daemonised successfully - about to enter function"
# now i'm finished debugging and testing, i want to reduce the level for all the loggers by changing the level of the handler
# Note that I also tried changing the level of the root handler, but saw no change
>>> rootlogger.handlers[0].setLevel(logging.INFO)
>>> rootlogger.info( "test" )
INFO:root:"test"
>>> print( rootlogger.debug("test") )
None
>>> subprocess.Popen( ["python" , "daemon_script.py"] )
DEBUG:__main__:"Created logger successfully"
DEBUG:__main__:"Daemonised successfully - about to enter function"

我认为我可能没有正确处理这个问题,但是我不清楚什么会更好。任何意见,将不胜感激。

【问题讨论】:

  • 你好@bazza1988,欢迎来到stackoverflow,没有一个具体、简洁和最小的代码示例来展示你的问题,很难判断你的问题可能是什么。
  • @zmo - 见编辑。我原本希望我的描述足以得到定性的答案。如果您需要更多信息,请告诉我。

标签: python logging python-daemon


【解决方案1】:

您在守护程序中创建的记录器与您在 ipython 中创建的记录器不同。您可以通过打印出两个记录器对象本身来确定这一点,这将显示它们的内存地址。

我认为更好的模式是在运行守护程序时通过是否要处于“调试”模式。换句话说,像这样调用 popen:

subprocess.Popen( ["python" , "daemon_script.py", "debug"] )

这取决于你,你可以像上面一样传递一个表示“调试模式已开启”的字符串,或者你可以传递一个表示“调试”的日志级别常量,例如: subprocess.Popen( ["python" , "daemon_script.py", "10"] ) (https://docs.python.org/2/library/logging.html#levels)

然后在守护进程的 init 函数中使用 argv 来获取该参数并使用它:

...
import sys

def __init__(self):
     self.daemon_name = __name__
     logging.basicConfig()  # <--- required, or I don't get any log messages
     log_level = int(sys.argv[1])  # Probably don't actually just blindly convert it without error handling
     self.logger = logging.getLogger(self.daemon_name)
     self.logger.setLevel(log_level)
     ...

【讨论】:

  • 谢谢!有趣的是你提到了内存地址比较,我刚刚做了那个测试,当然,你是对的。但是,关于您的解决方案;守护进程将是一个长时间运行的进程,此时用户可能希望在不重新启动该程序的情况下更改级别。根据您的建议,我似乎需要实施一种方法来专门告诉守护程序更改级别 - 您同意吗? (这是我在最初的问题中提到的,但我问了这个问题,看看我是否遗漏了一些简单的东西)
  • @bazza1988 是的,肯定公开一个函数来改变它会起作用。我不确定你什么时候需要改变关卡。例如,如果您总是想看到该消息,那么我很难想到您不能简单地使用信息级别来记录“我已正确启动”。然后使用调试级别进行真正的调试。然后,如果您遇到问题,请在调试级别运行,否则在信息级别运行。
  • 或者,如果不是子进程,而是将守护进程放入模块并将其导入 ipython,则可以传递实际的记录器并按照您实际考虑的方式更改其日志级别。然后在守护进程中,您可以使用其他解决方案让 IT 在其他线程或子进程上生成工作人员。
猜你喜欢
  • 2016-11-27
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2016-02-20
  • 2020-11-19
  • 1970-01-01
  • 2023-03-24
  • 2011-07-26
相关资源
最近更新 更多