使用 log4j2 作为 SLF4J 后端的 EventData 消息丢失?

Posted

技术标签:

【中文标题】使用 log4j2 作为 SLF4J 后端的 EventData 消息丢失?【英文标题】:EventData message lost with log4j2 as SLF4J backend? 【发布时间】:2015-10-22 18:51:01 【问题描述】:

我想使用 SLF4J-ext EventData 和 EventLogger 在我的业务逻辑中记录重要事件:

public void onMessage(Message message) 
    EventData messageEvent = new EventData();
    messageEvent.setMessage("Message arrived");
    messageEvent.put("messageID", message.getJMSMessageID());
    EventLogger.logEvent(messageEvent);

我也想使用 log4j2 作为后端。目前,这导致以下工件成为我部署的一部分:slf4j-api-1.7.12、slf4j-ext-1.7.12、log4j-api-2.3、log4j-core-2.3、log4j-slf4j-impl-2.3、 log4j-web-2.3 - 当然还有它们的依赖关系。

我的 log4j2 配置旨在在常规文件中生成格式化条目:

[...]
<Appenders>
    <RollingFile name="traceFileAppender"
        fileName="$logBase/trace.log"
        filePattern="$logBase/trace.log.%dyyyy-MM-dd">
        <TimeBasedTriggeringPolicy interval="1" modulate="true" />
        <DefaultRolloverStrategy max="7"/>
        <PatternLayout pattern="%dateISO8601[%thread] %level %marker %logger%nThread-Stack: %x%nThread-Map: %X%nMessage-Map: %K%nMessage: %m%n%rEx-- %n%n" />
        <ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY" />
    </RollingFile>
    [...]
</Appenders>
<Loggers>
    [...]
    <Logger name="EventLogger" level="INFO" additivity="true" />
    [...]
    <Root level="TRACE">
        <AppenderRef ref="traceFileAppender" />
        [...]
    </Root>
</Loggers>
[...]

但是,我的日志语句如下所示:

2015-07-31T08:13:55,589[MessageListenerThreadPool : 0] INFO EVENT EventLogger
Thread-Stack: []
Thread-Map: 
Message-Map: messageID=ID:c3e2d840d4d8d4f14040404040404040cf522d11eb57d22b
Message: 
-- 

我错过了什么?

【问题讨论】:

【参考方案1】:

log4j-slf4j-impl 模块 converts 一个 slf4j EventData 对象到 log4j2 StructuredMessage。输出显示消息 ID,证明此转换成功。

但是,输出不显示该消息。看起来这是由于 StructuredMessage.toString() 实现。乍一看,似乎无法通过使用%Kkey 转换说明符为消息部分指定一个键来自定义它... :-(

【讨论】:

感谢您指出这一点。我进行了更多调查,发现我的日志中有 XML 异常,抱怨不符合 stax2 的实现。应用程序应该在 WebSphere 上运行,根据this blog-entry,我无能为力。 我认为应该可以编写一个自定义转换器,尝试从结构化消息中获取 EventData 对象,然后手动附加输出以反映原始预期输出。

以上是关于使用 log4j2 作为 SLF4J 后端的 EventData 消息丢失?的主要内容,如果未能解决你的问题,请参考以下文章

企业级干货丢弃Log4j,使用Slf4j集成Log4j2构建项目日志系统

为啥在 Log4j2 上使用 Slf4j 时 log4j-slf4j-impl 不依赖于 log4j-core

记一次项目上线后Log4j2不输出日志的坑

使用 slf4j 绑定自定义 log4j2 包装器

slf4j & log4j2 maven 设置查询

slf4j 搭配 log4j2 处理日志