Фильтр потокового журналирования для PHP? - PullRequest
4 голосов
/ 06 марта 2012

Мне нужно отладить сокетное соединение, которое мой PHP-интерфейс выполняет с бэкэнд-сервисом на другом хосте, и мне нужно сделать это как можно ближе к металлу .Я уже абстрагировал соединение на разных уровнях, что, помимо прочего, дает мне возможность легко подключать потоковые фильтры к соединению.Таким образом, проблему должно быть очень легко решить: упаковать потоковый фильтр в класс, который позволяет выполнять произвольные обратные вызовы при отправке или получении данных, а затем, например, добавить их в пару файлов журнала.

Единственная проблема заключается в том, что мое (наивное?) Ожидание, что должна быть какая-то такая реализация фильтра, плавающая в сети, кажется неправильным!Я сам не против написать фильтр, но, может быть, есть что-то доступное, что мне просто не удалось найти?

Для справки, я сделал в Google много очевидных вариаций "фильтра потока журналирования php".

Обновление: Чтобы уточнить, что я ищу, это то, что позволило бы мне написать код, морально эквивалентный этому:

$params = array(
    'onDataSent' => function($data) { echo "Sent: $data\n"; },
    'onDataReceived' => function($data) { echo "Received: $data\n"; },
);

stream_filter_register('logging', 'HookableStreamFilter');
stream_filter_append($someStream, 'logging', STREAM_FILTER_ALL, $params);

1 Ответ

1 голос
/ 13 марта 2012

Для потомков вот что я закончил, взбив. Сам фильтр происходит от php_user_filter, который описан в документации для stream_filter_register:

class HookableFilter extends php_user_filter {
    public function filter($in, $out, &$consumed, $closing) {
        $data = '';

        while ($bucket = stream_bucket_make_writeable($in)) {
            $consumed += $bucket->datalen;
            $data .= $bucket->data;
            stream_bucket_append($out, $bucket);
        }

        call_user_func($this->params, $data);
        return PSFS_PASS_ON;
    }
}

Обратите внимание, что я использую непосредственно $this->params в качестве обратного вызова, что делает эту функцию действительно спартанской (есть причина; см. Ниже).

Регистрация фильтра с помощью PHP:

stream_filter_register('generic.hookable', 'HookableFilter');

Присоединение фильтра к потоку:

$callback = function($data) { /* log the data */ };
stream_filter_append($stream, 'generic.hookable', STREAM_FILTER_READ, $callback);
stream_filter_append($stream, 'generic.hookable', STREAM_FILTER_WRITE, $callback);

Важно: Насколько я мог видеть, если вы подключите фильтр к обоим каналам дуплексного потока (например, один, созданный с помощью stream_socket_client) у вашего фильтра нет возможности узнать, на каком канале он работает, когда он вызывается . Поэтому, если вам необходимо различать входящие и исходящие данные, как я, единственный вариант - прикрепить фильтр отдельно к каждому каналу. Если вы это сделаете, вы также наверняка захотите предоставить разные обратные вызовы для каждого канала (не так, как в упрощенном примере выше).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...