I’m writing a node.js function to ssh to a remote machine, and attempt to scrape logs for exceptions from a variety of different log files. The important bit of the log file will look something like this:
.... gunk ....
2013-01-29 04:06:39,133 com.blahblah.BaseServlet processRequest Thread-1629 Site-102 Cons-0 Url-http://theurlthat.com/caused/the/problem App-26 yada yada yada
java.lang.NullPointerException
at com.blahblah.MyClass.hi(MyClass.java:173)
at com.blahblah.StandardStackTrace.main(StandardStackTrace.java:125)
at com.blahblah.SoOnAndSo.forth(SoOnAndSo.java:109)
at java.lang.Thread.run(Thread.java:595)
2013-01-29 04:06:39,133 com.blahblah.BaseServlet defaultThrowableHandler Thread-1629 Site-102 Cons-0 Url-http://theurlthat.com/caused/the/problem App-26 yad yada yada
TechnicalDifficultiesException: TD page delivered by handleThrowable
http://theurlthat.com/caused/the/problem
....more gunk....
I need to find the exception and corresponding date in the log file that meets the following three requirements:
-
The exception must be the first that precedes this static text:
TechnicalDifficultiesException: TD page delivered by handleThrowable
-
The Exception must be directly between two lines that have “BaseServlet.*Site-102”
-
The exception must be the most recent (last) in the log files that meets the above conditions. The log is rolled over periodically, so it need to be the last in Log, or if that doesn’t exist the last in Log.001, or if that doesn’t exist the last in Log.002, etc.
Since this program has to ssh into one of many potential servers, it’s better to only have to maintain the logic in the node.js program and not on the machines with the logs. Thus, a one-liner in perl/sed/awk/grep/etc would be most ideal.
So your question looks like this, if I understand correctly:
/BaseServlet.*?Site-102/./^TechnicalDifficultiesException: TD page delivered by handleThrowable/, we want to select the body of the previously matched section, which we should maybe validate to look like a java exception.Fair enough.
(not really tested that much, but prints out the error from your snippet)
The code is a bit to long for a one-liner. You could always pipe the source into the perl interpreter, if you wanted.
Specify the log file as a command line argument, or pipe the file contents directly into that program. Finding the correct log file isn’t hard. In a snippet of Perl:
Update
If the date should be captured as well, the code would change to
And as the one-liner:
I don’t understand how it could only return the first match; this code should process the whole file. If you could provide a more complete testcase, I could verify that this code works as required.