首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于验证日志文件中记录器日期格式的Shell脚本

用于验证日志文件中记录器日期格式的Shell脚本
EN

Stack Overflow用户
提问于 2011-02-11 17:11:35
回答 4查看 1.9K关注 0票数 2

我需要验证我的日志文件:

-All新的日志行应以日期开始。

-This日期将遵守ISO 8601标准。例子: 2011-02-03 12:51:45,220 Z-

使用shell脚本,我可以验证它在每一行上循环并验证日期模式。守则如下:

代码语言:javascript
复制
#!/bin/bash

processLine(){
    # get all args
    line="$@"    
    result=`echo $line | egrep "[0-9]{4}-[0-9]{2}-[0-9]{2} [012][0-9]:[0-9]{2}:[0-9]{2},[0-9]{3}Z" -a -c`    
    if [ "$result" == "0" ]; then
        echo "The log is not with correct date format: "
        echo $line
        exit 1
    fi

}


# Make sure we get file name as command line argument
if [ "$1" == "" ]; then
   echo "You must enter a logfile"
   exit 0
else
    file="$1"
    # make sure file exist and readable
    if [ ! -f $file ]; then
        echo "$file : does not exists"
        exit 1
    elif [ ! -r $file ]; then
        echo "$file: can not read"
        exit 2
    fi
fi


# Set loop separator to end of line
BAKIFS=$IFS
IFS=$(echo -en "\n\b")
exec 3<&0
exec 0<"$file"
while read -r line
do
    # use $line variable to process line in processLine() function
    processLine $line
done
exec 0<&3

# restore $IFS which was used to determine what the field separators are
IFS=$BAKIFS
echo SUCCESS

但是,有一个问题。有些日志包含堆栈或使用多行的东西,换句话说,堆栈跟踪就是一个例子,它可以是任何。Stacktrace示例:

代码语言:javascript
复制
2011-02-03 12:51:45,220Z [ERROR] - File not found
java.io.FileNotFoundException: fred.txt
        at java.io.FileInputStream.<init>(FileInputStream.java)
        at java.io.FileInputStream.<init>(FileInputStream.java)
        at ExTest.readMyFile(ExTest.java:19)
        at ExTest.main(ExTest.java:7)
        ...

不会通过我的脚本,但是有效的!然后,如果我运行我的脚本传递带有堆栈跟踪的日志文件,我的脚本就会失败,因为它逐行循环。

我有正确的模式,我需要验证记录器日期格式,但我没有错误的日期格式模式跳过行。

我不知道我怎么能解决这个问题。有人能帮我吗?

谢谢

EN

回答 4

Stack Overflow用户

发布于 2011-02-11 17:40:07

您需要将搜索的日期定位到行的开头(否则,日期可能出现在行的任何位置--而不仅仅是开始)。

下面的代码段将遍历以有效日期开头的所有行。您仍然需要确定这些行是否构成错误。

代码语言:javascript
复制
DATEFMT='^[0-9]{4}-[0-9]{2}-[0-9]{2} [012][0-9]:[0-9]{2}:[0-9]{2},[0-9]{3}Z'
egrep -v ${DATEFMT} /path/to/log | while read LINE; do
   echo ${LINE} # did not begin with date.
done
票数 1
EN

Stack Overflow用户

发布于 2011-02-11 19:53:42

所以(安静地)丢弃一个堆栈跟踪。在有些冗长的巴什:

代码语言:javascript
复制
STATE=idle

while read -r line; do
    case $STATE in
    idle)
        if [[ $line =~ ^java\..*Exception ]]; then
            STATE=readingexception
        else
            processLine "$line"
        fi
        ;;

    readingexception)
        if ! [[ $line =~ ^' '*'at ' ]]; then
            STATE=idle
            processLine "$line"
        fi
        ;;

    *)
        echo "Urk! internal error [$STATE]" >&2
        exit 1
        ;;
    esac
done <logfile

这依赖于processLine,而不是继续错误,否则您将需要跟踪一个更多的状态,以避免两个连续的堆栈跟踪。

票数 1
EN

Stack Overflow用户

发布于 2011-02-12 05:52:44

这就做出了两个假设。

以空格开头的

  1. 行是前几行的延续。我们正在匹配前导空间或前导选项卡。具有非空格字符的
  2. 行(从^开始)是新的日志行。

如果一行匹配#2与日期格式不匹配,则出现错误,因此打印错误,并包括行号。

代码语言:javascript
复制
count=0

processLine() {
     count=$(( count + 1 ))
     line="$@"

     result=$( echo $line | egrep '^[0-9]{4}-[0-9]{2}-[0-9]{2} [012][0-9]:[0-9]{2}:[0-9]{2},[0-9]{3}Z' -a -c )

     if (( $result == 0 )); then

        # if result = 0, then my line did not start with the proper date.
        # if the line starts with whitespace, then it may be a continuation
        # of a multi-line log entry (like a java stacktrace)

        continues=$( echo $line | egrep "^ |^   " -a -c )

        if (( $continues == 0 )); then

                # if we got here, then the line did not start with a proper date,
                # AND the line did not start with white space.  This is a bad line.

                echo "The line is not with correct date format: "
                echo "$count: $line"
                exit 1
        fi
    fi
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4971951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档