3

syslog-ng我编写了一个与(via )挂钩的 PHP 程序,syslog-ng.conf它基本上是这样的:

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

在哪里process()cleanup()由我定义。

我面临的问题是它cleanup(2)永远不会被调用,我需要在程序退出之前执行它。

我试图使用 SIGTERM、SIGHUP 和 SIGPIPE 来捕获 SIGTERM、SIGHUP 和 SIGPIPE,pcntl_signal()并且该应用程序的这一部分似乎工作正常(如果我在 PHP 进程上使用 kill -1,我的信号处理程序被调用并运行cleanup()),但似乎我不是从 syslog-ng 获取这些消息。

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

我如何知道 syslog-ng 何时将停止我的应用程序,以便进行一些清理工作?

谢谢,汤姆

更新:我试图捕捉从 1 到 31 的所有信号,但当 syslog-ng 重新启动(或被 SIGTERM 杀死)时,它仍然没有收到任何信号。

4

5 回答 5

4

也许尝试注册cleanup()为 PHP关闭函数,如下所示:

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

从理论上讲,这将导致 php 在退出之前执行该函数。但是,当与强制停止选项(如 kill)一起使用时,这可能不起作用,所以它(又一个)是在黑暗中拍摄的。

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

编辑:我很高兴这对你有用!

于 2009-11-05T05:11:35.900 回答
0

这是在黑暗中拍摄的,但请尝试按如下方式重新编写循环:

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

这个想法是当 syslog-ng 关闭标准输出时(假设它关闭了?),fgets 将尝试读取并实际到达 EOF。

于 2009-11-04T02:27:30.230 回答
0

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

启用 PHP 错误日志以查看发生了什么。

于 2009-11-06T00:00:19.753 回答
0

我可以想到几件事你可以尝试解决这个问题:

1) 利用 PHP 的set_error_handler() 函数

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() 需要的特定数据,那么您必须了解如何序列化数据并将其写入磁盘以供清理脚本读取。

祝你好运!

于 2009-11-08T02:50:25.793 回答
0

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

于 2009-11-08T02:55:18.467 回答