BAEL-1230: Get Java Logs into the JSON Format (#3381)

* Added code for BAEL-1230: Getting log in JSON format

* Added code for BAEL-1230: Getting log in JSON format

* Improved tests to check correct JSON format in logs

* Renamed Test classes to make clear what they do

* Fixed wrong indentation
This commit is contained in:
Miguel Rivero 2018-01-20 16:35:48 +01:00 committed by Grzegorz Piwowarek
parent a3585ddc8e
commit 740073b6ad
6 changed files with 169 additions and 32 deletions

View File

@ -59,10 +59,10 @@
<properties>
<jackson.version>2.8.5</jackson.version>
<jackson.version>2.9.3</jackson.version>
<h2.version>1.4.193</h2.version>
<commons-dbcp2.version>2.1.1</commons-dbcp2.version>
<log4j-core.version>2.7</log4j-core.version>
<log4j-core.version>2.10.0</log4j-core.version>
</properties>
</project>

View File

@ -0,0 +1,45 @@
package com.baeldung.logging.log4j2.tests;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JSONLayoutTest {
private static Logger logger;
private ByteArrayOutputStream consoleOutput = new ByteArrayOutputStream();
private PrintStream ps = new PrintStream(consoleOutput);
@Before
public void setUp() {
// Redirect console output to our stream
System.setOut(ps);
logger = LogManager.getLogger("CONSOLE_JSON_APPENDER");
}
@Test
public void whenLogLayoutInJSON_thenOutputIsCorrectJSON() {
logger.debug("Debug message");
String currentLog = consoleOutput.toString();
assertTrue(!currentLog.isEmpty() && isValidJSON(currentLog));
}
public static boolean isValidJSON(String jsonInString) {
try {
final ObjectMapper mapper = new ObjectMapper();
mapper.readTree(jsonInString);
return true;
} catch (IOException e) {
return false;
}
}
}

View File

@ -1,16 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns:xi="http://www.w3.org/2001/XInclude" status="WARN">
<Configuration xmlns:xi="http://www.w3.org/2001/XInclude"
status="WARN">
<Appenders>
<xi:include href="log4j2-includes/console-appender_pattern-layout_colored.xml" />
<xi:include
href="log4j2-includes/console-appender_pattern-layout_colored.xml" />
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d [%t] %-5level %logger{36} - %msg%n%throwable" />
<PatternLayout
pattern="%d [%t] %-5level %logger{36} - %msg%n%throwable" />
</Console>
<Console name="ConsoleRedAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%style{%message}{red}%n" />
<MarkerFilter marker="CONN_TRACE" />
</Console>
<Console name="ConsoleGreenAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%style{userId=%X{userId}:}{white} %style{%message}{green}%n" />
<PatternLayout
pattern="%style{userId=%X{userId}:}{white} %style{%message}{green}%n" />
</Console>
<Console name="ConsoleJSONAppender" target="SYSTEM_OUT">
<JsonLayout complete="false" compact="false">
<KeyValuePair key="myCustomField" value="myCustomValue" />
</JsonLayout>
</Console>
<File name="JSONLogfileAppender" fileName="target/logfile.json">
<JSONLayout compact="true" eventEol="true" />
@ -19,53 +28,58 @@
<Async name="AsyncAppender" bufferSize="80">
<AppenderRef ref="JSONLogfileAppender" />
</Async>
<!--
<Syslog name="Syslog" format="RFC5424" host="localhost" port="514" protocol="TCP" facility="local3" connectTimeoutMillis="10000" reconnectionDelayMillis="5000" mdcId="mdc" includeMDC="true" />
<Failover name="FailoverAppender" primary="Syslog">
<Failovers>
<AppenderRef ref="ConsoleAppender" />
</Failovers>
</Failover>
-->
<!-- <Syslog name="Syslog" format="RFC5424" host="localhost" port="514"
protocol="TCP" facility="local3" connectTimeoutMillis="10000" reconnectionDelayMillis="5000"
mdcId="mdc" includeMDC="true" /> <Failover name="FailoverAppender" primary="Syslog">
<Failovers> <AppenderRef ref="ConsoleAppender" /> </Failovers> </Failover> -->
<JDBC name="JDBCAppender" tableName="logs">
<ConnectionFactory class="com.baeldung.logging.log4j2.tests.jdbc.ConnectionFactory" method="getConnection" />
<ConnectionFactory
class="com.baeldung.logging.log4j2.tests.jdbc.ConnectionFactory"
method="getConnection" />
<Column name="when" isEventTimestamp="true" />
<Column name="logger" pattern="%logger" />
<Column name="level" pattern="%level" />
<Column name="message" pattern="%message" />
<Column name="throwable" pattern="%ex{full}" />
</JDBC>
<RollingFile name="XMLRollingfileAppender" fileName="target/logfile.xml" filePattern="target/logfile-%d{yyyy-MM-dd}-%i.log.gz">
<RollingFile name="XMLRollingfileAppender" fileName="target/logfile.xml"
filePattern="target/logfile-%d{yyyy-MM-dd}-%i.log.gz">
<XMLLayout />
<Policies>
<SizeBasedTriggeringPolicy size="17 kB" />
<SizeBasedTriggeringPolicy
size="17 kB" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="CONSOLE_PATTERN_APPENDER_MARKER" level="TRACE" additivity="false">
<Logger name="CONSOLE_PATTERN_APPENDER_MARKER" level="TRACE"
additivity="false">
<AppenderRef ref="ConsoleRedAppender" />
</Logger>
<Logger name="CONSOLE_PATTERN_APPENDER_THREAD_CONTEXT" level="INFO" additivity="false">
<Logger name="CONSOLE_PATTERN_APPENDER_THREAD_CONTEXT"
level="INFO" additivity="false">
<AppenderRef ref="ConsoleGreenAppender" />
<ThreadContextMapFilter>
<KeyValuePair key="userId" value="1000" />
</ThreadContextMapFilter>
</Logger>
<Logger name="ASYNC_JSON_FILE_APPENDER" level="INFO" additivity="false">
<Logger name="ASYNC_JSON_FILE_APPENDER" level="INFO"
additivity="false">
<AppenderRef ref="AsyncAppender" />
</Logger>
<!--
<Logger name="FAIL_OVER_SYSLOG_APPENDER" level="INFO" additivity="false">
<AppenderRef ref="FailoverAppender" />
</Logger>
-->
<!-- <Logger name="FAIL_OVER_SYSLOG_APPENDER" level="INFO" additivity="false">
<AppenderRef ref="FailoverAppender" /> </Logger> -->
<Logger name="JDBC_APPENDER" level="INFO" additivity="false">
<AppenderRef ref="JDBCAppender" />
</Logger>
<Logger name="XML_ROLLING_FILE_APPENDER" level="INFO" additivity="false">
<Logger name="XML_ROLLING_FILE_APPENDER" level="INFO"
additivity="false">
<AppenderRef ref="XMLRollingfileAppender" />
</Logger>
<Logger name="CONSOLE_JSON_APPENDER" level="TRACE"
additivity="false">
<AppenderRef ref="ConsoleJSONAppender" />
</Logger>
<Root level="DEBUG">
<AppenderRef ref="ConsoleAppender" />
</Root>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
@ -12,6 +12,8 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<logback.version>1.2.3</logback.version>
<logback.contrib.version>0.1.5</logback.contrib.version>
<jackson.version>2.9.3</jackson.version>
</properties>
<parent>
@ -28,7 +30,21 @@
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-json-classic</artifactId>
<version>${logback.contrib.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-jackson</artifactId>
<version>${logback.contrib.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>

View File

@ -0,0 +1,45 @@
package com.baeldung.logback;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JSONLayoutTest {
private static Logger logger;
private ByteArrayOutputStream consoleOutput = new ByteArrayOutputStream();
private PrintStream ps = new PrintStream(consoleOutput);
@Before
public void setUp() {
// Redirect console output to our stream
System.setOut(ps);
logger = LoggerFactory.getLogger("jsonLogger");
}
@Test
public void whenLogLayoutInJSON_thenOutputIsCorrectJSON() {
logger.debug("Debug message");
String currentLog = consoleOutput.toString();
assertTrue(!currentLog.isEmpty() && isValidJSON(currentLog));
}
public static boolean isValidJSON(String jsonInString) {
try {
final ObjectMapper mapper = new ObjectMapper();
mapper.readTree(jsonInString);
return true;
} catch (IOException e) {
return false;
}
}
}

View File

@ -1,14 +1,31 @@
<configuration debug="true">
<configuration debug="false">
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
<appender name="map" class="com.baeldung.logback.MapAppender">
<prefix>test</prefix>
</appender>
<appender name="badMap" class="com.baeldung.logback.MapAppender"/>
<appender name="badMap" class="com.baeldung.logback.MapAppender" />
# JSON appender
<appender name="json" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
<jsonFormatter
class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
<prettyPrint>true</prettyPrint>
</jsonFormatter>
<timestampFormat>yyyy-MM-dd' 'HH:mm:ss.SSS</timestampFormat>
</layout>
</appender>
<logger name="jsonLogger" level="TRACE">
<appender-ref ref="json" />
</logger>
<root level="debug">
<appender-ref ref="map"/>
<appender-ref ref="badMap"/>
<appender-ref ref="map" />
<appender-ref ref="badMap" />
</root>
</configuration>