Juha Syrjälä
Juha Syrjälä

Reputation: 34281

Stacktrace aware grep

Are there any grep -like Unix/Linux command line tools that understand Java stacktraces in log files that are printed by log4j or logback? The tool should understand that a stacktrace consists of several lines.

Typical use case would be to filter out certain exceptions and corresponding stacktraces when viewing logs that are stored to files.

Upvotes: 6

Views: 2923

Answers (2)

Masáč
Masáč

Reputation: 173

I'm using following sed one line program:

sed -nr ':main; /^[0-9 :,-]{23} ERROR / { :loop; p; n; /^[0-9 :,-]{23} / b main; b loop}'

The first [0-9 :,-]{23} recognizes log record start. Right after it, before the slash, you can write additional regexp to limit which records to print. The expression in {...} loops through the following lines until new record header is found.

My program works for logs where log records start with:

2015-08-25 12:49:34,906 ...

And prints all records with stack traces which has ERROR after record start. Example:

2015-08-25 12:49:34,906 ERROR [http-8080-89] [Error@112] NullPointerException:
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
...

The sed program explanation

The sed program expression /regexp/ command means: if the current line matches the regexp run command.

sed will read the input line and run the program. When the line matches /^[0-9 :,-]{23} ERROR / it runs the command block {...}, if not then since program ended, sed will not print the current line to output (option -n), then sed reads the next line and run the program again. This repeats until end of input.

{...} explanation:

  1. p - print the current line
  2. n - read next line
  3. /^[0-9 :,-]{23} / b main - if the line matches the regexp continue at label :main - effectively rerunning the whole program on the current line without reading next line - to not miss next possible exception
  4. continue at label :loop

So the regexps:

  1. /^[0-9 :,-]{23} ERROR / matches lines which starts the log record
  2. /^[0-9 :,-]{23} / matches line which is next log record

Upvotes: 8

AntonioOtero
AntonioOtero

Reputation: 1789

I don't know if this answers your question but when I want to get the stacktrace I use grep -A to get the lines right after the line I'm looking for.

For example: grep -A 200 "2014-09-08/12:11:36.110" catalina.out

Upvotes: 0

Related Questions