我的任务是编写一个 BASH 脚本来过滤 log4j 文件并将它们通过 netcat 管道传输到另一台主机。要求之一是脚本必须跟踪它已经发送到服务器的内容,并且由于接收服务器上的许可限制而不能再次发送(服务器上的产品在每天数据模型上获得许可) .
为了实现过滤,我使用了封装在 BASH 脚本中的 AWK。BASH 组件工作正常——当我试图让它记住已经发送到服务器的内容时,让我感到悲伤的是 AWK 程序。每次一行与我的模式匹配时,我通过抓取一行的时间戳来做到这一点。在程序结束时,最后一个时间戳被写入当前工作目录中的隐藏文件。在程序的连续运行中,AWK 会将这个文件读入一个变量。现在,每次一行与模式匹配时,它的时间戳也会与变量中的时间戳进行比较。如果它较新,则打印,否则不打印。
期望的输出:
信息 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 交互状态=Accept InteractionDateTime=2012-08-07T16:57:33.379+12:00 零售商=CTCT RequestType=RemoteReconnect
隐藏文件:
2012-10-11 12:08:19,918
这就是理论,现在是我的问题。
该脚本适用于人为/琐碎的示例,例如:
信息 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 交互状态=Accept 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;
}
}
任何帮助找出为什么会发生这种情况将不胜感激。
更新:
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)
我一直无法确定为什么会发生这种情况。