diff --git a/ecs-logging-core/src/main/java/co/elastic/logging/EcsJsonSerializer.java b/ecs-logging-core/src/main/java/co/elastic/logging/EcsJsonSerializer.java index e3960b90..cbfa1128 100644 --- a/ecs-logging-core/src/main/java/co/elastic/logging/EcsJsonSerializer.java +++ b/ecs-logging-core/src/main/java/co/elastic/logging/EcsJsonSerializer.java @@ -103,6 +103,21 @@ public static void serializeTag(StringBuilder builder, String tag) { } } + public static void serializeTagStart(StringBuilder builder) { + builder.append("\"tags\":["); + } + + public static void serializeSingleTag(StringBuilder builder, String tag) { + if (tag != null) { + builder.append("\"").append(tag).append("\","); + } + } + + public static void serializeTagEnd(StringBuilder builder) { + builder.setLength(builder.length() - 1); + builder.append("],"); + } + public static void serializeLabels(StringBuilder builder, Map labels, Set topLevelLabels) { if (!labels.isEmpty()) { for (Map.Entry entry : labels.entrySet()) { diff --git a/log4j2-ecs-layout/README.md b/log4j2-ecs-layout/README.md index 0671b804..1dac33fa 100644 --- a/log4j2-ecs-layout/README.md +++ b/log4j2-ecs-layout/README.md @@ -17,7 +17,14 @@ Add a dependency to your application ## Step 2: use the `EcsLayout` -Instead of the usual ``, use `` +Instead of the usual ``, use ``. + +If you want to include [Markers](https://logging.apache.org/log4j/2.0/manual/markers.html) as tags, +set the `includeMarkers` attribute to `true` (default: `false`). + +``` + +``` ## Example ```xml diff --git a/log4j2-ecs-layout/src/main/java/co/elastic/logging/log4j2/EcsLayout.java b/log4j2-ecs-layout/src/main/java/co/elastic/logging/log4j2/EcsLayout.java index 58d6e18d..c11565b9 100644 --- a/log4j2-ecs-layout/src/main/java/co/elastic/logging/log4j2/EcsLayout.java +++ b/log4j2-ecs-layout/src/main/java/co/elastic/logging/log4j2/EcsLayout.java @@ -27,6 +27,7 @@ import co.elastic.logging.EcsJsonSerializer; import co.elastic.logging.JsonUtils; +import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.core.Layout; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.config.Configuration; @@ -59,6 +60,7 @@ public class EcsLayout extends AbstractStringLayout { private static final ThreadLocal messageStringBuilder = new ThreadLocal(); + public static final Charset UTF_8 = Charset.forName("UTF-8"); private final TriConsumer WRITE_KEY_VALUES_INTO = new TriConsumer() { @Override @@ -77,10 +79,12 @@ public void accept(final String key, final Object value, final StringBuilder str private final KeyValuePair[] additionalFields; private final Set topLevelLabels; private String serviceName; + private boolean includeMarkers; - private EcsLayout(Configuration config, String serviceName, KeyValuePair[] additionalFields, Collection topLevelLabels) { - super(config, Charset.forName("UTF-8"), null, null); + private EcsLayout(Configuration config, String serviceName, boolean includeMarkers, KeyValuePair[] additionalFields, Collection topLevelLabels) { + super(config, UTF_8, null, null); this.serviceName = serviceName; + this.includeMarkers = includeMarkers; this.topLevelLabels = new HashSet(topLevelLabels); this.topLevelLabels.add("trace.id"); this.topLevelLabels.add("transaction.id"); @@ -163,16 +167,36 @@ private void serializeLabels(LogEvent event, StringBuilder builder) { private void serializeTags(LogEvent event, StringBuilder builder) { List contextStack = event.getContextStack().asList(); + Marker marker = event.getMarker(); + boolean hasTags = !contextStack.isEmpty() || (includeMarkers && marker != null); + if (hasTags) { + EcsJsonSerializer.serializeTagStart(builder); + } + if (!contextStack.isEmpty()) { - builder.append("\"tags\":["); for (int i = 0; i < contextStack.size(); i++) { builder.append('\"'); JsonUtils.quoteAsString(contextStack.get(i), builder); builder.append("\","); } - // removes last comma - builder.setLength(builder.length() - 1); - builder.append("],"); + } + + if (includeMarkers && marker != null) { + serializeMarker(builder, marker); + } + + if (hasTags) { + EcsJsonSerializer.serializeTagEnd(builder); + } + } + + private void serializeMarker(StringBuilder builder, Marker marker) { + EcsJsonSerializer.serializeSingleTag(builder, marker.getName()); + if (marker.hasParents()) { + Marker[] parents = marker.getParents(); + for (int i = 0; i < parents.length; i++) { + serializeMarker(builder, parents[i]); + } } } @@ -215,6 +239,8 @@ public static class Builder extends AbstractStringLayout.BuilderemptyList() : Arrays.asList(topLevelLabels)); + return new EcsLayout(getConfiguration(), serviceName, includeMarkers, additionalFields, topLevelLabels == null ? Collections.emptyList() : Arrays.asList(topLevelLabels)); } } } diff --git a/log4j2-ecs-layout/src/test/java/co/elastic/logging/log4j2/AbstractLog4j2EcsLayoutTest.java b/log4j2-ecs-layout/src/test/java/co/elastic/logging/log4j2/AbstractLog4j2EcsLayoutTest.java new file mode 100644 index 00000000..db1cb304 --- /dev/null +++ b/log4j2-ecs-layout/src/test/java/co/elastic/logging/log4j2/AbstractLog4j2EcsLayoutTest.java @@ -0,0 +1,99 @@ +/*- + * #%L + * Java ECS logging + * %% + * Copyright (C) 2019 Elastic and contributors + * %% + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * #L% + */ +package co.elastic.logging.log4j2; + +import co.elastic.logging.AbstractEcsLoggingTest; +import com.fasterxml.jackson.databind.node.TextNode; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; +import org.apache.logging.log4j.ThreadContext; +import org.apache.logging.log4j.core.Logger; +import org.apache.logging.log4j.message.StringMapMessage; +import org.apache.logging.log4j.test.appender.ListAppender; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +abstract class AbstractLog4j2EcsLayoutTest extends AbstractEcsLoggingTest { + protected Logger root; + protected ListAppender listAppender; + + @AfterEach + void tearDown() throws Exception { + ThreadContext.clearAll(); + } + + @Test + void globalLabels() throws Exception { + putMdc("trace.id", "foo"); + debug("test"); + assertThat(getLastLogLine().get("cluster.uuid").textValue()).isEqualTo("9fe9134b-20b0-465e-acf9-8cc09ac9053b"); + assertThat(getLastLogLine().get("node.id").textValue()).isEqualTo("foo"); + assertThat(getLastLogLine().get("404")).isNull(); + } + + @Test + void testMarker() throws Exception { + Marker parent = MarkerManager.getMarker("parent"); + Marker child = MarkerManager.getMarker("child").setParents(parent); + Marker grandchild = MarkerManager.getMarker("grandchild").setParents(child); + root.debug(grandchild, "test"); + + assertThat(getLastLogLine().get("tags")).contains( + TextNode.valueOf("parent"), + TextNode.valueOf("child"), + TextNode.valueOf("grandchild")); + } + + @Test + void testMapMessage() throws Exception { + root.info(new StringMapMessage(Map.of("foo", "bar"))); + assertThat(getLastLogLine().get("labels.foo").textValue()).isEqualTo("bar"); + } + + @Override + public void putMdc(String key, String value) { + ThreadContext.put(key, value); + } + + @Override + public boolean putNdc(String message) { + ThreadContext.push(message); + return true; + } + + @Override + public void debug(String message) { + root.debug(message); + } + + @Override + public void error(String message, Throwable t) { + root.error(message, t); + } +} diff --git a/log4j2-ecs-layout/src/test/java/co/elastic/logging/log4j2/Log4j2EcsLayoutIntegrationTest.java b/log4j2-ecs-layout/src/test/java/co/elastic/logging/log4j2/Log4j2EcsLayoutIntegrationTest.java new file mode 100644 index 00000000..19f05e7a --- /dev/null +++ b/log4j2-ecs-layout/src/test/java/co/elastic/logging/log4j2/Log4j2EcsLayoutIntegrationTest.java @@ -0,0 +1,52 @@ +/*- + * #%L + * Java ECS logging + * %% + * Copyright (C) 2019 Elastic and contributors + * %% + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * #L% + */ +package co.elastic.logging.log4j2; + +import com.fasterxml.jackson.databind.JsonNode; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.test.appender.ListAppender; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; + +import java.io.IOException; + +class Log4j2EcsLayoutIntegrationTest extends AbstractLog4j2EcsLayoutTest { + @BeforeEach + void setUp() { + root = LoggerContext.getContext().getRootLogger(); + listAppender = (ListAppender) root.getAppenders().get("TestAppender"); + } + + @AfterEach + void tearDown() throws Exception { + super.tearDown(); + listAppender.clear(); + } + + @Override + public JsonNode getLastLogLine() throws IOException { + return objectMapper.readTree(listAppender.getMessages().get(0)); + } +} diff --git a/log4j2-ecs-layout/src/test/java/co/elastic/logging/log4j2/Log4j2EcsLayoutTest.java b/log4j2-ecs-layout/src/test/java/co/elastic/logging/log4j2/Log4j2EcsLayoutTest.java index 58801558..6043111d 100644 --- a/log4j2-ecs-layout/src/test/java/co/elastic/logging/log4j2/Log4j2EcsLayoutTest.java +++ b/log4j2-ecs-layout/src/test/java/co/elastic/logging/log4j2/Log4j2EcsLayoutTest.java @@ -11,9 +11,9 @@ * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -24,58 +24,50 @@ */ package co.elastic.logging.log4j2; -import co.elastic.logging.AbstractEcsLoggingTest; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.ThreadContext; import org.apache.logging.log4j.core.Appender; import org.apache.logging.log4j.core.BasicConfigurationFactory; -import org.apache.logging.log4j.core.Logger; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.config.ConfigurationFactory; import org.apache.logging.log4j.core.util.KeyValuePair; -import org.apache.logging.log4j.message.StringMapMessage; import org.apache.logging.log4j.test.appender.ListAppender; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import java.io.IOException; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; - -class Log4j2EcsLayoutTest extends AbstractEcsLoggingTest { +class Log4j2EcsLayoutTest extends AbstractLog4j2EcsLayoutTest { private static ConfigurationFactory configFactory = new BasicConfigurationFactory(); - private LoggerContext ctx = LoggerContext.getContext(); - private Logger root = ctx.getRootLogger(); - private ObjectMapper objectMapper = new ObjectMapper(); - private ListAppender listAppender; + private LoggerContext ctx; @AfterAll - public static void cleanupClass() { + static void cleanupClass() { ConfigurationFactory.removeConfigurationFactory(configFactory); } @BeforeAll - public static void setupClass() { + static void setupClass() { ConfigurationFactory.setConfigurationFactory(configFactory); - final LoggerContext ctx = LoggerContext.getContext(); - ctx.reconfigure(); } @BeforeEach - public void setUp() throws Exception { + void setUp() { + ctx = new LoggerContext("Test"); + ctx.reconfigure(); + ctx.getConfiguration().getProperties().put("node.id", "foo"); + + root = ctx.getRootLogger(); + for (final Appender appender : root.getAppenders().values()) { root.removeAppender(appender); } EcsLayout ecsLayout = EcsLayout.newBuilder() .setConfiguration(ctx.getConfiguration()) .setServiceName("test") + .setIncludeMarkers(true) .setAdditionalFields(new KeyValuePair[]{ new KeyValuePair("cluster.uuid", "9fe9134b-20b0-465e-acf9-8cc09ac9053b"), new KeyValuePair("node.id", "${node.id}"), @@ -87,55 +79,17 @@ public void setUp() throws Exception { listAppender.start(); root.addAppender(listAppender); root.setLevel(Level.DEBUG); - ctx.getConfiguration().getProperties().put("node.id", "foo"); } @AfterEach - public void tearDown() throws Exception { - ThreadContext.clearAll(); - } - - @Test - void globalLabels() throws Exception { - putMdc("trace.id", "foo"); - debug("test"); - assertThat(getLastLogLine().get("cluster.uuid").textValue()).isEqualTo("9fe9134b-20b0-465e-acf9-8cc09ac9053b"); - assertThat(getLastLogLine().get("node.id").textValue()).isEqualTo("foo"); - assertThat(getLastLogLine().get("empty")).isNull(); - assertThat(getLastLogLine().get("404")).isNull(); - } - - @Test - void testMapMessage() throws Exception { - root.info(new StringMapMessage(Map.of("foo", "bar"))); - assertThat(getLastLogLine().get("labels.foo").textValue()).isEqualTo("bar"); - } - - @Override - public void putMdc(String key, String value) { - ThreadContext.put(key, value); - } - - @Override - public boolean putNdc(String message) { - ThreadContext.push(message); - return true; - } - - @Override - public void debug(String message) { - root.debug(message); - } - @Override - public void error(String message, Throwable t) { - root.error(message, t); + void tearDown() throws Exception { + super.tearDown(); + ctx.close(); } @Override public JsonNode getLastLogLine() throws IOException { - String content = listAppender.getMessages().get(0); - System.out.println(content); - return objectMapper.readTree(content); + return objectMapper.readTree(listAppender.getMessages().get(0)); } } diff --git a/log4j2-ecs-layout/src/test/resources/log4j2-test.xml b/log4j2-ecs-layout/src/test/resources/log4j2-test.xml new file mode 100644 index 00000000..cc9f56c1 --- /dev/null +++ b/log4j2-ecs-layout/src/test/resources/log4j2-test.xml @@ -0,0 +1,20 @@ + + + + foo + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/logback-ecs-encoder/README.md b/logback-ecs-encoder/README.md index cc122299..39b13089 100644 --- a/logback-ecs-encoder/README.md +++ b/logback-ecs-encoder/README.md @@ -21,6 +21,8 @@ All you have to do is to use the `co.elastic.logging.logback.EcsEncoder` instead ```xml my-application + + true ``` @@ -56,5 +58,4 @@ All you have to do is to use the `co.elastic.logging.logback.EcsEncoder` instead --> - ``` \ No newline at end of file diff --git a/logback-ecs-encoder/src/main/java/co/elastic/logging/logback/EcsEncoder.java b/logback-ecs-encoder/src/main/java/co/elastic/logging/logback/EcsEncoder.java index b0f185b5..fe1899da 100644 --- a/logback-ecs-encoder/src/main/java/co/elastic/logging/logback/EcsEncoder.java +++ b/logback-ecs-encoder/src/main/java/co/elastic/logging/logback/EcsEncoder.java @@ -29,15 +29,18 @@ import ch.qos.logback.core.encoder.EncoderBase; import co.elastic.logging.EcsJsonSerializer; import co.elastic.logging.JsonUtils; +import org.slf4j.Marker; import java.nio.charset.Charset; import java.util.HashSet; +import java.util.Iterator; import java.util.Set; public class EcsEncoder extends EncoderBase { private static final Charset UTF_8 = Charset.forName("UTF-8"); private String serviceName; + private boolean includeMarkers = false; private ThrowableProxyConverter throwableProxyConverter; private Set topLevelLabels = new HashSet(EcsJsonSerializer.DEFAULT_TOP_LEVEL_LABELS); @@ -60,6 +63,7 @@ public byte[] encode(ILoggingEvent event) { EcsJsonSerializer.serializeLogLevel(builder, event.getLevel().toString()); EcsJsonSerializer.serializeFormattedMessage(builder, event.getFormattedMessage(), null); serializeException(event, builder); + serializeMarkers(event, builder); EcsJsonSerializer.serializeServiceName(builder, serviceName); EcsJsonSerializer.serializeThreadName(builder, event.getThreadName()); EcsJsonSerializer.serializeLoggerName(builder, event.getLoggerName()); @@ -69,6 +73,25 @@ public byte[] encode(ILoggingEvent event) { return builder.toString().getBytes(UTF_8); } + private void serializeMarkers(ILoggingEvent event, StringBuilder builder) { + Marker marker = event.getMarker(); + if (includeMarkers && marker != null) { + EcsJsonSerializer.serializeTagStart(builder); + serializeMarker(builder, marker); + EcsJsonSerializer.serializeTagEnd(builder); + } + } + + private void serializeMarker(StringBuilder builder, Marker marker) { + if (marker != null) { + EcsJsonSerializer.serializeSingleTag(builder, marker.getName()); + Iterator it = marker.iterator(); + while (it.hasNext()) { + serializeMarker(builder, it.next()); + } + } + } + private void serializeException(ILoggingEvent event, StringBuilder builder) { if (event.getThrowableProxy() != null) { // remove `", ` @@ -87,4 +110,8 @@ public byte[] footerBytes() { public void setServiceName(String serviceName) { this.serviceName = serviceName; } + + public void setIncludeMarkers(boolean includeMarkers) { + this.includeMarkers = includeMarkers; + } } diff --git a/logback-ecs-encoder/src/test/java/co/elastic/logging/logback/AbstractEcsEncoderTest.java b/logback-ecs-encoder/src/test/java/co/elastic/logging/logback/AbstractEcsEncoderTest.java new file mode 100644 index 00000000..984d4b40 --- /dev/null +++ b/logback-ecs-encoder/src/test/java/co/elastic/logging/logback/AbstractEcsEncoderTest.java @@ -0,0 +1,69 @@ +/*- + * #%L + * Java ECS logging + * %% + * Copyright (C) 2019 Elastic and contributors + * %% + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * #L% + */ +package co.elastic.logging.logback; + +import ch.qos.logback.classic.Logger; +import co.elastic.logging.AbstractEcsLoggingTest; +import com.fasterxml.jackson.databind.node.TextNode; +import org.junit.jupiter.api.Test; +import org.slf4j.MDC; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +import static org.assertj.core.api.Assertions.assertThat; + +abstract class AbstractEcsEncoderTest extends AbstractEcsLoggingTest { + protected Logger logger; + + @Override + public void putMdc(String key, String value) { + MDC.put(key, value); + } + + @Override + public void debug(String message) { + logger.debug(message); + } + + @Test + void testMarker() throws Exception { + Marker parent = MarkerFactory.getMarker("parent"); + Marker child = MarkerFactory.getMarker("child"); + Marker grandchild = MarkerFactory.getMarker("grandchild"); + child.add(grandchild); + parent.add(child); + logger.debug(parent, "test"); + + assertThat(getLastLogLine().get("tags")).contains( + TextNode.valueOf("parent"), + TextNode.valueOf("child"), + TextNode.valueOf("grandchild")); + } + + @Override + public void error(String message, Throwable t) { + logger.error(message, t); + } +} diff --git a/logback-ecs-encoder/src/test/java/co/elastic/logging/logback/EcsEncoderIntegrationTest.java b/logback-ecs-encoder/src/test/java/co/elastic/logging/logback/EcsEncoderIntegrationTest.java new file mode 100644 index 00000000..f206ef3d --- /dev/null +++ b/logback-ecs-encoder/src/test/java/co/elastic/logging/logback/EcsEncoderIntegrationTest.java @@ -0,0 +1,51 @@ +/*- + * #%L + * Java ECS logging + * %% + * Copyright (C) 2019 Elastic and contributors + * %% + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * #L% + */ +package co.elastic.logging.logback; + +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.util.ContextInitializer; +import ch.qos.logback.core.joran.spi.JoranException; +import com.fasterxml.jackson.databind.JsonNode; +import org.junit.jupiter.api.BeforeEach; + +import java.io.IOException; + +class EcsEncoderIntegrationTest extends AbstractEcsEncoderTest { + private OutputStreamAppender appender; + + @BeforeEach + void setUp() throws JoranException { + LoggerContext context = new LoggerContext(); + ContextInitializer contextInitializer = new ContextInitializer(context); + contextInitializer.configureByResource(this.getClass().getResource("/logback-config.xml")); + logger = context.getLogger("root"); + appender = (OutputStreamAppender) logger.getAppender("out"); + } + + @Override + public JsonNode getLastLogLine() throws IOException { + return objectMapper.readTree(appender.getBytes()); + } +} diff --git a/logback-ecs-encoder/src/test/java/co/elastic/logging/logback/EcsEncoderTest.java b/logback-ecs-encoder/src/test/java/co/elastic/logging/logback/EcsEncoderTest.java index b01095eb..3a01da3a 100644 --- a/logback-ecs-encoder/src/test/java/co/elastic/logging/logback/EcsEncoderTest.java +++ b/logback-ecs-encoder/src/test/java/co/elastic/logging/logback/EcsEncoderTest.java @@ -11,9 +11,9 @@ * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -24,24 +24,18 @@ */ package co.elastic.logging.logback; -import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.read.ListAppender; -import co.elastic.logging.AbstractEcsLoggingTest; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; -import org.slf4j.MDC; import java.io.IOException; -class EcsEncoderTest extends AbstractEcsLoggingTest { +class EcsEncoderTest extends AbstractEcsEncoderTest { private ListAppender appender; - private Logger logger; private EcsEncoder ecsEncoder; - private ObjectMapper objectMapper = new ObjectMapper(); @BeforeEach void setUp() { @@ -53,24 +47,10 @@ void setUp() { logger.addAppender(appender); ecsEncoder = new EcsEncoder(); ecsEncoder.setServiceName("test"); + ecsEncoder.setIncludeMarkers(true); ecsEncoder.start(); } - @Override - public void putMdc(String key, String value) { - MDC.put(key, value); - } - - @Override - public void debug(String message) { - logger.debug(message); - } - - @Override - public void error(String message, Throwable t) { - logger.error(message, t); - } - @Override public JsonNode getLastLogLine() throws IOException { return objectMapper.readTree(ecsEncoder.encode(appender.list.get(0))); diff --git a/logback-ecs-encoder/src/test/java/co/elastic/logging/logback/OutputStreamAppender.java b/logback-ecs-encoder/src/test/java/co/elastic/logging/logback/OutputStreamAppender.java new file mode 100644 index 00000000..5a7263df --- /dev/null +++ b/logback-ecs-encoder/src/test/java/co/elastic/logging/logback/OutputStreamAppender.java @@ -0,0 +1,41 @@ +/*- + * #%L + * Java ECS logging + * %% + * Copyright (C) 2019 Elastic and contributors + * %% + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * #L% + */ +package co.elastic.logging.logback; + +import ch.qos.logback.classic.spi.ILoggingEvent; + +import java.io.ByteArrayOutputStream; + +public class OutputStreamAppender extends ch.qos.logback.core.OutputStreamAppender { + @Override + public void start() { + setOutputStream(new ByteArrayOutputStream()); + super.start(); + } + + byte[] getBytes() { + return ((ByteArrayOutputStream) getOutputStream()).toByteArray(); + } +} diff --git a/logback-ecs-encoder/src/test/resources/logback-config.xml b/logback-ecs-encoder/src/test/resources/logback-config.xml new file mode 100644 index 00000000..9477481a --- /dev/null +++ b/logback-ecs-encoder/src/test/resources/logback-config.xml @@ -0,0 +1,12 @@ + + + + + test + true + + + + + + \ No newline at end of file