【问题标题】:logback SMTPAppender is duplicating pattern on different threadslogback SMTPAppender 在不同的线程上复制模式
【发布时间】:2013-02-20 02:07:28
【问题描述】:

我无法始终如一地重现这一点。我确实怀疑这是 logback 中的一个错误,但显然这听起来不太可能,在我提交之前我需要一个干净的可重现测试用例,所以我问一下,以防有人看到类似的行为。

基本上我有一个看起来像这样的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 的回调中)。

你好!线程:主你好!线程:NioProcessor-2

另一种情况与另一个附加程序匹配,为简洁起见省略:

已为用户 / 创建了操作。

由机器创建:ip-10-212-90-140.ec2.internal 时间戳:2013 年 2 月 19 日,02:48:09.747 记录器来源:me.unroll.logging.loggers.InfoEmail 在应用程序中:监控客户端 yahoo =============================用户 12345 / test@gmail.com

由机器创建:ip-10-212-90-140.ec2.internal 时间戳:2013年2月19日15:24:06.016

“用户 ID / 电子邮件”取自 MDC - 这就是为什么我想显式打印线程的原因。从本质上讲,它看起来像是创建了相同的日志事件,一个来自主线程(logback 到底是如何设法附加我的主线程的?不知道),另一个来自有问题的实际线程。

有没有人见过这种行为或知道如何解决?

【问题讨论】:

  • 请在问题中添加 ch.qos.logback 版本。我个人对 1.0.x 有奇怪的问题。尝试更新到最新的稳定版本。
  • 您也可以粘贴您的代码吗?这将是一个很大的帮助。
  • @JintianDENG 不幸的是,没有,这没有干净或简单地复制,并且需要很多类来正确设置。
  • @user1516873 是的,我使用的是 1.0.x,将确保它是最新的,看看是否有修复。

标签: java logback smtpappender


【解决方案1】:

也许我误解了你的问题,但正如我所见,你说 logback 有时会在一封电子邮件中发送两个事件。按照设计,有一个 bufferSize 允许收集事件包,如果它们来得很快。文档中有一段引述:

SMTPAppender 在一个或多个固定大小的缓冲区中累积日志记录事件,并在用户指定的事件发生后将相应缓冲区的内容发送到电子邮件中。 SMTP 电子邮件传输(发送)是异步执行的。默认情况下,邮件传输由 ERROR 级别的日志事件触发。

您将评估器更改为基于标记的。这意味着附加到记录器的先前事件将位于缓冲区中,直到标记的事件到来。

还要注意评估者如何触发电子邮件传输。

因此,SMTPAppender 发送的任何电子邮件中传递的日志记录事件的数量上限为 256。

如果您希望每封电子邮件有单个事件,则应将缓冲区大小更改为 1。但我怀疑如果消息的发送速度比电子邮件发送的速度快,它会丢弃消息:

SMTPAppender 仅在其循环缓冲区中保留最后 256 个日志记录事件,当其缓冲区已满时丢弃较旧的事件。

但据我了解,您可以将 asynchronousSending 更改为 false,以便在发送消息之前阻止日志记录。

也许您可以在模式的末尾添加“%n”,这样它就会用新的一行分隔日志事件,这样它就可以阅读了。

免责声明:我只是在阅读文档,从未尝试过自己,所以不要相信,只是在家里尝试一下。

【讨论】:

  • 是的,我明白这一点 - 但缓冲逻辑不应导致从两个单独的线程触发相同的事件。
  • @djechlin 我没有看到同样的事件。我看到你有两个事件,不同的消息“已创建”和“12345”,不同的时间戳 02:48:09 和 15:24:06...为什么你认为它是同一个事件?
猜你喜欢
  • 2010-12-31
  • 2014-09-03
  • 2016-12-28
  • 1970-01-01
  • 1970-01-01
  • 2012-04-20
  • 2011-11-24
  • 1970-01-01
  • 2015-11-25
相关资源
最近更新 更多