在 Debian 上,当我询问服务状态时,它只打印出几行:
sudo service tor status
CPU: 3ms
Dec 15 17:57:27 systemd[1]: Starting tor.service - Anonymizing overlay network for TCP (multi-instance-master)...
Dec 15 17:57:27 systemd[1]: Finished tor.service - Anonymizing overlay network for TCP (multi-instance-master).
sudo journalctl -u tor.service
还有一点点
Dec 15 17:57:27 systemd[1]: Stopped tor.service - Anonymizing overlay network for TCP (multi-instance-master).
Dec 15 17:57:27 systemd[1]: Stopping tor.service - Anonymizing overlay network for TCP (multi-instance-master)...
Dec 15 17:57:27 systemd[1]: Starting tor.service - Anonymizing overlay network for TCP (multi-instance-master)...
Dec 15 17:57:27 systemd[1]: Finished tor.service - Anonymizing overlay network for TCP (multi-instance-master).
但仍然不是整个输出。出于同样的原因,我不得不调用
python3 -u test.py
在服务文件中,否则它只会在第一行停留数小时。
没有输出就无法调试。当然,当我在 systemd 之外手动调用命令时,命令是有效的。
我怎样才能使其更加实时?或者在合理的时间内打印所有输出?
答案1
不是有定期冲洗吗?
就时间而言,不是周期性的。这需要程序中有一个单独的线程执行定期刷新,或者语言运行时接管程序可以自己使用的计时器信号等。这是可以做到的,特别是如果运行时已经管理线程的话,但我认为我还没有在实践中看到过这样做。
因此,刷新总是每 X 次进行一次字节,缓冲区通常约为 8kB;或者换句话说,输出仅作为 fwrite() 处理程序的一部分刷新。如果没有更多写入,则输出可能永远不会被刷新。
我怎样才能使其更加实时?或者在合理的时间内打印所有输出?
由于它是由语言运行时缓冲的,因此没有完全通用的方法从外部删除该缓冲(除了stdbuf -o0
libc 缓冲,以及为程序的 stdout 创建 pty 的丑陋解决方法)。
但是大多数运行时都提供了一种方法来控制这一点,作为程序的一部分——例如,在最近的 Python 中,你可以sys.stdout.reconfigure(line_buffering=True)
在 C 中使用 while ,而你在调用setlinebuf(stdout)
。大多数运行时也不会将此缓冲应用于 stderr——即使输出进入管道,它仍保持行缓冲。
换句话说,如果程序员选择将重要信息记录到 stdout,那么程序员就有责任调整缓冲或者在每条消息之后明确刷新 stdout...或者写入 stderr 而不是 stdout。
事实上,大多数服务不仅仅记录到 stdout,它们还记录到系统日志(例如使用 python 的syslog.syslog()
),这可能是一个更好的选择,因为它允许您指定用户可以过滤的消息优先级(在“调试”和“关键”之间),而不是所有内容都是平坦的文本。