Как узнать, останавливает ли syslog-ng ваш демон прослушивания? - PullRequest
3 голосов
/ 30 октября 2009

Я написал программу PHP, которая подключается к syslog-ng (через syslog-ng.conf), и это в основном это:

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

, где process() и cleanup() определены мной.

Проблема, с которой я сталкиваюсь, заключается в том, что cleanup(2) никогда не вызывается, и мне нужно, чтобы он был выполнен до выхода из программы.

Я пытался перехватить SIGTERM, SIGHUP и SIGPIPE, используя pcntl_signal(), и эта часть приложения, кажется, работает нормально (если я использую kill -1 в процессе PHP, мой обработчик сигнала вызывается и запускается cleanup() ), но, похоже, я не получаю эти сообщения от syslog-ng.

Я попытался настроить STDIN на неблокирование, думая, что PHP не будет вызывать обработчики сигналов, потому что поток блокируется. Это тоже не сработало, мои обработчики сигналов не были бы вызваны.

Как узнать, когда syslog-ng собирается остановить мое приложение, чтобы я мог выполнить некоторую очистку?

Спасибо, Том

ОБНОВЛЕНИЕ: Я пытался перехватить все сигналы от 1 до 31, и он все еще не получает ничего, когда syslog-ng перезапускается (или уничтожается с помощью SIGTERM).

Ответы [ 5 ]

4 голосов
/ 05 ноября 2009

Возможно, попробуйте зарегистрировать cleanup() как PHP функцию выключения , например:

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

Теоретически это заставит php выполнить функцию до выхода. Это может не работать при использовании с параметрами принудительной остановки (например, kill), так что это (еще один) выстрел в темноте.

Я надеюсь, что вы найдете что-то, что работает, хотя. Мне было бы интересно узнать и результаты.

Редактировать: Я рад, что это сработало для вас!

0 голосов
/ 08 ноября 2009

PHP тщательно обрабатывает ваши сигналы для вас? Попробуйте создать прототип на другом языке, которым вы больше владеете.

0 голосов
/ 08 ноября 2009

Я могу вспомнить пару вещей, которые вы можете попытаться устранить, это:

1) Используйте функцию PHP set_error_handler () .

2) Поместите упомянутый выше код в структуру try / catch, чтобы попытаться перехватить любые исключения, которые могут быть сгенерированы.

3) Когда вы запускаете этот скрипт, убедитесь, что вы фиксируете как вывод, так и стандартную ошибку. Измените командную строку на что-то вроде:

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

... это поможет вам поймать ошибки.

Наконец, если это действительно тот случай, когда PHP не может перехватывать сигналы, вам придется сделать это с помощью сценария оболочки с помощью команды trap. Что-то вроде:

#!/bin/sh<br> #<br> # This gets run when the script is hit with a signal<br> #<br> trap /path/to/script --cleanup<br> #<br> # Run our script<br> #<br> /path/to/script 2>&1 >> /path/to/logfile.txt </p> <p>

Если в скрипте есть определенные данные, которые нужны для cleanup (), вам нужно будет узнать о сериализации данных и их записи на диск, чтобы скрипт очистки мог их прочитать.

Удачи!

0 голосов
/ 06 ноября 2009

Резкое завершение вашего PHP-скрипта без надлежащей очистки, возможно, из-за ошибки во время выполнения (например, из-за того, что ваш процесс () не готов обработать пустую строку, возвращаемую функцией fgets () при достижении EOF).

Включите ведение журнала ошибок PHP, чтобы увидеть, что происходит.

0 голосов
/ 04 ноября 2009

Это выстрел в темноте, но попробуйте переписать ваш цикл следующим образом:

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

Идея состоит в том, что когда syslog-ng закрывает стандартный вывод (предполагая, что это так?), Fgets попытается прочитать и фактически достигнет EOF.

...