我正在尝试使用https://logging.apache.org/log4j/2.x/manual/layouts.html#JSONLayout中记录的 log4j2 找出 JSON 日志记录
一切正常,除非我试图通过使用 SLF4J 记录器对象设置objectMessageAsJsonObject=true将对象记录为 json。SLF4j 记录器只是忽略该对象。而当我使用 org.apache.logging.log4j.Logger 的实例时,它可以工作。
此功能(通过 JSON 布局将对象记录为 json)已在 Log4j2 中添加,带有 github 问题https://github.com/apache/logging-log4j2/pull/141
通过创建 org.apache.logging.log4j.message.ObjectMessage 的新实例并传递给 SLF4J 来尝试,但看起来它只是忽略了它。
//这不起作用
logger_slf4j.info(MarkerFactory.getMarker("SLF4J_LOGGER"), "SLF4J logger log object as json", om);
//这有效
logger_log4j2.info(MarkerManager.getMarker("LOG4J2_LOGGER"), om);
更多细节可以在下面的代码部分中找到。
pom.xml
<properties>
<slf4j.version>1.7.28</slf4j.version>
<log4j2.version>2.12.1</log4j2.version>
<jackson.version>2.9.5</jackson.version>
</properties>
!-- slf4j dependencies -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- Log4j2 dependencies -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j2.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j2.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
<scope>provided</scope>
</dependency>
<!-- This is used by JSONLayout. -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<scope>provided</scope>
</dependency>
log4j2.xml
<Configuration status="debug" strict="true">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<JSONLayout compact="true" eventEol="true" objectMessageAsJsonObject="true"/>
</Console>
</Appenders>
<loggers>
<Logger name="com.logging.test" level="all"/>
<root level="all">
<appender-ref ref="STDOUT"/>
</root>
</loggers>
</Configuration>
要记录为 json 的用户对象
public class User implements Serializable {
private String firstName;
private String lastName;
}
JUnit
public class SampleLoggingTest {
private static final org.apache.logging.log4j.Logger logger_log4j2 = LogManager.getLogger(SampleLoggingTest.class);
private static final org.slf4j.Logger logger_slf4j = LoggerFactory.getLogger(SampleLoggingTest.class);
private static final Marker TEST_MARKER = MarkerFactory.getMarker("SLF_LOG");
@Test
public void test_logging(){
User user = new User("john","doe");
ObjectMessage om=new ObjectMessage(msg);
logger_slf4j.info(MarkerFactory.getMarker("SLF4J_LOGGER"), "SLF4J logger log object as json", om);
logger_log4j2.info(MarkerManager.getMarker("LOG4J2_LOGGER"), om);
}
}
预期(使用 SLF4J 记录器):
{"thread":"main","level":"INFO","loggerName":"com.logging.test.SampleLoggingTest","marker":{"name":"SLF4J_LOGGER"},"message":{"firtsName":"john","lastName":"doe"},"endOfBatch":false,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","instant":{"epochSecond":1571770198,"nanoOfSecond":746000000},"threadPriority":5,"threadId":1}
实际(使用 SLF4J 记录器):
{"thread":"main","level":"INFO","loggerName":"com.logging.test.SampleLoggingTest","marker":{"name":"SLF4J_LOGGER"},"message":"Test Message","endOfBatch":false,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","instant":{"epochSecond":1571770198,"nanoOfSecond":746000000},"threadPriority":5,"threadId":1}
预期(使用 LOG4J 记录器):
{"thread":"main","level":"INFO","loggerName":"com.logging.test.SampleLoggingTest","marker":{"name":"LOG42L_LOGGER"},"message":{"firtsName":"john","lastName":"doe"},"endOfBatch":false,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","instant":{"epochSecond":1571770198,"nanoOfSecond":746000000},"threadPriority":5,"threadId":1}
问题
- 是否可以使用 SLF4J 记录器使用 log4j2 JSON 布局记录对象?如果是这样,任何示例都会有所帮助。
- 有没有更简单的方法可以将瞬间更改为人类可读的日期和时间戳格式?