你怎么知道 syslog-ng 是不是停止了你的监听守护进程?
Posted
技术标签:
【中文标题】你怎么知道 syslog-ng 是不是停止了你的监听守护进程?【英文标题】:How do you know if syslog-ng stops your listening daemon?你怎么知道 syslog-ng 是否停止了你的监听守护进程? 【发布时间】:2009-10-30 18:27:28 【问题描述】:我编写了一个挂钩到syslog-ng
(通过syslog-ng.conf
)的php程序,基本上是这样的:
while (!feof(STDIN))
$input = fgets(STDIN);
process($input);
cleanup();
process()
和 cleanup()
由我定义。
我面临的问题是 cleanup(2)
从未被调用,我需要在程序退出之前执行它。
我尝试使用pcntl_signal()
捕获 SIGTERM、SIGHUP 和 SIGPIPE,并且应用程序的这一部分似乎工作正常(如果我在 PHP 进程上使用 kill -1,我的信号处理程序被调用并运行 cleanup()
),但似乎我没有从 syslog-ng 收到这些消息。
我尝试将 STDIN 设置为非阻塞,认为 PHP 不会调用信号处理程序,因为流是阻塞的。那也不起作用,我的信号处理程序不会被调用。
我如何知道 syslog-ng 何时将停止我的应用程序,以便我进行一些清理工作?
谢谢, 汤姆
更新:我已尝试捕获从 1 到 31 的所有信号,但当 syslog-ng 重新启动(或被 SIGTERM 杀死)时,它仍然没有收到任何信号。
【问题讨论】:
重新标记,这与信号处理无关(与信号处理领域无关,与处理OS信号有关)。 这可能是一个愚蠢的问题,但是您是否尝试过将清理注册为关闭功能? us.php.net/manual/en/function.register-shutdown-function.php 编辑汤姆。很高兴它对你有用! 【参考方案1】:也许尝试将cleanup()
注册为PHP shutdown function,如下所示:
function cleanup()
register_shutdown_function("cleanup");
理论上这会导致 php 在退出之前执行函数。但是,当与强制停止选项(如 kill)一起使用时,这可能不起作用,所以它(又一个)是在黑暗中拍摄的。
我希望你能找到一些有用的东西。我也有兴趣了解结果。
编辑:我很高兴这对你有用!
【讨论】:
我想你的意思是register_shutdown_function('cleanup');
这是一个很酷的功能,感谢您指出这一点!
我不小心对你投了反对票。对不起,你的回答是正确的。尝试编辑它,以便我可以撤销投票。
请查看此答案上的日期。我不再使用 php 并且多年来它发生了很大变化。请随时提交对符合当今要求的答案的修改。【参考方案2】:
这是在黑暗中拍摄的,但请尝试如下重写循环:
do
$input = fgets(STDIN);
process( $input );
while ( !feof( STDIN ) )
cleanup();
这个想法是当 syslog-ng 关闭标准输出时(假设它关闭了?),fgets 将尝试读取并实际到达 EOF。
【讨论】:
在提到的情况下,您的逻辑不是更适合 do while() 吗? 我可能还会在 fgets 调用周围添加一个 if,因为 fgets 在失败时返回 falseif( ( $input = fgets(STDIN); ) === FALSE ) break;
feof 不应该在 do/while 中使用,因为 feof 需要在 从文件中读取之前进行检查。空文件在 fopen 时位于 EOF。 $ touch testfile $ ls -l testfile -rw-r--r-- 1 clint staff 0 Nov 9 08:43 testfile $ php -r '$x = fopen("testfile", "r"); var_dump($x); $y = feof($x); var_dump($y);'类型(流)bool(假)的资源(5)
这是真的,但是在这种情况下 fgets 也应该返回 false。【参考方案3】:
在没有适当清理的情况下突然终止 PHP 脚本可能是因为发生了运行时错误(例如,因为您的 process() 尚未准备好处理 fgets() 在到达 EOF 时返回的空字符串)。
启用 PHP 错误日志以查看发生了什么。
【讨论】:
【参考方案4】:我能想到几件事你可以尝试解决这个问题:
1) 使用 PHP 的set_error_handler() function。
2) 将上面提到的代码放在一个 try/catch 结构中,以尝试捕获任何可能抛出的异常。
3) 当您运行该脚本时,请确保您正在捕获输出和标准错误。将命令行更改为:
/path/to/script 2>&1 >> /path/to/logfile.txt
...这将帮助您发现错误。
最后,如果确实是 PHP 无法捕获信号的情况,则必须通过带有 trap 命令的 shell 脚本来执行此操作。比如:
#!/bin/sh
#
# This gets run when the script is hit with a signal
#
trap /path/to/script --cleanup
#
# Run our script
#
/path/to/script 2>&1 >> /path/to/logfile.txt
如果脚本中有 cleanup() 需要的特定数据,那么您必须了解如何序列化数据并将其写入磁盘以供清理脚本读取。
祝你好运!
【讨论】:
在处理 SIGTERM 时仍然没有帮助,抱歉。【参考方案5】:PHP 是否会为您精心处理您的信号?尝试使用您可以更好地控制的另一种语言进行原型设计。
【讨论】:
以上是关于你怎么知道 syslog-ng 是不是停止了你的监听守护进程?的主要内容,如果未能解决你的问题,请参考以下文章
作为 IT 从业人员,你觉得有啥工具大大提高了你的工作效率?