python-daemon 和 logging:交互设置日志级别
python-daemon and logging: set logging level interactively
我有一个 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"
我认为我可能没有正确地处理这个问题,但是,我不清楚什么会更好。任何意见,将不胜感激。
您在守护程序中创建的记录器将与您在 ipython 中创建的记录器不同。您可以通过打印出两个记录器对象本身来对此进行测试以确保这一点,这将向您显示它们的内存地址。
我认为更好的模式是,当你 运行 守护程序时,你是否想进入 "debug" 模式。换句话说,像这样调用 popen:
subprocess.Popen( ["python" , "daemon_script.py", "debug"] )
这取决于你,你可以像上面那样传递一个表示 "debug mode is on" 的字符串,或者你可以传递表示 "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)
...
我有一个 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"
我认为我可能没有正确地处理这个问题,但是,我不清楚什么会更好。任何意见,将不胜感激。
您在守护程序中创建的记录器将与您在 ipython 中创建的记录器不同。您可以通过打印出两个记录器对象本身来对此进行测试以确保这一点,这将向您显示它们的内存地址。
我认为更好的模式是,当你 运行 守护程序时,你是否想进入 "debug" 模式。换句话说,像这样调用 popen:
subprocess.Popen( ["python" , "daemon_script.py", "debug"] )
这取决于你,你可以像上面那样传递一个表示 "debug mode is on" 的字符串,或者你可以传递表示 "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)
...