简体   繁体   中英

How do you know if syslog-ng stops your listening daemon?

I wrote a PHP program that hooks into syslog-ng (via syslog-ng.conf ) and it's basically this:

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

where process() and cleanup() are defined by me.

The problem I am facing is that cleanup(2) is never called and I need it to be executed before the program exits.

I have tried to catch SIGTERM, SIGHUP and SIGPIPE using pcntl_signal() and that part of the application seems to work fine (if I use kill -1 on the PHP process, my signal handler gets called and it runs cleanup() ), but it appears that I am not getting those meessages from syslog-ng.

I have tried setting STDIN to non-blocking, thinking that PHP wouldn't call the signal handlers because the stream was blocking. That didn't work either, my signal handlers wouldn't get called.

How do I know when syslog-ng is about to stop my application, so I can do some cleanup?

Thanks, Tom

I've tried to catch all the signals, from 1 to 31 and it still doesn't receive anything when syslog-ng is restarted (or killed with SIGTERM). 我试图捕获所有信号,从1到31,当syslog-ng重新启动(或使用SIGTERM杀死)时仍然没有收到任何信号。

Perhaps try to register cleanup() as a PHP shutdown function , like so:

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

In theory this will cause php to execute the function prior to exiting. This may not work when used with forced halt options (like kill) though, so it's (yet another) shot in the dark.

I hope you find something that works though. I'd be interested in learning the results as well.

Edit: I'm glad this worked out for you!

This is a shot in the dark, but try re-writing your loop as follows:

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

The idea being that when syslog-ng closes stdout (assuming it does?), fgets will attempt to read and actually reach EOF.

Abrupt termination of your PHP script without proper cleanup is probably because a runtime error happens (for example, because your process() is not ready to handle an empty string returned by by fgets() when it reaches EOF).

Enable PHP error logging to see what happens.

I can think of a couple of things you can try to troubleshoot this:

1) Make use of PHP's set_error_handler() function .

2) Put the code mentioned above in a try/catch structure, to try and catch any exceptions that might be thrown.

3) When you run that script, make sure you are capturing both the output and standard error. Change the command line to be something like:

/path/to/script 2>&1 >> /path/to/logfile.txt

...that will help you catch errors.

Finally, if it really is a case where PHP isn't able to catch signals, you'll have to do this through a shell script with the trap command. Something like:

#!/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

If there's specific data in the script that cleanup() needs, then you'll have to see about serializing the data and writing it to disk for the cleanup script to read.

Good luck!

Does PHP thoughtfully handle your signals for you? Try prototyping in another language that you have more control.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM