bash - 如何过滤java异常信息

时间:2010-03-24 00:40:05

标签: bash shell

我们有一个多代理Java环境,其中不同的代理最有可能产生抛出到stderr的各种异常。

以下是从巨大异常日志中获取的示例

**java.security.AccessControlException: access denied (java.io.FilePermission ..\tournament\Driver\HotelRoomAnalyser.class read)**
    at java.security.AccessControlContext.checkPermission(Unknown Source)
    at java.security.AccessController.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkRead(Unknown Source)
    at java.io.File.length(Unknown Source)
    at emarket.client.EmarketSandbox$SandboxFileLoader.loadClassData(EmarketSandbox.java:218)
    at emarket.client.EmarketSandbox$SandboxFileLoader.loadClass(EmarketSandbox.java:199)
    at java.lang.ClassLoader.loadClass(Unknown Source)
**java.security.AccessControlException: access denied (java.io.FilePermission ..\tournament\Driver\HotelRoomAnalyser.class read)**
    at java.security.AccessControlContext.checkPermission(Unknown Source)
    at java.security.AccessController.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkRead(Unknown Source)
    at java.io.File.length(Unknown Source)
    at emarket.client.EmarketSandbox$SandboxFileLoader.loadClassData(EmarketSandbox.java:218)
    at emarket.client.EmarketSandbox$SandboxFileLoader.loadClass(EmarketSandbox.java:199)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClassInternal(Unknown Source)
    at MySmarterAgent.hotelRoomBookings(MySmarterAgent.java:108)

幸运的是,所有顶级异常都没有前导空格,由上面的**包裹。

我关注的是获取所有顶级异常名称(由冒号:)分隔,以及下面第一行包含类似

的内容
at emarket.client.EmarketSandbox$SandboxFileLoader.loadClassData(EmarketSandbox.java:218)

基本上,填充样式的东西,以“at”开头,以“.java:108”结尾

因此,此信息可以转发给容易出错的代理的所有者,让他/她修复它。

〜/ .bashrc中的代码现在已经完成了:

alias startmatch='java -jar "emarket.jar" ../tournament 100';
function geterrors() 
{ 
    startmatch 2>"$1";
    a=0;
    while read line
    do 
        if true;
            then a=$(($a+1));
                echo $a;
        fi;
    done
}

它现在所做的是将所有stderr重定向到由传入的第一个参数指定的文本文件,然后逐行解析该文本文件,如果某些条件返回true,则仅回显该行。

我对循环内部的操作感到困惑。

任何建议都非常值得赞赏,欢迎任何暗示。

2 个答案:

答案 0 :(得分:2)

你可以使用awk

awk ' $1~/^\*\*/{except=$0}
/emarket\.client/{
  print except
  print
}' logfile

输出

$ ./shell.sh
**java.security.AccessControlException: access denied (java.io.FilePermission ..\tournament\Driver\HotelRoomAnalyser.class read)**
    at emarket.client.EmarketSandbox$SandboxFileLoader.loadClassData(EmarketSandbox.java:218)
**java.security.AccessControlException: access denied (java.io.FilePermission ..\tournament\Driver\HotelRoomAnalyser.class read)**
    at emarket.client.EmarketSandbox$SandboxFileLoader.loadClass(EmarketSandbox.java:199)
**java.security.AccessControlException: access denied (java.io.FilePermission ..\tournament\Driver\HotelRoomAnalyser.class read)**
    at emarket.client.EmarketSandbox$SandboxFileLoader.loadClassData(EmarketSandbox.java:218)
**java.security.AccessControlException: access denied (java.io.FilePermission ..\tournament\Driver\HotelRoomAnalyser.class read)**
    at emarket.client.EmarketSandbox$SandboxFileLoader.loadClass(EmarketSandbox.java:199)

更准确的版本,只有在找到“emarket.client”模式时才会打印

awk 'f&&g{next}
$1~/^\*\*/{
  except=$0
  f=1
  g=0
}
f&&/emarket\.client/{
  print except
  print
  f=0;g=1
}' file

答案 1 :(得分:1)

怎么样:

java -jar "emarket.jar" ../tournament 100 | grep '^\([^ ]\| \+at.*\.java:[0-9]\+)$\)' | grep -A 1 '^[^ ]'

不是超级高效,因为它读取了两次,但是,它很短。查找未填充的行或带行号的填充,然后再次查看未填充的行并保留下一行。它在每对匹配之间放置一条“ - ”行,您可以通过| grep -v '^--$'添加来删除。