2

私は、log4j ファイルをフィルタリングし、それらを netcat 経由で別のホストにパイプする BASH スクリプトを作成する任務を負っています。要件の 1 つは、スクリプトが既にサーバーに送信したものを追跡し、受信側サーバーのライセンス制限により再度送信しないようにする必要があることです (サーバー上の製品は 1 日あたりのデータ モデルでライセンスされています)。 .

フィルタリングを実現するために、BASH スクリプトにカプセル化された AWK を使用しています。BASH コンポーネントは正常に動作します。サーバーに既に送信された内容を記憶させようとすると、AWK プログラムが問題になります。行がパターンに一致するたびに、行のタイムスタンプを取得することでこれを行っています。プログラムの最後に、現在の作業ディレクトリにある隠しファイルに最後のタイム スタンプが書き込まれます。プログラムを連続して実行すると、AWK はこのファイルを変数に読み込みます。これで、行がパターンに一致するたびに、そのタイム スタンプも変数内のタイム スタンプと比較されます。新しい場合は印刷され、そうでない場合は印刷されません。

望ましい出力:

INFO 2012-11-07 09:57:12,479 [[artifactid].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: MsgID=5017f1ff-1dfa-48c7-a03c-ed3c29050d12 InteractionStatus =Accept InteractionDateTime=2012-08-07T16:57:33.379+12:00 Retailer=CTCT RequestType=RemoteReconnect

隠しファイル:

2012-10-11 12:08:19,918

それが理論であり、今私の問題です。

スクリプトは、次のような不自然な/些細な例に対しては正常に機能します。

INFO 2012-11-07 09:57:12,479 [[artifactid].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: MsgID=5017f1ff-1dfa-48c7-a03c-ed3c29050d12 InteractionStatus =Accept InteractionDateTime=2012-08-07T16:57:33.379+12:00 Retailer=CTCT RequestType=RemoteReconnect

ただし、スタックトレースなどを含む完全なログファイルに対して実行すると、インデントレベルがプログラムに大混乱をもたらすように見えます。プログラムを最初に実行すると、目的の結果が生成されます。一致する行が出力され、最新のタイム スタンプが隠しファイルに書き込まれます。もう一度実行すると、問題が発生します。プログラムの出力には、スタック トレースなどからのインデントされた行が含まれており (以下のブロックを参照)、その理由がわかりません。次に、一致する最後の行にタイムスタンプが含まれておらず、いくつかのガベージが書き込まれ、それ以上の実行が無意味になるため、隠しファイルが詰め込まれます。

望ましくない出力:

package.reverse.domain.SomeClass.someMethod(SomeClass.java:233) で package.reverse.domain.processor.SomeClass.process(SomeClass.java:129) で package.reverse.domain.processor.someClass.someMethod(SomeClassjava) :233) package.reverse.domain.processor.SomeClass.process(SomeClass.java:129) で

次の後の隠しファイル:

package.reverse.domain.process(SomeClass.java:129)

私のawkプログラム:

FNR == 1 {
    CMD = "basename " FILENAME
    CMD | getline FILE;
    FILE = "." FILE ".last";
    if (system("[ -f "FILE" ]") == 0) {
        getline FIRSTLINE < FILE;
        close(FILE);
        print FIRSTLINE;
    }
    else {
        FIRSTLINE = "1970-01-01 00:00:00,000";
    }
 }
$0 ~ EXPRESSION {
    if (($2 " " $3) > FIRSTLINE) {
        print $0;
        LASTLINE=$2 " " $3;
    }
}
END {
    if (LASTLINE != "") {
        print LASTLINE > FILE;
    }
}

なぜこれが起こっているのかを知るための支援をいただければ幸いです。

アップデート:

BASH スクリプト:

#!/bin/bash
while getopts i:r:e:h:p: option
do
    case "${option}"
    in
        i) INPUT=${OPTARG};;
        r) RULES=${OPTARG};;
        e) PATFILE=${OPTARG};;
        h) HOST=${OPTARG};;
        p) PORT=${OPTARG};;
        ?) printf "Usage: %s: -i <\"file1.log file2.log\"> -r <\"rules1.awk rules2.awk\"> -e <\"patterns.pat\"> -h <host> -p <port>\n" $0;
           exit 1;
    esac
done

#prepare expression with sed
EXPRESSION=`cat $PATFILE | sed ':a;N;$!ba;s/\n/|/g'`;
EXPRESSION="^(INFO|DEBUG|WARNING|ERROR|FATAL)[[:space:]]{2}[[:digit:]]{4}\\\\-[[:digit:]]{1,2}\\\\-[[:digit:]]{1,2}[[:space:]][[:digit:]]{1,2}:[[:digit:]]{2}:[[:digit:]]{2},[[:digit:]]{3}.*"$EXPRESSION".*";

#Make sure the temp file is empty
echo "" > .temp;

#input through awk.
for file in $INPUT
do
    awk -v EXPRESSION="$EXPRESSION" -f $RULES $file >> .temp;
done

#send contents of file to splunk indexer over udp
cat .temp;
#cat .temp | netcat -t $HOST $PORT;

#cleanup temporary files
if [ -f .temp ]
then
    rm .temp;
fi

パターン ファイル (一致させたいもの):

Warning
Exception

上記の awk スクリプト。

Example.log

info  2012-09-04 16:00:11,638 [[adr-com-adaptor-stub].connector.http.mule.default.receiver.02] nz.co.amsco.interop.multidriveinterop: session not initialised
error 2012-09-04 16:00:11,639 [[adr-com-adaptor-stub].connector.http.mule.default.receiver.02] nz.co.amsco.adrcomadaptor.processor.comadaptorprocessor: nz.co.amsco.interop.exceptions.systemdownexception
nz.co.amsco.interop.exceptions.systemdownexception
    at nz.co.amsco.adrcomadaptor.processor.comadaptorprocessor.getdeviceconfig(comadaptorprocessor.java:233)
    at nz.co.amsco.adrcomadaptor.processor.comadaptorprocessor.process(comadaptorprocessor.java:129)
    at org.mule.processor.chain.defaultmessageprocessorchain.doprocess(defaultmessageprocessorchain.java:99)
    at org.mule.processor.chain.abstractmessageprocessorchain.process(abstractmessageprocessorchain.java:66)
    at org.mule.processor.abstractinterceptingmessageprocessorbase.processnext(abstractinterceptingmessageprocessorbase.java:105)
    at org.mule.processor.asyncinterceptingmessageprocessor.process(asyncinterceptingmessageprocessor.java:90)
    at org.mule.processor.chain.defaultmessageprocessorchain.doprocess(defaultmessageprocessorchain.java:99)
    at org.mule.processor.chain.abstractmessageprocessorchain.process(abstractmessageprocessorchain.java:66)
    at org.mule.processor.AbstractInterceptingMessageProcessorBase.processNext(AbstractInterceptingMessageProcessorBase.java:105)
    at org.mule.interceptor.AbstractEnvelopeInterceptor.process(AbstractEnvelopeInterceptor.java:55)
    at org.mule.processor.AbstractInterceptingMessageProcessorBase.processNext(AbstractInterceptingMessageProcessorBase.java:105)

使用法:

./filter.sh -i "Example.log" -r "rules.awk" -e "patterns.pat" -h ホスト -p ポート

このバージョンでは、出力が標準出力にスローされるだけなので、ホストとポートはどちらも使用されないことに注意してください。

したがって、これを実行すると、次の出力が得られます。

情報 2012-09-04 16:00:11,638 [[adr-com-adaptor-stub].connector.http.mule.default.receiver.02] nz.co.amsco.interop.multidriveinterop: セッションが初期化されていないエラー 2012- 09-04 16:00:11,639 [[adr-com-adaptor-stub].connector.http.mule.default.receiver.02] nz.co.amsco.adrcomadaptor.processor.comadaptorprocessor: nz.co.amsco.interop .exceptions.systemdownexception at nz.co.amsco.adrcomadaptor.processor.comadaptorprocessor.getdeviceconfig(comadaptorprocessor.java:233) at nz.co.amsco.adrcomadaptor.processor.comadaptorprocessor.process(comadaptorprocessor.java:129)

同じ変更されていないファイルで再度実行すると、出力は得られませんが、次のように表示されます。

nz.co.amsco.adrcomadaptor.processor.comadaptorprocessor.process (comadaptorprocessor.java:129)

なぜこれが起こっているのかを特定できませんでした。

4

1 に答える 1

1

問題を再現できるサンプル入力を提供しなかったので、スクリプトをクリーンアップしてそこから始めましょう。これに変更します:

BEGIN{
  expression = "^(INFO|DEBUG|WARNING|ERROR|FATAL)[[:space:]]{2}[[:digit:]]{4}-[[:digit:]]{1,2}-[[:digit:]]{1,2}[[:space:]][[:digit:]]{1,2}:[[:digit:]]{2}:[[:digit:]]{2},[[:digit:]]{3}.*Exception|Warning"
    # Do you really want "(Exception|Warning)" in brackets instead?
    # As written "Warning" on its own will match the whole expression.
}

FNR == 1 {
    tstampFile = "/" FILENAME ".last"
    sub(/.*\//,".",tstampFile)

    if ( (getline prevTstamp < tstampFile) > 0 ) {
        close(tstampFile)
        print prevTstamp
    }
    else {
        prevTstamp = "1970-01-01 00:00:00,000"
    }

    nextTstamp = ""
}

$0 ~ expression {
    currTstamp = $2 " " $3
    if (currTstamp > prevTstamp) {
        print
        nextTstamp = currTstamp
    }
}

END {
    if (nextTstamp != "") {
        print nextTstamp > tstampFile
    }
}

さて、まだ問題がありますか?その場合は、スクリプトの実行方法、つまり実行しているbashコマンドを示し、問題を再現する小さなサンプル入力を投稿してください。

于 2012-11-08T12:55:42.910 に答える