你怎么知道 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 在失败时返回 false if( ( $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 是不是停止了你的监听守护进程?的主要内容,如果未能解决你的问题,请参考以下文章

NLP悦读 | 停止评判,能量就提升了

作为 IT 从业人员,你觉得有啥工具大大提高了你的工作效率?

password啥意思

你不逼自己一把,永远不知道自己多优秀,别让懒癌搁浅了你的梦想!

不同的SHA1键(Android)

NLP:停止评判别人,你的能量就提升了