12

バックグラウンドで実行する必要があるphpプログラムを管理するためにsupervisordを使用しています。そのプログラムは、イベントをファイルに記録しますworker_logsupervisord.conf私が使用しているでこれを構成するのは簡単です:

stderr_logfile=/var/log/supervisord/worker_log;

ただし、ログに書き込まれるイベント自体にタイムスタンプを付けたいと思います。私はphpプログラムを制御できないため、ログを装飾することはできません。私は、上記のロギング構成をコメントアウトし、スーパーバイザーのコマンド構成でコマンドラインパイプを介してプログラムを装飾することだと考えました。

command=php /www/myapp/worker.php 2>&1 | sed "s/^/`date` /" > /var/log/supervisord/worker_log;

このコマンドを手動で実行すると、問題なく動作するようです。ただし、supervisord はどういうわけか適切に機能するのを妨げているようで、その方法がわかりません。worker.php正常に実行されますが、この構成ではレポートが抑制されます。そのため、もちろんタイムスタンプは追加されません。

ワーカーの出力にタイムスタンプを付けるという目標を達成する方法についてのガイダンスを提供するために、これについて十分に知っている人はいますか?

4

3 に答える 3

8

ワーカー コードを呼び出す前に、stderr にフィルターをアタッチする専用のラッパー スクリプトを作成できます。

// filter to prepend date/time on all stderr output
class eventdata_filter extends php_user_filter
{
    function filter($in, $out, &$consumed, $closing)
    {
        while (($bucket = stream_bucket_make_writeable($in))) {
            $bucket->data = date('c') . ' ' . $bucket->data;
            $consumed += $bucket->datalen;
            stream_bucket_append($out, $bucket);
        }
        return PSFS_PASS_ON;
    }
}

// register our custom filter    
stream_filter_register('eventdata', 'eventdata_filter');

// keep a reference to the attached filter
$filter = stream_filter_append(STDERR, 'eventdata', STREAM_FILTER_WRITE);

// isolate the worker from any variables in this scope, such as $filter
function run()
{
    include 'worker.php';
}

// run the worker
run();

// remove the filter
stream_filter_remove($filter);

ところで、フィルターを削除しないと、セグメンテーション違反が発生します (少なくとも、5.4 でテスト済み)。

于 2013-07-25T02:29:57.767 に答える
4

各行にタイムスタンプを付けるために別のコード層が必要であるという点で、以前の回答 (Jack から) は正しいです。この perl のワンライナーは同じ結果を達成します:

perl -ne '@timeparts=localtime(); printf("%04d/%02d/%02d %02d:%02d:%02d %s",$timeparts[5]+1900,$timeparts[4]+1,@timeparts[3,2,1,0], $_);'

これを sed スクリプトの代わりに使用します。

あなたが試みたアプローチの問題の1つは、sedコマンドが呼び出された時点で日付が計算され、シェルによって置き換えられるため、すべての行が同じログタイムスタンプを持つことでした。

于 2013-07-27T14:24:09.043 に答える