2012-11-08 31 views
2

我的任務是編寫一個BASH腳本來過濾log4j文件並通過netcat將它們傳送到另一個主機。其中一個要求是,腳本必須跟蹤它已發送到服務器的內容,並且由於接收服務器上的許可限制而不再發送它(服務器上的產品是按照每日數據模型許可的) 。持久AWK程序

爲了實現我使用AWK封裝在一個bash腳本過濾。 BASH組件工作正常 - 這是AWK程序,當我試圖讓它記住已經發送到服務器的內容時​​,它讓我感到悲傷。我通過抓住每一行符合我的模式的行的時間戳來做到這一點。在程序結束時,最後的時間標記寫入當前工作目錄中的隱藏文件。在程序的連續運行中,AWK將把這個文件讀入一個變量。現在,每當一行符合該模式時,它的時間戳也會與變量中的一個進行比較。如果它是更新的它被打印,否則它不是。

所需的輸出:

INFO 2012-11-07 09:57:12479 [[artifactId的] .connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor :的MsgID = 5017f1ff-1dfa-48c7-a03c-ed3c29050d12 InteractionStatus =接受InteractionDateTime = 2012-08-07T16:57:33.379 + 12:00零售商= CTCT的RequestType = RemoteReconnect

隱藏文件:

2012-10-11 12:08:1 9,918

所以這是理論,現在我的問題。

該腳本適用罰款做作/簡單的例子,如:

INFO 2012-11-07 09:57:12479 [[artifactId的] .connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor:的MsgID = 5017f1ff-1dfa-48c7-a03c-ed3c29050d12 InteractionStatus =接受InteractionDateTime = 2012-08-07T16:57:33.379 + 12:00零售商= 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; 
    } 
} 

任何幫助找出爲什麼會發生這將不勝感激。

UPDATE:

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年9月4日16:00:11638 [ADR-COM適配器存根] .connector.http.mule.default .receiver.02] nz.co.amsco.interop.multidriveinterop:session not initialised error 2012-09-04 16:00:11,639 [[adr-com-adapter-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)

我一直無法確定爲什麼會發生這種情況。

+1

我花了大約10分鐘,但我甚至不能重現您的問題:腳本沒有定義'EXPRESSION',當我手動定義它時,我發現這個表達式不適用於提供的輸入示例。請提供可以重現問題的工作示例(http://sscce.org)。 –

+0

Dunno。寧願將zip以某種方式照顧數據量考慮。我已經看到800Mb變成6Mb。另外,我總是需要更換我使用的濾鏡。如果數據不完整,我會討厭它,因爲一些過濾器錯誤/要求。爲什麼不爲開發人員/質量保證/支持人員提供方便的過濾工具? – joepd

+0

我已經添加了額外的腳本等,所以現在我的問題應該是完全可重現的。道歉,當我發佈這個問題時,我應該這樣做。 –

回答

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命令,併發布一些可以再現你的問題的小樣本輸入。

+0

我更新了所有支持腳本等問題以重現我的問題。希望現在有足夠的信息:) –