1

ubuntuサーバーで実行されるphpスクリプトがあります。このスクリプトは、クエリを実行して統計を収集する無限ループで実行されます...これは、他のサービスの監視です。60 秒ごとに、収集された統計が json オブジェクトとして .js ファイルにダンプされます。.js ファイルは別の場所で監視されており、私の質問では重要ではありません。

スクリプトを実行すると、stdout と stderr の両方がログ ファイルにリダイレクトされます。ほとんどの場合、標準またはエラーの出力がないため、ログは空のままになります。

もちろん、場合によっては出力があります。昨夜私が経験した問題は、何らかの理由でスクリプトが失敗し、ログ ファイルがパーティション全体を埋めてしまい、サーバーの安定性を台無しにしてしまったことです。

私がやったこと..またはやろうとしたことは、60秒ごとに(統計がダンプされるとき)スクリプトがログファイルのサイズをチェックするという簡単なチェックを追加することです..サイズがX mbより大きい場合、基本的にファイルを空にして、ロギングを続行できるようにします。スクリプトで再び問題が発生した場合に、ログ ファイルでパーティション全体がいっぱいにならないようにするためです。

ログ ファイルのサイズを正常に検出でき、設定したサイズに達したときに正常にクリアできますが、次に STDOUT または STDERR の書き込みが発生したときに、以前のすべてのデータが一度にダンプされます。

これに関するご支援をいただければ幸いです。


スクリプトの呼び出し:

php checker.php &> log

しかし、試してみました

php checker.php > log 2>&1

また、スクリプトの開始時にストリームをリダイレクトします

close(STDOUT);
fclose(STDERR);
$STDOUT = fopen($LOG_FILE_LOCATION, 'wb');
$STDERR = fopen($LOG_FILE_LOCATION, 'wb');

どちらの方法でも同じ出力が生成されます。

コードクリアログファイル

function CheckLogFilesize($file)
{
    global $LOG_FILE_LOCATION;
    global $MAX_LOG_SIZE_MB;
    $max_log_size_bytes = $MAX_LOG_SIZE_MB * 1024 * 1024;

    $size = exec('stat -c %s ' . $file);

    // If log file size is too large.. reset it.
    if (intval($size) > $max_log_size_bytes)
    {
        flush();

        // Clear the log
        $fp = fopen($file, 'w');
        fwrite($fp, '');
        fclose($fp);
    }
}

ありがとう

4

3 に答える 3

1

stdoutログファイルにリダイレクトしている場合は、そのファイルにリダイレクトすることもできますが、まだ接続されているunlink()ため、機能しません。stdout

1つの方法は、プロセスを開始する前にログファイルをクリアし、ファイルが特定のサイズを超えたときにプロセスを停止することです。次に、スクリプトをシェルスクリプトループ内で実行します(プロセスが存在する場合にのみ終了しますcode = 0、つまりエラーはありません)。スクリプトが停止すると、すぐに再起動されます。

通常、デーモンは独自のログファイルHUPを開くため、ログファイルを再度開くようにデーモンに信号を送信して、完全な再起動を回避できます。

于 2012-05-30T06:02:47.027 に答える
1

編集

理解した:

function get_log_size() {
    clearstatcache();
    return filesize("/tmp/log.log");
}

foreach (range(1, 1000000) as $interval) {
    echo $interval . "\n";
    usleep(10000);
    if ($interval % 50 == 0) {
        fwrite(STDERR, "mod 50 fail test");
    }
    $size = get_log_size();
    echo $size . " bytes\n";
    if ($size > 100) {
        $file = "/tmp/log.log";
        $fp = fopen($file, 'w');
        fclose($fp);
        print "Truncated\n";
    }

}

で始まった

php test.php >> /tmp/log.log 2>&1

>の代わりに>>に注意してください。追加モードを使用する必要があります

の出力例tail -f /tmp/log.log:

λ ~/ tail -f /tmp/log.log

1
2 bytes
2
12 bytes
3
23 bytes
4
34 bytes
5
45 bytes
6
56 bytes
7
67 bytes
8
78 bytes
9
89 bytes
10
101 bytes
Truncated
11
13 bytes
12
25 bytes
13
37 bytes
14
49 bytes
15
61 bytes
16
73 bytes
17
85 bytes
18
97 bytes
19
109 bytes
Truncated
20
13 bytes
21
25 bytes
22
37 bytes
23
49 bytes
24
61 bytes
25
73 bytes
26
85 bytes
27
97 bytes
28
109 bytes
Truncated
于 2012-05-30T06:04:38.577 に答える
1

そのようなことをしなければならない場合は、ログファイルのサイズを検出し、それがしきい値よりも大きい場合は、ファイルを別のファイル名 (例: old-log.txt) に移動します。その場合、合計サイズがしきい値の 2 倍の最大 2 つのログファイルが作成されます。

利点は、しきい値に達した直後にまだ古いログ エントリが残っていることです。ファイルをクリアすると、空のファイルで情報を見つけようとしていることがわかります

編集:

PHP の ob_* コマンドを見てみましょう。バッファをクリアするのに役立つ場合があります

ob_start()コメントでは、標準出力に関する詳細情報を見つけることができます

...
ob_start();
// keep writing log until done
ob_end_clean(); // or use ob_end_flush();

いくつかの擬似コード...

于 2012-05-30T05:50:50.760 に答える