你怎么知道syslog-ng是否会停止你的监听守护进程?

时间:2009-10-30 18:27:28

标签: php linux syslog syslog-ng

我编写了一个挂钩到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,我的信号处理程序被调用并运行{ {1}}),但似乎我没有从syslog-ng获得这些消息。

我已经尝试将STDIN设置为非阻塞,认为PHP不会调用信号处理程序,因为流阻塞了。这也不起作用,我的信号处理程序不会被调用。

我怎么知道syslog-ng何时会停止我的应用程序,所以我可以做一些清理工作?

谢谢, 汤姆

更新:我试图捕获所有信号,从1到31,当syslog-ng重新启动(或使用SIGTERM终止)时,它仍然没有收到任何信息。

5 个答案:

答案 0 :(得分:4)

也许尝试将cleanup()注册为PHP shutdown function,如下所示:

function cleanup(){}
register_shutdown_function("cleanup");

理论上,这将导致php在退出之前执行该功能。当使用强制暂停选项(如杀戮)时,这可能不起作用,所以它是(又一次)在黑暗中拍摄。

我希望你找到一些有用的东西。我也有兴趣了解结果。

编辑:我很高兴为你效劳!

答案 1 :(得分:0)

这是一个黑暗中的镜头,但尝试按如下方式重写你的循环:

do {
   $input = fgets(STDIN);
   process( $input );
while ( !feof( STDIN ) ) {
cleanup();

当syslog-ng关闭stdout(假设确实如此?)时,fgets会尝试读取并实际达到EOF。

答案 2 :(得分:0)

在没有正确清理的情况下突然终止你的PHP脚本可能是因为发生了运行时错误(例如,因为你的process()还没有准备好处理fgets()在达到EOF时返回的空字符串。) p>

启用PHP错误记录以查看会发生什么。

答案 3 :(得分:0)

我可以想到一些你可以尝试解决这个问题的事情:

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(),那么你必须看到有关序列化数据并将其写入磁盘以便清理脚本的信息。

祝你好运!

答案 4 :(得分:0)

PHP是否为您精心处理您的信号?尝试使用您可以更好控制的另一种语言进行原型设计。