Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I capture Java exceptions, including the stack trace, from a log file using grep?

Summary

I am trying to fetch logs from a log file using the grep command. However, I can match time stamps, but am not getting the full stack trace I need.

Log File Sample

[1/10/16 23:55:33:018 PST] 00000057 ServerObj E   SECJ0373E: Exception message
at com.own.ws.wim.util.UniqueNameHelper.formatUniqueName(UniqueNameHelper.java:102)
at com.own.ws.wim.ProfileManager.getImpl(ProfileManager.java:1569)

What I've Tried

I am able to fetch log entries, but I want the stack trace as well. I've tried:

$ grep -i '^[[:space:]]*at' --before-context=2 SystemOut.log |
    grep "1/13/16 7:[1-60]" 
[1/10/16 23:55:33:018 PST] 00000057 ServerObj E   SECJ0373E: Exception message

Any idea how this can be achieved?

like image 626
Anil Kumar Avatar asked Jan 14 '16 11:01

Anil Kumar


People also ask

How do I grep for exceptions in a log file?

For searching files, the command syntax you use is grep [options] [pattern] [file] , where “pattern” is what you want to search for. For example, to search for the word “error” in the log file, you would enter grep 'error' junglediskserver. log , and all lines that contain”error” will output to the screen.

How do I see exceptions in logs?

Let's start with -A option to solve our problem. grep -A n [pattern] [file] will output n lines from the [pattern] match in [file]. For example, the following command will search for the string “Exception” in the log. txt file and output 10 lines from the match.

How do I print a stack trace log file?

Log4J exception stack trace - short answer The short answer is that all you have to do to print the stack trace of an exception using Java and Log4J (or the Apache Commons Logging project) is this: log. error("Your description here", exception);

What is exception stack trace in Java?

A Java stack trace is displayed when an error or exception occurs. The stack trace, also called a backtrace, consists of a collection of stack records, which store an application's movement during its execution.


2 Answers

(From my answer here: https://stackoverflow.com/a/16064081/430128)

Here is a quick-and-dirty grep expression... if you are using a logger such as log4j than the first line of the exception will generally contain WARN or ERROR, the next line will contain the Exception name, and optionally a message, and then the subsequent stack trace will begin with one of the following:

  1. "\tat" (tab + at)
  2. "Caused by: "
  3. "\t... <some number> more" (these are the lines that indicate the number of frames in the stack not shown in a "Caused by" exception)
  4. An Exception name (and perhaps message) before the stack

We want to get all of the above lines, so the grep expression is:

grep -P "(WARN|ERROR|^\tat |Exception|^Caused by: |\t... \d+ more)"

It assumes an Exception class always contains the word Exception which may or may not be true, but this is quick-and-dirty after all.

Adjust as necessary for your specific case.

like image 181
Raman Avatar answered Sep 28 '22 09:09

Raman


Use Context for Fixed-Length Traces

In your original post, you show a single three-line entry. If you know that each exception message with a stack trace is exactly three lines long, then you can use one of the --after-context flags (if supported by your grep) to get all three lines. For example, to pull all exceptions along with the stack trace:

$ fgrep -A2 'Exception message' SystemOut.log
[1/10/16 23:55:33:018 PST] 00000057 ServerObj E   SECJ0373E: Exception message
at com.own.ws.wim.util.UniqueNameHelper.formatUniqueName(UniqueNameHelper.java:102)
at com.own.ws.wim.ProfileManager.getImpl(ProfileManager.java:1569)

Use Multi-Line Expressions for Variable-Length Stack Traces

However, if you don't know how many lines are in the stack trace, then you need a multiline regex with a stop-pattern. For this, you need a grep with the Perl-compatible regular expression (PCRE) library compiled in. For example, with grep -PM or pcregrep -M:

$ pcregrep -M 'Exception message[^\[]+' SystemOut.log
[1/10/16 23:55:33:018 PST] 00000057 ServerObj E   SECJ0373E: Exception message
at com.own.ws.wim.util.UniqueNameHelper.formatUniqueName(UniqueNameHelper.java:102)
at com.own.ws.wim.ProfileManager.getImpl(ProfileManager.java:1569)

This will print each line with an exception, using the square bracket that starts a new timestamp as the stop-pattern. You can certainly adjust the regular expression to suit your needs, or pipe the results to another grep to filter specific timestamps in or out.

This worked for me given the corpus you originally posted. Your mileage may vary.

like image 43
Todd A. Jacobs Avatar answered Sep 28 '22 09:09

Todd A. Jacobs