我使用ExecutorService
异步发送邮件的Java堆栈跟踪,所以有一类:保留跨线程
class Mailer implements Runnable { ...
,处理发送。这被逮住被记录,为(匿名)如任何异常:
javax.mail.internet.AddressException: foo is bar
at javax.mail.internet.InternetAddress.checkAddress(InternetAddress.java:1213) ~[mail.jar:1.4.5]
at javax.mail.internet.InternetAddress.parse(InternetAddress.java:1091) ~[mail.jar:1.4.5]
at javax.mail.internet.InternetAddress.parse(InternetAddress.java:633) ~[mail.jar:1.4.5]
at javax.mail.internet.InternetAddress.parse(InternetAddress.java:610) ~[mail.jar:1.4.5]
at mycompany.Mailer.sendMail(Mailer.java:107) [Mailer.class:?]
at mycompany.Mailer.run(Mailer.java:88) [Mailer.class:?]
... suppressed 5 lines
at java.lang.Thread.run(Thread.java:680) [?:1.6.0_35]
不是非常有帮助 - 我需要看到的是调用导致这一切的ExecutorService
堆栈跟踪。我的解决方案是创建一个空的Exception
并把它传递到Mailer
:
executorService.submit(new Mailer(foo, bar, new Exception()));
...
// constructor
public Mailer(foo, bar, Exception cause) { this.cause = cause; ...
现在在例外的情况下,我想记录本身的问题,并从其他线程的原因:
try {
// send the mail...
} catch (Throwable t) {
LOG.error("Stuff went wrong", t);
LOG.error("This guy invoked us", cause);
}
这很好,但会产生两个日志。我想将t
和cause
组合成一个例外并记录下来。在我看来,t
导致cause
,所以使用cause.initCause(t)
应该是正确的方法。和作品。我看到一个完整的堆栈跟踪:从通话始发地到达AddressException
。
问题是,initCause()
只能工作一次,然后崩溃。 问题1:我可以克隆Exception
?我会克隆cause
并每次初始化它与t
。
我试过t.initCause(cause)
,但是马上崩溃了。
问题2:是否有另一种巧妙结合这两个例外的巧妙方法?或者为了记录的目的只保留另一个线程上下文中的一个线程上下文?
如何从异常中获取堆栈跟踪并使用它? – RealSkeptic
我想尽可能地利用Log4j中的日志记录机制。操纵栈跟踪似乎是一件破解事情的黑客。 – vektor
“问题是,initCause()只能工作一次,然后崩溃。” - 它如何崩溃? – user3707125