Regular Expression to Match Entire Java Exception Stacktrace

Given a standard log file for a java application:

 INFO [main] (AutoMain.java:133) - querying data 1
DEBUG [main] (AutoMain.java:142) - data 1 count: 23180
 INFO [main] (AutoMain.java:151) - querying data 2
ERROR [main] (AutoMain.java:607) - Failure in auto
java.net.ConnectException: Connection refused (Connection refused)
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at java.net.Socket.connect(Socket.java:538)
    at java.net.Socket.<init>(Socket.java:434)
    at java.net.Socket.<init>(Socket.java:211)
    at com.myCompany.client.ClientIOFactory$1.<init>(ClientIOFactory.java:17)
    at com.myCompany.client.ClientIOFactory.lambda$clientIOFactoryFromSocket$0(ClientIOFactory.java:15)
    at com.myCompany.client.queryData(Client.java:83)
    at com.myCompany.client.queryData(Client.java:91)
    at com.myCompany.queryOptData(InstantAutomaton.java:153)
    at com.myCompany.AutoMain.main(InstantAutomaton.java:426)

What is a regular expression to match the entire stack trace for any java Exception?

It's easy enough to match any single line that contains "Exception":

grep "Exception" log.txt

But I want all of the subsequent "at" statements as well. So the result matched string should be:

java.net.ConnectException: Connection refused (Connection refused)
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at java.net.Socket.connect(Socket.java:538)
    at java.net.Socket.<init>(Socket.java:434)
    at java.net.Socket.<init>(Socket.java:211)
    at com.myCompany.client.ClientIOFactory$1.<init>(ClientIOFactory.java:17)
    at com.myCompany.client.ClientIOFactory.lambda$clientIOFactoryFromSocket$0(ClientIOFactory.java:15)
    at com.myCompany.client.queryData(Client.java:83)
    at com.myCompany.client.queryData(Client.java:91)
    at com.myCompany.queryOptData(InstantAutomaton.java:153)
    at com.myCompany.AutoMain.main(InstantAutomaton.java:426)

Thank you in advance for your consideration and response.

Upvotes: 4

Views: 4571

Answers (2)

Ed Morton
Ed Morton

Reputation: 204568

Don't use a complicated, non-portable regexp when you can do this trivially using any awk in any shell on any UNIX box:

$ awk '/^[^ ]/{f=0} /Exception/{f=1} f' file
java.net.ConnectException: Connection refused (Connection refused)
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at java.net.Socket.connect(Socket.java:538)
    at java.net.Socket.<init>(Socket.java:434)
    at java.net.Socket.<init>(Socket.java:211)
    at com.myCompany.client.ClientIOFactory$1.<init>(ClientIOFactory.java:17)
    at com.myCompany.client.ClientIOFactory.lambda$clientIOFactoryFromSocket$0(ClientIOFactory.java:15)
    at com.myCompany.client.queryData(Client.java:83)
    at com.myCompany.client.queryData(Client.java:91)
    at com.myCompany.queryOptData(InstantAutomaton.java:153)
    at com.myCompany.AutoMain.main(InstantAutomaton.java:426)

Upvotes: 2

revo
revo

Reputation: 48751

Using Java +8 you could do:

(?m)^.*?Exception.*(?:\R+^\s*at .*)+

See live demo here

In grep however, since it processes one line at a time by default, you could match lines with Exception or those starting with at:

grep -P '(?m)^(?:\S+?Exception|\h+at )' file

Upvotes: 6

Related Questions