diff --git a/CHANGELOG.md b/CHANGELOG.md index 3398a37..3f04a29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - Fix NPE in `StringTruncatingGeneratorDelegate`. (#53) +- Implement work around for FasterXML/jackson-core#609 triggered when + `maxStringLength` is used in combination with + `emptyPropertyExclusionEnabled=true`. (#55) + ### (2019-10-15) v0.21 - Add feature comparison matrix. diff --git a/layout/src/main/java/com/vlkan/log4j2/logstash/layout/LogstashLayoutSerializationContexts.java b/layout/src/main/java/com/vlkan/log4j2/logstash/layout/LogstashLayoutSerializationContexts.java index d85fac9..97e5b22 100644 --- a/layout/src/main/java/com/vlkan/log4j2/logstash/layout/LogstashLayoutSerializationContexts.java +++ b/layout/src/main/java/com/vlkan/log4j2/logstash/layout/LogstashLayoutSerializationContexts.java @@ -91,12 +91,13 @@ private static JsonGenerator createJsonGenerator( if (prettyPrintEnabled) { jsonGenerator.setPrettyPrinter(PRETTY_PRINTER); } - if (emptyPropertyExclusionEnabled) { - jsonGenerator = new FilteringGeneratorDelegate(jsonGenerator, NullExcludingTokenFilter.INSTANCE, true, true); - } if (maxStringLength > 0) { jsonGenerator = new StringTruncatingGeneratorDelegate(jsonGenerator, maxStringLength); } + // TokenFilter has to come last due to FasterXML/jackson-core#609. + if (emptyPropertyExclusionEnabled) { + jsonGenerator = new FilteringGeneratorDelegate(jsonGenerator, NullExcludingTokenFilter.INSTANCE, true, true); + } return jsonGenerator; } catch (IOException error) { throw new RuntimeException("failed creating JsonGenerator", error); diff --git a/layout/src/test/java/com/vlkan/log4j2/logstash/layout/LogstashLayoutTest.java b/layout/src/test/java/com/vlkan/log4j2/logstash/layout/LogstashLayoutTest.java index e06fec8..17f7eb7 100644 --- a/layout/src/test/java/com/vlkan/log4j2/logstash/layout/LogstashLayoutTest.java +++ b/layout/src/test/java/com/vlkan/log4j2/logstash/layout/LogstashLayoutTest.java @@ -1420,4 +1420,39 @@ public void test_StackTraceObjectResolver_against_getStackTrace_failures() throw } + @Test + public void test_maxStringLength_with_emptyPropertyExclusionEnabled() throws Exception { + + // Create the event template. + ObjectNode eventTemplateRootNode = JSON_NODE_FACTORY.objectNode(); + eventTemplateRootNode.put("message", "${json:message}"); + String eventTemplate = eventTemplateRootNode.toString(); + + // Create the layout. + int maxStringLength = eventTemplate.length(); + Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build(); + LogstashLayout layout = LogstashLayout + .newBuilder() + .setConfiguration(configuration) + .setEventTemplate(eventTemplate) + .setMaxStringLength(maxStringLength) + .setEmptyPropertyExclusionEnabled(true) + .build(); + + // Create the log event. + SimpleMessage message = new SimpleMessage(StringUtils.repeat('m', maxStringLength) + 'x'); + LogEvent logEvent = Log4jLogEvent + .newBuilder() + .setLoggerName(LogstashLayoutTest.class.getSimpleName()) + .setMessage(message) + .build(); + + // Check the serialized event. + String serializedLogEvent = layout.toSerializable(logEvent); + JsonNode rootNode = OBJECT_MAPPER.readTree(serializedLogEvent); + String expectedMessage = message.getFormattedMessage().substring(0, maxStringLength); + assertThat(point(rootNode, "message").asText()).isEqualTo(expectedMessage); + + } + }