Skip to content

Add StructuredLogFormatter wrapper for JsonEncoder (logback) #210

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cf-java-logging-support-logback/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
<artifactId>cf-java-logging-support-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>com.sap.hcp.cf.logging</groupId>
<artifactId>cf-java-logging-support-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.sap.hcp.cf.logback.boot;

import ch.qos.logback.classic.spi.ILoggingEvent;
import com.sap.hcp.cf.logback.encoder.JsonEncoder;
import org.springframework.boot.logging.structured.StructuredLogFormatter;

/**
* A Logback events formatter for structured logging in SpringBoot
* configuration, suited
* for Cloud Foundry applications. This class can be used as a value for
* {@code logging.structured.format.console}
* or @{code logging.structured.format.file} in a SpringBoot applications.
* <p>
* This is a simple wrapper around the {@code JsonEncoder} created for Logback.
* This formatter does not accept any configuration parameters and uses the default
* settings coming with JsonEncoder. The JSON output will contain the same fields
* as produced with {@code JsonEncoder}, but you don't have to use logback.xml
* (or logback-spring.xml) to use it.
* <p>
* Example usage with SpringBoot ({@code application.properties}):
*
* <pre>
* logging.structured.format.console = com.sap.hcp.cf.logback.boot.CloudFoundryStructuredLogFormatter
* </pre>
*/
public class CloudFoundryStructuredLogFormatter implements StructuredLogFormatter<ILoggingEvent> {

private final JsonEncoder jsonEncoder;

public CloudFoundryStructuredLogFormatter() {
this.jsonEncoder = JsonEncoder.createStarted();
}

@Override
public String format(ILoggingEvent event) {
return jsonEncoder.getJson(event);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.jr.ob.JSON;
import com.fasterxml.jackson.jr.ob.JSON.Builder;
Expand Down Expand Up @@ -78,6 +77,19 @@ public JsonEncoder() {
logbackContextFieldSuppliers.add(new RequestRecordFieldSupplier());
}

/**
* Creates a new encoder instance in the {@code started} state, with default settings.
* This means that the encoder is ready to encode log events once this method returns.
*
* @return a new {@link JsonEncoder} instance in the started state
*/
public static JsonEncoder createStarted() {
JsonEncoder encoder = new JsonEncoder();
encoder.start();

return encoder;
}

/**
* <p>
* Adds a field to the "#cf" object in the generated output. If the log
Expand Down Expand Up @@ -286,7 +298,11 @@ public byte[] encode(ILoggingEvent event) {
return getJson(event).getBytes(charset);
}

private String getJson(ILoggingEvent event) {
public String getJson(ILoggingEvent event) {
if(!isStarted()) {
throw new IllegalStateException("Encoder is not started. Please call start() before encoding.");
}

try (StringWriter writer = new StringWriter()) {
ObjectComposer<JSONComposer<OutputStream>> oc = json.composeTo(writer).startObject();
addMarkers(oc, event);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.sap.hcp.cf.logback.boot;

import static org.junit.Assert.assertTrue;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.LoggingEvent;
import org.junit.Test;

public class CloudFoundryStructuredLogFormatterTest {

CloudFoundryStructuredLogFormatter underTest = new CloudFoundryStructuredLogFormatter();

@Test
public void testFormat() throws Exception {
LoggingEvent event = new LoggingEvent();
event.setLevel(Level.DEBUG);
event.setLoggerName("my-logger");
event.setMessage("This is some very important log message");
event.setThreadName("thread-1");

String result = underTest.format(event);

assertTrue(result.startsWith("{"));
assertTrue(result.endsWith("}\n"));
assertTrue(result.contains("\"level\":\"DEBUG\""));
assertTrue(result.contains("\"logger\":\"my-logger\""));
assertTrue(result.contains("\"msg\":\"This is some very important log message\""));
assertTrue(result.contains("\"thread\":\"thread-1\""));

}

}
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
<java-jwt.version>4.4.0</java-jwt.version>
<jackson-databind.version>2.18.2</jackson-databind.version>
<httpclient.version>4.5.14</httpclient.version>
<springboot.version>3.4.5</springboot.version>
</properties>

<modules>
Expand Down