调试:控制台输出和 Upstart 脚本

调试:控制台输出和 Upstart 脚本

如何将 upstart 脚本的输出发送到终端以查找 python 代码中的回溯?没有回溯,我花了很长时间才完成以前只需一秒钟的事情。我不得不进行几次文件写入调用来追踪错误。以前使用回溯查找只需几秒钟,现在变成了几分钟。这太糟糕了。这种情况已经持续了几个星期,我受够了。有人能不能说说这个。我觉得我又在使用没有调试器的汇编语言了。

答案1

如果你使用 Upstart 1.4 或更新版本,将其放入console log你的 Upstart 作业中,所有到 stdout/stderr 的输出将最终为/var/log/upstart/<job>.log。然后你可以执行tail -f /var/log/upstart/<job>.log &操作让输出出现在终端中。

答案2

有一整节关于调试技术的内容新贵食谱。您可以做的最简单的事情就是添加--debug到内核参数中,这将增加 upstart 的详细程度并将所有内容转储到 syslog。是的,调试很复杂,它反映了创建并行化 init 系统所需的净复杂性。我相信还有改进的空间。

答案3

当我编写 Python 守护程序时,我会捕获所有异常并将其抛出到日志文件。我不仅将其用于调试,还将其用于生产。我有一个每天早上运行的小脚本,用于在日志中查找令人不安的事情。

当然,它也有助于保持守护进程运行。

一些示例代码(我删除了不感兴趣的部分):

import logging

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(levelname)s %(message)s',
                    filename=LOG_FILE,
                    filemode='w')
    logging.info("Sincrod inicializado")
    if not DEBUG:
        daemonize()
    while True:
        try:
            actua()
        except:
            logging.error(sys.exc_info())
        if (datetime.datetime.now().hour > NOITE_EMPEZA\
         and datetime.datetime.now().hour < NOITE_REMATA):
            time.sleep(INTERVALO_NOITE)
        else:
            time.sleep(INTERVALO_DIA)

其中 actua() 是真正的守护进程(它也会写入日志)。请注意,我在设置文件中还有一个 DEBUG 变量,当它为 True 时,我不会分叉守护进程,因此它会在控制台上执行。

守护进程

守护进程是 UNIX 中相当于 Windows 服务的进程。它们是独立于其他进程在后台运行的进程。这意味着它们的父进程通常是 init,并且它们与任何 tty 分离。由于它们是独立的,因此没有预定义的位置来放置它们的输出。

有很多 Python 库和代码片段可以创建守护进程,在上面的例子中,我使用了我自己的函数,它结合了 Steinar Knutsens 和 Jeff Kunces 版本的一些想法。它尽可能简单,请注意我分叉了两次

def daemonize():
    """Forks this process creating a daemon and killing the original one"""
    if (not os.fork()):
        # get our own session and fixup std[in,out,err]
        os.setsid()
        sys.stdin.close()
        sys.stdout = NullDevice()
        sys.stderr = NullDevice()
        if (not os.fork()):
            # hang around till adopted by init
            ppid = os.getppid()
            while (ppid != 1):
                time.sleep(0.5)
                ppid = os.getppid()
        else:
            # time for child to die
            os._exit(0)
    else:
        # wait for child to die and then bail
        os.wait()
        sys.exit()

相关内容