bash - how to filter java exception info
We've got a multi-agent Java environment where different agent would most likely produce all sorts of exceptions thrown to stderr.
Here is a sample taken from the huge exception log
**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)
fortunately all top-tier exceptions are denoted by no leading spaces, as wrapped by ** above.开发者_如何学Go
My concern is to get all of the top-tier exception name (delimited by colon :), together with the first line below which contains something like
at emarket.client.EmarketSandbox$SandboxFileLoader.loadClassData(EmarketSandbox.java:218)
Basically, something with padded style, starts with "at" and ends with ".java:108"
So this info can be forwarded to the owner of that error-prone agent and let him/her fix it.
My code in ~/.bashrc is incompleted now :
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
}
What it does now is to redirect all stderr to a text file specified by the first argument passed in, and after that, parse that text file line by line, if certain conditions returns true, echo only that line.
And I am stuck with what to do inside the loop.
Any suggestion is much appreciates, any hint is welcomed.
you can use awk
awk ' $1~/^\*\*/{except=$0}
/emarket\.client/{
print except
print
}' logfile
output
$ ./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)
A more accurate version, only when "emarket.client" pattern is found will it print
awk 'f&&g{next}
$1~/^\*\*/{
except=$0
f=1
g=0
}
f&&/emarket\.client/{
print except
print
f=0;g=1
}' file
How about:
java -jar "emarket.jar" ../tournament 100 | grep '^\([^ ]\| \+at.*\.java:[0-9]\+)$\)' | grep -A 1 '^[^ ]'
Not super super efficient, since it reads things twice, but eh, it's short. Look for either the unpadded line or the padded with line number, then look again for the unpadded line and keep the next line too. It puts a '--' line between each pair of matches, which you could remove by tacking on | grep -v '^--$'
.
精彩评论