Reputation: 2967
I use sl4j-api 1.7.2 with slf4j-log4j12.
I would like to log something like this:
22:52:27,345 WARN [class] Failed to load user 1 - Reason : javax.ejb.EJBException: javax.persistence.NoResultException: No entity found for query at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:166) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final] at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:230) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final] at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:304) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final] ... fullstackTrace
So I tried
try {
//...
} catch (Exception e) {
logger.warn("Failed to load User {} - Reason : {}", userId, e);
}
Or
try {
// ...
} catch (Exception e) {
logger.warn("Failed to load User {} - Reason : ", userId, e);
}
But none of this two solutions work
The first try give :
Failed to load User 4 - Reason : javax.ejb.EJBException: javax.persistence.NoResultException: No entity found for query
The second :
Failed to load User 4 - Reason :
Is it possible to made it ?
Thanks.
Upvotes: 2
Views: 2781
Reputation: 3378
This might be not obvious, but with Slf4J it's possible to attach exception to the log event
if exception passed as a last argument.
Example:
logger.error("Parameterized msg {} {} {}", 1, 2, 3, exception)
Output (JSON Appender in my case):
{"message":"Parameterized msg 1 2 3","logger_name":"com.may.Main$","stack_trace":"java.lang.Exception: My Exception\n\tat com.may.Main$.main(Main.scala:34)\n\tat com.may.Main.main(Main.scala)\n","application":"app1","environment":"ENV"}
Docs:
https://www.slf4j.org/faq.html#paramException
Upvotes: 0
Reputation: 22461
Check the Logger API and the SL4J FAQ. You are probably using a SL4J version prior to 1.6.0 in which e
will be interpreted as a simple object (i.e., SL4J will call e.toString()
) if you have a parameter placeholder or ignored if you don't.
As for why it is using a version different than 1.7.2, a previous version is probably included in your Application Server Classpath and getting loaded before you even start your application.
You can either try to fix the Classloading problem or workaround the old version behavior.
If you choose the latter path, from the overloaded versions you need either the warn(String msg, Throwable t))
version that auto expands the stacktrace:
logger.warn("Failed to load User " + userId + " - Reason", e);
Or the warn(String format, Object arg1, Object arg2)
one with code that expands the stacktrace for you.
if (logger.isWarnEnabled()) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String expanded = sw.toString(); // stack trace as a string
logger.warn("Failed to load User {} - Reason : {}", userId, expanded);
}
Upvotes: 3