我一直无法完全一致地重现这一点。我确实怀疑这是 logback 中的错误,但显然这听起来不太可能,在提交之前我需要一个干净的可重现测试用例,所以我问 SO 以防有人看到类似的行为。
基本上我有一个看起来像这样的 SMTPAppender
:
<appender name="QA-SMTP"
class="ch.qos.logback.classic.net.SMTPAppender">
<!-- SMTP appends a default evaluator of on error, this is the simplest evaluator I found to implement -->
<evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
<marker>me.unroll.logging.loggers.InfoEmail.QA</marker>
</evaluator>
<smtpHost>smtp.gmail.com</smtpHost>
<smtpPort>465</smtpPort>
<SSL>true</SSL>
<username>test</username>
<password>test</password>
<from>test</from>
<to>test</to>
<subject>%message</subject>
<layout>
<pattern>hello! thread: %thread</pattern>
</layout>
</appender>
我收到的电子邮件看起来像这样。这没有发生 1) 如果 logger.error(...)
在 main
线程上被调用,或者 2) 当我刚刚创建一个测试池并提交到那,虽然它经常 - 但不始终如一地 - 在我发现它的实际生产案例中发生(这是从 MINA 的回调)。
hello! thread: mainhello! thread: NioProcessor-2
另一个 case 与另一个 appender 匹配,为简洁起见省略:
Action was taken was created for user / .
Created by machine: ip-10-212-90-140.ec2.internal Timestamp: February 19, 2013, 02:48:09.747 Logger source: me.unroll.logging.loggers.InfoEmail In application: Monitoring Client yahoo ============================Action was taken for user 12345 / test@gmail.com
Created by machine: ip-10-212-90-140.ec2.internal Timestamp: February 19, 2013, 15:24:06.016
“用户 ID/电子邮件”取自 MDC
- 这就是为什么我有显式打印线程的想法。从本质上讲,它看起来像是创建了相同的日志事件,一个来自主线程(logback 究竟是如何设法合并我的主线程的?不知道),另一个来自有问题的实际线程。
有没有人见过这种行为或知道如何解决?
最佳答案
也许我误解了你的问题,但正如我所看到的,logback 有时会在一封电子邮件中发送两个事件。这是设计使然,有一个 bufferSize 允许收集事件包,如果它们来得非常快。文档中有一段引述:
The SMTPAppender accumulates logging events in one or more fixed-size buffers and sends the contents of the appropriate buffer in an email after a user-specified event occurs. SMTP email transmission (sending) is performed asynchronously. By default, the email transmission is triggered by a logging event of level ERROR.
您将评估器更改为基于标记的。这意味着附加到记录器的先前事件将位于缓冲区中,直到标记的事件到来。
还要注意评估者如何触发电子邮件传输。
Thus, the number of logging events delivered in any e-mail sent by SMTPAppender is upper-bounded by 256.
如果您希望每封电子邮件只有一个事件,您应该将缓冲区大小更改为 1。但我怀疑如果消息的发送速度快于电子邮件的发送速度,它会丢弃消息:
The SMTPAppender keeps only the last 256 logging events in its cyclic buffer, throwing away older events when its buffer becomes full.
但据我所知,您可以将 asynchronousSending
更改为 false,这样它将阻止日志记录语句,直到消息被发送。
也许您可以在模式末尾添加“%n”,这样它将用新行分隔日志记录事件,这样它就可读了。
免责声明:我只是在阅读文档,从未亲自尝试过,所以不要相信,请在家尝试一下。
关于java - logback SMTPAppender 在不同线程上复制模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14971144/