Skip to content

Commit

Permalink
Remove unmaintained logback-contrib and replace by direct jackson (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
sschnabe authored May 17, 2023
1 parent 909fd62 commit 562cac6
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 37 deletions.
32 changes: 9 additions & 23 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>io.kokuwa.micronaut</groupId>
<artifactId>micronaut-logging</artifactId>
<version>3.1.1-SNAPSHOT</version>
<version>3.2.0-SNAPSHOT</version>

<name>Logging Support for Micronaut</name>
<description>Enhanced logging using MDC or request header.</description>
Expand Down Expand Up @@ -101,8 +101,8 @@
<!-- dependencies -->

<version.ch.qos.logback>1.2.12</version.ch.qos.logback>
<version.ch.qos.logback.contrib>0.1.5</version.ch.qos.logback.contrib>
<version.io.kokuwa.micronaut.logging>3.1.1-SNAPSHOT</version.io.kokuwa.micronaut.logging>
<version.com.fasterxml.jackson>2.15.0</version.com.fasterxml.jackson>
<version.io.kokuwa.micronaut.logging>3.2.0-SNAPSHOT</version.io.kokuwa.micronaut.logging>
<version.io.micronaut>3.9.1</version.io.micronaut>
<version.io.micronaut.security> 3.11.0</version.io.micronaut.security>
<version.org.slf4j.api>1.7.36</version.org.slf4j.api>
Expand Down Expand Up @@ -138,19 +138,9 @@
<version>${version.ch.qos.logback}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-json-classic</artifactId>
<version>${version.ch.qos.logback.contrib}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-json-core</artifactId>
<version>${version.ch.qos.logback.contrib}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-jackson</artifactId>
<version>${version.ch.qos.logback.contrib}</version>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${version.com.fasterxml.jackson}</version>
</dependency>

</dependencies>
Expand Down Expand Up @@ -217,13 +207,9 @@
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-json-classic</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-jackson</artifactId>
<scope>runtime</scope>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>provided</scope>
</dependency>

</dependencies>
Expand Down
2 changes: 1 addition & 1 deletion src/it/log-gcp-with-service/postbuild.bsh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// verify log

String expected = "^\\{\"time\":\"202[3-9]-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{0,3}Z\",\"severity\":\"INFO\",\"thread\":\"main\",\"logger\":\"io.kokuwa.micronaut.logging.LoggingTest\",\"message\":\"test-output-marker\",\"raw-message\":\"test-output-marker\",\"serviceContext\":\\{\"version\":\"0.1.2\",\"service\":\"test-service\"}}$";
String expected = "^\\{\"time\":\"202[3-9]-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{0,3}Z\",\"severity\":\"INFO\",\"thread\":\"main\",\"logger\":\"io.kokuwa.micronaut.logging.LoggingTest\",\"message\":\"test-output-marker\",\"raw-message\":\"test-output-marker\",\"serviceContext\":\\{\"service\":\"test-service\",\"version\":\"0.1.2\"}}$";
String[] logs = org.codehaus.plexus.util.FileUtils.fileRead(basedir + "/build.log").split("\n");

for (String log : logs) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package io.kokuwa.micronaut.logging.layout;

import java.time.Instant;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.contrib.json.classic.JsonLayout;
import io.micronaut.core.util.StringUtils;

/**
Expand Down Expand Up @@ -44,7 +42,7 @@ protected Map<String, Object> toJsonMap(ILoggingEvent event) {

private void addServiceContext(Map<String, Object> map) {
if (serviceContext == null) {
serviceContext = new HashMap<>(2);
serviceContext = new LinkedHashMap<>(2);
if (StringUtils.isNotEmpty(serviceName) && !serviceName.endsWith(UNDEFINED)) {
serviceContext.put("service", serviceName);
}
Expand Down
182 changes: 182 additions & 0 deletions src/main/java/io/kokuwa/micronaut/logging/layout/JsonLayout.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package io.kokuwa.micronaut.logging.layout;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TimeZone;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import ch.qos.logback.classic.pattern.ThrowableHandlingConverter;
import ch.qos.logback.classic.pattern.ThrowableProxyConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.CoreConstants;
import ch.qos.logback.core.LayoutBase;
import io.micronaut.http.MediaType;

public class JsonLayout extends LayoutBase<ILoggingEvent> {

public static final String TIMESTAMP_ATTR_NAME = "timestamp";
public static final String LEVEL_ATTR_NAME = "level";
public static final String THREAD_ATTR_NAME = "thread";
public static final String MDC_ATTR_NAME = "mdc";
public static final String LOGGER_ATTR_NAME = "logger";
public static final String FORMATTED_MESSAGE_ATTR_NAME = "message";
public static final String MESSAGE_ATTR_NAME = "raw-message";
public static final String EXCEPTION_ATTR_NAME = "exception";
public static final String CONTEXT_ATTR_NAME = "context";

private final ObjectMapper mapper = new ObjectMapper();

protected boolean includeLevel = true;
protected boolean includeThreadName = true;
protected boolean includeMDC = true;
protected boolean includeLoggerName = true;
protected boolean includeFormattedMessage = true;
protected boolean includeMessage = true;
protected boolean includeException = true;
protected boolean includeContextName = false;
protected boolean includeTimestamp = true;
private String timestampFormat;
private String timestampFormatTimezoneId;
private ThrowableHandlingConverter throwableHandlingConverter = new ThrowableProxyConverter();

@Override
public String getContentType() {
return MediaType.APPLICATION_JSON;
}

@Override
public void start() {
this.throwableHandlingConverter.start();
super.start();
}

@Override
public void stop() {
super.stop();
this.throwableHandlingConverter.stop();
}

@Override
public String doLayout(ILoggingEvent event) {
var map = toJsonMap(event);
try {
return mapper.writeValueAsString(map) + CoreConstants.LINE_SEPARATOR;
} catch (JsonProcessingException e) {
addError("Failed to write json from event " + event + " and map " + map, e);
return null;
}
}

protected Map<String, Object> toJsonMap(ILoggingEvent event) {
var map = new LinkedHashMap<String, Object>();
addTimestamp(TIMESTAMP_ATTR_NAME, includeTimestamp, event.getTimeStamp(), map);
add(LEVEL_ATTR_NAME, includeLevel, String.valueOf(event.getLevel()), map);
add(THREAD_ATTR_NAME, includeThreadName, event.getThreadName(), map);
addMap(MDC_ATTR_NAME, includeMDC, event.getMDCPropertyMap(), map);
add(LOGGER_ATTR_NAME, includeLoggerName, event.getLoggerName(), map);
add(FORMATTED_MESSAGE_ATTR_NAME, includeFormattedMessage, event.getFormattedMessage(), map);
add(MESSAGE_ATTR_NAME, includeMessage, event.getMessage(), map);
add(CONTEXT_ATTR_NAME, includeContextName, event.getLoggerContextVO().getName(), map);
addThrowableInfo(EXCEPTION_ATTR_NAME, includeException, event, map);
return map;
}

protected void addThrowableInfo(String fieldName, boolean field, ILoggingEvent value, Map<String, Object> map) {
if (field && value != null) {
var throwableProxy = value.getThrowableProxy();
if (throwableProxy != null) {
var ex = throwableHandlingConverter.convert(value);
if (ex != null && !ex.equals("")) {
map.put(fieldName, ex);
}
}
}
}

protected void addMap(String key, boolean field, Map<String, ?> mapValue, Map<String, Object> map) {
if (field && mapValue != null && !mapValue.isEmpty()) {
map.put(key, mapValue);
}
}

protected void addTimestamp(String key, boolean field, long timeStamp, Map<String, Object> map) {
if (field) {
var formatted = formatTimestamp(timeStamp);
if (formatted != null) {
map.put(key, formatted);
}
}
}

protected void add(String fieldName, boolean field, String value, Map<String, Object> map) {
if (field && value != null) {
map.put(fieldName, value);
}
}

protected String formatTimestamp(long timestamp) {
if (timestampFormat == null || timestamp < 0) {
return String.valueOf(timestamp);
}
var date = new Date(timestamp);
var format = new SimpleDateFormat(timestampFormat);
if (timestampFormatTimezoneId != null) {
format.setTimeZone(TimeZone.getTimeZone(timestampFormatTimezoneId));
}
return format.format(date);
}

// setter

public void setIncludeLevel(boolean includeLevel) {
this.includeLevel = includeLevel;
}

public void setIncludeThreadName(boolean includeThreadName) {
this.includeThreadName = includeThreadName;
}

public void setIncludeMDC(boolean includeMDC) {
this.includeMDC = includeMDC;
}

public void setIncludeLoggerName(boolean includeLoggerName) {
this.includeLoggerName = includeLoggerName;
}

public void setIncludeFormattedMessage(boolean includeFormattedMessage) {
this.includeFormattedMessage = includeFormattedMessage;
}

public void setIncludeMessage(boolean includeMessage) {
this.includeMessage = includeMessage;
}

public void setIncludeException(boolean includeException) {
this.includeException = includeException;
}

public void setIncludeContextName(boolean includeContextName) {
this.includeContextName = includeContextName;
}

public void setIncludeTimestamp(boolean includeTimestamp) {
this.includeTimestamp = includeTimestamp;
}

public void setTimestampFormat(String timestampFormat) {
this.timestampFormat = timestampFormat;
}

public void setTimestampFormatTimezoneId(String timestampFormatTimezoneId) {
this.timestampFormatTimezoneId = timestampFormatTimezoneId;
}

public void setThrowableHandlingConverter(ThrowableHandlingConverter throwableHandlingConverter) {
this.throwableHandlingConverter = throwableHandlingConverter;
}
}
4 changes: 0 additions & 4 deletions src/main/resources/io/kokuwa/logback/appender-gcp.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@
<layout class="io.kokuwa.micronaut.logging.layout.GcpJsonLayout">
<serviceName>${SERVICE_NAME}</serviceName>
<serviceVersion>${SERVICE_VERSION}</serviceVersion>
<jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter" />
<appendLineSeparator>true</appendLineSeparator>
<includeMessage>true</includeMessage>
<includeContextName>false</includeContextName>
</layout>
</encoder>
</appender>
Expand Down
7 changes: 1 addition & 6 deletions src/main/resources/io/kokuwa/logback/appender-json.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@

<appender name="JSON" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
<jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter" />
<appendLineSeparator>true</appendLineSeparator>
<includeMessage>true</includeMessage>
<includeContextName>false</includeContextName>
</layout>
<layout class="io.kokuwa.micronaut.logging.layout.JsonLayout" />
</encoder>
</appender>

Expand Down

0 comments on commit 562cac6

Please sign in to comment.