5

ログファイルに特定の文字列が表示されたときにアラートが生成されるスクリプトを設定しようとしています。

すでに導入されているソリューションは、ログファイル全体を1分に1回取得し、ログ行のタイムスタンプを使用して前の1分間の発生のみをカウントし、文字列が表示される頻度をカウントします。

尻尾を使ってこれを行う方がはるかに効率的だと思ったので、テストとして次のことを試しました。

FILENAME="/var/log/file.log"

tail -f $FILENAME | awk -F , -v var="$HOSTNAME" '
                BEGIN {
                        failed_count=0;
                }
                /account failure reason/ {
                        failed_count++;
                }
                END {
                        printf("%saccount failure reason (Errors per Interval)=%d\n", var, failed_count);
                }
'

しかし、これはハングし、何も出力しません。誰かがこの小さな変更を提案しました:

FILENAME="/var/log/file.log"

awk -F , -v var="$HOSTNAME" '
                BEGIN {
                        failed_count=0;
                }
                /account failure reason/ {
                        failed_count++;
                }
                END {
                        printf("%saccount failure reason (Errors per Interval)=%d\n", var, failed_count);
                }
' <(tail -f $FILENAME)

しかし、それは同じことをします。

私が使用しているawk(上記のコードで簡略化したもの)は、grep "^$TIMESTAMP"の結果がパイプされる既存のスクリプトで使用されているため機能します。

私の質問は、tail -fをawkで機能させるにはどうすればよいですか?

4

1 に答える 1

5

ログが次のようになっていると仮定します。

Jul 13 06:43:18 foo account failure reason: unknown
 │   │    
 │   └── $2 in awk
 └────── $1 in awk

次のようなことができます。

FILENAME="/var/log/file.log"

tail -F $FILENAME | awk -v hostname="$HOSTNAME" '
    NR == 1 {
        last=$1 " " $2;
    }
    $1 " " $2 != last {
        printf("%s account failure reason (Errors on %s)=%d\n", hostname, last, failed);
        last=$1 " " $2;
        failed=0;
    }
    /account failure reason/ {
        failed++;
    }
'

tail -Fログのエージングを処理するため、これを (大文字の F) に変更したことに注意してください。これはすべてのオペレーティング システムでサポートされているわけではありませんが、最新の BSD および Linux では機能するはずです。

これはどのように作動しますか?

awk スクリプトはtest { commands; }、入力の各行に対して評価される のセットで構成されます。(2 つの特別なテストがありBEGINENDそのコマンドは awk の開始時と awk の終了時にそれぞれ実行されます。質問では、awk は決して終了しなかったため、ENDコードは実行されませんでした。)

上記のスクリプトには、次の 3 つのテスト/コマンド セクションがあります。

  • 1 つ目NR == 1は、入力の最初の行のみで true と評価されるテストです。last実行されるコマンドは、次のセクションで使用される変数の初期値を作成します。
  • 2 番目のセクションでは、評価された最後の行以降に「最後の」変数が変更されたかどうかをテストします。これが true の場合、新しい日のデータを評価していることを示しています。先月の要約 (ログ) を印刷し、変数をリセットして先に進みます。
  • 3 番目では、評価している行が正規表現/account failure reason/に一致する場合、カウンターをインクリメントします。

泥のように透明?:-)

于 2012-07-13T12:08:13.240 に答える