com.sap.hcp.cf.logging
cf-java-logging-support-core
diff --git a/cf-java-logging-support-logback/src/main/java/com/sap/hcp/cf/logback/boot/CloudFoundryStructuredLogFormatter.java b/cf-java-logging-support-logback/src/main/java/com/sap/hcp/cf/logback/boot/CloudFoundryStructuredLogFormatter.java
new file mode 100644
index 0000000..f399a7c
--- /dev/null
+++ b/cf-java-logging-support-logback/src/main/java/com/sap/hcp/cf/logback/boot/CloudFoundryStructuredLogFormatter.java
@@ -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.
+ *
+ * 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.
+ *
+ * Example usage with SpringBoot ({@code application.properties}):
+ *
+ *
+ * logging.structured.format.console = com.sap.hcp.cf.logback.boot.CloudFoundryStructuredLogFormatter
+ *
+ */
+public class CloudFoundryStructuredLogFormatter implements StructuredLogFormatter {
+
+ private final JsonEncoder jsonEncoder;
+
+ public CloudFoundryStructuredLogFormatter() {
+ this.jsonEncoder = JsonEncoder.createStarted();
+ }
+
+ @Override
+ public String format(ILoggingEvent event) {
+ return jsonEncoder.getJson(event);
+ }
+
+}
diff --git a/cf-java-logging-support-logback/src/main/java/com/sap/hcp/cf/logback/encoder/JsonEncoder.java b/cf-java-logging-support-logback/src/main/java/com/sap/hcp/cf/logback/encoder/JsonEncoder.java
index 45efe06..dd28641 100644
--- a/cf-java-logging-support-logback/src/main/java/com/sap/hcp/cf/logback/encoder/JsonEncoder.java
+++ b/cf-java-logging-support-logback/src/main/java/com/sap/hcp/cf/logback/encoder/JsonEncoder.java
@@ -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;
@@ -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;
+ }
+
/**
*
* Adds a field to the "#cf" object in the generated output. If the log
@@ -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> oc = json.composeTo(writer).startObject();
addMarkers(oc, event);
diff --git a/cf-java-logging-support-logback/src/test/java/com/sap/hcp/cf/logback/boot/CloudFoundryStructuredLogFormatterTest.java b/cf-java-logging-support-logback/src/test/java/com/sap/hcp/cf/logback/boot/CloudFoundryStructuredLogFormatterTest.java
new file mode 100644
index 0000000..5abd292
--- /dev/null
+++ b/cf-java-logging-support-logback/src/test/java/com/sap/hcp/cf/logback/boot/CloudFoundryStructuredLogFormatterTest.java
@@ -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\""));
+
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index f3425f8..09e1ba3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -147,6 +147,7 @@
4.4.0
2.18.2
4.5.14
+ 3.4.5