awk/regex: 解析错误日志不总是返回错误描述
awk/regex: parsing error logs not always returned error description
我最近请求帮助从一组日志文件中解析出 Java 错误堆栈,并在下面的 link 处得到了一个非常好的解决方案(使用 awk)。
我将问题标记为已回答,经过一些调试和研究,我发现了一些潜在的问题,因为它们与我最初的问题无关,而是由于我对 awk 和正则表达式的理解有限,我认为它可能会更好问一个新问题。
解决方法如下:
BEGIN{ OFS="," }
/[[:space:]]+*<Error / {
split("",n2v)
while ( match([=11=],/[^[:space:]]+="[^"]+/) ) {
name = value = substr([=11=],RSTART,RLENGTH)
sub(/=.*/,"",name)
sub(/^[^=]+="/,"",value)
[=11=] = substr([=11=],RSTART+RLENGTH)
n2v[name] = value
print name value
}
code = n2v["ErrorCode"]
desc[code] = n2v["ErrorDescription"]
count[code]++
if (!seen[code,FILENAME]++) {
fnames[code] = (code in fnames ? fnames[code] ", " : "") FILENAME
}
}
END {
print "Count", "ErrorCode", "ErrorDescription", "Files"
for (code in desc) {
print count[code], code, desc[code], fnames[code]
}
}
我遇到的一个问题是并非所有 ErrorDescriptions 都被捕获。例如,这个错误描述出现在这个脚本的输出中:
ErrorDescription="Database Error."
但是这个错误描述没有出现在结果中(从实际日志文件复制的描述):
ErrorDescription="Operation not allowed for reason code "7" on table "SCHEMA.TABLE".. SQLCODE=-668, SQLSTATE=57016, DRIVER=4.13.127"
这个也不行:
ErrorDescription="Cannot Find Person For Given Order."
似乎大多数错误描述都没有由该脚本返回,但确实存在于日志文件中。我不明白为什么会出现一些错误描述而有些则不会。有人有什么想法吗?
编辑 1:
这是我正在解析的 XML 的示例:
<Errors>
<Error ErrorCode="ERR_0139"
ErrorDescription="Cannot Find Person For Given Order." ErrorMoreInfo="">
...
...
</Error>
</Errors>
这个正则表达式只会匹配错误描述。
ErrorDescription="(.+?)"
它使用捕获组来记住您的错误描述。
演示 here.(针对您的编辑和您之前的问题错误日志的组合进行测试。)
脚本中的模式与您的数据不匹配:
/[[:space:]]+*<Error / {
详情:
- “+”告诉它至少匹配一个 space。
- "Error" 之后的 space 告诉它匹配另一个 space - 但您的数据在“=”之前没有 space。
- “<”是不必要的(但不是问题的一部分)。
这会是一个更好的模式:
/^[[:space:]]*ErrorDescription[[:space:]]*=[[:space:]]*".*"/
我最近请求帮助从一组日志文件中解析出 Java 错误堆栈,并在下面的 link 处得到了一个非常好的解决方案(使用 awk)。
我将问题标记为已回答,经过一些调试和研究,我发现了一些潜在的问题,因为它们与我最初的问题无关,而是由于我对 awk 和正则表达式的理解有限,我认为它可能会更好问一个新问题。
解决方法如下:
BEGIN{ OFS="," }
/[[:space:]]+*<Error / {
split("",n2v)
while ( match([=11=],/[^[:space:]]+="[^"]+/) ) {
name = value = substr([=11=],RSTART,RLENGTH)
sub(/=.*/,"",name)
sub(/^[^=]+="/,"",value)
[=11=] = substr([=11=],RSTART+RLENGTH)
n2v[name] = value
print name value
}
code = n2v["ErrorCode"]
desc[code] = n2v["ErrorDescription"]
count[code]++
if (!seen[code,FILENAME]++) {
fnames[code] = (code in fnames ? fnames[code] ", " : "") FILENAME
}
}
END {
print "Count", "ErrorCode", "ErrorDescription", "Files"
for (code in desc) {
print count[code], code, desc[code], fnames[code]
}
}
我遇到的一个问题是并非所有 ErrorDescriptions 都被捕获。例如,这个错误描述出现在这个脚本的输出中:
ErrorDescription="Database Error."
但是这个错误描述没有出现在结果中(从实际日志文件复制的描述):
ErrorDescription="Operation not allowed for reason code "7" on table "SCHEMA.TABLE".. SQLCODE=-668, SQLSTATE=57016, DRIVER=4.13.127"
这个也不行:
ErrorDescription="Cannot Find Person For Given Order."
似乎大多数错误描述都没有由该脚本返回,但确实存在于日志文件中。我不明白为什么会出现一些错误描述而有些则不会。有人有什么想法吗?
编辑 1:
这是我正在解析的 XML 的示例:
<Errors>
<Error ErrorCode="ERR_0139"
ErrorDescription="Cannot Find Person For Given Order." ErrorMoreInfo="">
...
...
</Error>
</Errors>
这个正则表达式只会匹配错误描述。
ErrorDescription="(.+?)"
它使用捕获组来记住您的错误描述。
演示 here.(针对您的编辑和您之前的问题错误日志的组合进行测试。)
脚本中的模式与您的数据不匹配:
/[[:space:]]+*<Error / {
详情:
- “+”告诉它至少匹配一个 space。
- "Error" 之后的 space 告诉它匹配另一个 space - 但您的数据在“=”之前没有 space。
- “<”是不必要的(但不是问题的一部分)。
这会是一个更好的模式:
/^[[:space:]]*ErrorDescription[[:space:]]*=[[:space:]]*".*"/