Skip to content

Commit 634aec3

Browse files
committed
#55 Work around for TokenFilter-vs-Delegate ordering bug.
1 parent 521a463 commit 634aec3

File tree

3 files changed

+67
-27
lines changed

3 files changed

+67
-27
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
- Fix `ArrayIndexOutOfBoundsException` thrown when `stackTrace:text` produces
44
an output violating the truncation limit. (#57)
55

6+
- Implement work around for FasterXML/jackson-core#609 triggered when
7+
`maxStringLength` is used in combination with
8+
`emptyPropertyExclusionEnabled=true`. (#55)
9+
610
### (2020-01-21) v1.0.1
711

812
- Fix NPE in `StringTruncatingGeneratorDelegate`. (#53)

layout/src/main/java/com/vlkan/log4j2/logstash/layout/LogstashLayoutSerializationContexts.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,13 @@ private static JsonGenerator createJsonGenerator(
9191
if (prettyPrintEnabled) {
9292
jsonGenerator.setPrettyPrinter(PRETTY_PRINTER);
9393
}
94-
if (emptyPropertyExclusionEnabled) {
95-
jsonGenerator = new FilteringGeneratorDelegate(jsonGenerator, NullExcludingTokenFilter.INSTANCE, true, true);
96-
}
9794
if (maxStringLength > 0) {
9895
jsonGenerator = new StringTruncatingGeneratorDelegate(jsonGenerator, maxStringLength);
9996
}
97+
// TokenFilter has to come last due to FasterXML/jackson-core#609.
98+
if (emptyPropertyExclusionEnabled) {
99+
jsonGenerator = new FilteringGeneratorDelegate(jsonGenerator, NullExcludingTokenFilter.INSTANCE, true, true);
100+
}
100101
return jsonGenerator;
101102
} catch (IOException error) {
102103
throw new RuntimeException("failed creating JsonGenerator", error);

layout/src/test/java/com/vlkan/log4j2/logstash/layout/LogstashLayoutTest.java

+59-24
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.fasterxml.jackson.databind.node.MissingNode;
2525
import com.fasterxml.jackson.databind.node.NullNode;
2626
import com.fasterxml.jackson.databind.node.ObjectNode;
27+
import joptsimple.internal.Strings;
2728
import org.apache.commons.lang3.StringUtils;
2829
import org.apache.logging.log4j.Level;
2930
import org.apache.logging.log4j.Marker;
@@ -32,7 +33,6 @@
3233
import org.apache.logging.log4j.core.config.Configuration;
3334
import org.apache.logging.log4j.core.config.DefaultConfiguration;
3435
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
35-
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
3636
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
3737
import org.apache.logging.log4j.core.layout.ByteBufferDestination;
3838
import org.apache.logging.log4j.core.lookup.MainMapLookup;
@@ -245,7 +245,7 @@ public void test_inline_template() throws Exception {
245245
String eventTemplate = eventTemplateRootNode.toString();
246246

247247
// Create the layout.
248-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
248+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
249249
String timeZoneId = TimeZone.getTimeZone("Europe/Amsterdam").getID();
250250
LogstashLayout layout = LogstashLayout
251251
.newBuilder()
@@ -275,7 +275,7 @@ public void test_log4j_deferred_runtime_resolver_for_MapMessage() throws Excepti
275275
String eventTemplate = eventTemplateRootNode.toString();
276276

277277
// Create the layout.
278-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
278+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
279279
LogstashLayout layout = LogstashLayout
280280
.newBuilder()
281281
.setConfiguration(configuration)
@@ -312,7 +312,7 @@ public void test_MapMessage_serialization() throws Exception {
312312
String eventTemplate = eventTemplateRootNode.toString();
313313

314314
// Create the layout.
315-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
315+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
316316
LogstashLayout layout = LogstashLayout
317317
.newBuilder()
318318
.setConfiguration(configuration)
@@ -403,7 +403,7 @@ public void test_empty_root_cause() throws Exception {
403403
String eventTemplate = eventTemplateRootNode.toString();
404404

405405
// Create the layout.
406-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
406+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
407407
LogstashLayout layout = LogstashLayout
408408
.newBuilder()
409409
.setConfiguration(configuration)
@@ -449,7 +449,7 @@ public void test_root_cause() throws Exception {
449449
String eventTemplate = eventTemplateRootNode.toString();
450450

451451
// Create the layout.
452-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
452+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
453453
LogstashLayout layout = LogstashLayout
454454
.newBuilder()
455455
.setConfiguration(configuration)
@@ -493,7 +493,7 @@ public void test_marker_name() throws IOException {
493493
String eventTemplate = eventTemplateRootNode.toString();
494494

495495
// Create the layout.
496-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
496+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
497497
LogstashLayout layout = LogstashLayout
498498
.newBuilder()
499499
.setConfiguration(configuration)
@@ -529,7 +529,7 @@ public void test_lineSeparator_suffix() {
529529
private void test_lineSeparator_suffix(LogEvent logEvent, boolean prettyPrintEnabled) {
530530

531531
// Create the layout.
532-
BuiltConfiguration config = ConfigurationBuilderFactory.newConfigurationBuilder().build();
532+
Configuration config = ConfigurationBuilderFactory.newConfigurationBuilder().build();
533533
LogstashLayout layout = LogstashLayout
534534
.newBuilder()
535535
.setConfiguration(config)
@@ -575,7 +575,7 @@ public void test_main_key_access() throws IOException {
575575
String template = templateRootNode.toString();
576576

577577
// Create the layout.
578-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
578+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
579579
LogstashLayout layout = LogstashLayout
580580
.newBuilder()
581581
.setConfiguration(configuration)
@@ -627,7 +627,7 @@ public void test_mdc_key_access() throws IOException {
627627
String eventTemplate = eventTemplateRootNode.toString();
628628

629629
// Create the layout.
630-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
630+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
631631
LogstashLayout layout = LogstashLayout
632632
.newBuilder()
633633
.setConfiguration(configuration)
@@ -665,7 +665,7 @@ public void test_MapResolver() throws IOException {
665665
String eventTemplate = eventTemplateRootNode.toString();
666666

667667
// Create the layout.
668-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
668+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
669669
LogstashLayout layout = LogstashLayout
670670
.newBuilder()
671671
.setConfiguration(configuration)
@@ -789,7 +789,7 @@ public void test_message_json() throws IOException {
789789
String eventTemplate = eventTemplateRootNode.toString();
790790

791791
// Create the layout.
792-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
792+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
793793
LogstashLayout layout = LogstashLayout
794794
.newBuilder()
795795
.setConfiguration(configuration)
@@ -823,7 +823,7 @@ public void test_message_json_fallback() throws IOException {
823823
String eventTemplate = eventTemplateRootNode.toString();
824824

825825
// Create the layout.
826-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
826+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
827827
LogstashLayout layout = LogstashLayout
828828
.newBuilder()
829829
.setConfiguration(configuration)
@@ -874,7 +874,7 @@ public void test_message_object() throws IOException {
874874
String eventTemplate = eventTemplateRootNode.toString();
875875

876876
// Create the layout.
877-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
877+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
878878
LogstashLayout layout = LogstashLayout
879879
.newBuilder()
880880
.setConfiguration(configuration)
@@ -912,7 +912,7 @@ public void test_StackTraceElement_template() throws IOException {
912912
String eventTemplate = eventTemplateRootNode.toString();
913913

914914
// Create the layout.
915-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
915+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
916916
LogstashLayout layout = LogstashLayout
917917
.newBuilder()
918918
.setConfiguration(configuration)
@@ -956,7 +956,7 @@ public void test_StackTraceElement_template() throws IOException {
956956
public void test_toSerializable_toByteArray_encode_outputs() {
957957

958958
// Create the layout.
959-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
959+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
960960
LogstashLayout layout = LogstashLayout
961961
.newBuilder()
962962
.setConfiguration(configuration)
@@ -1035,7 +1035,7 @@ public void test_maxStringLength() throws IOException {
10351035
String eventTemplate = eventTemplateRootNode.toString();
10361036

10371037
// Create the layout.
1038-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
1038+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
10391039
LogstashLayout layout = LogstashLayout
10401040
.newBuilder()
10411041
.setConfiguration(configuration)
@@ -1098,7 +1098,7 @@ public void test_exception_with_nonAscii_utf8_method_name() throws IOException {
10981098
String eventTemplate = eventTemplateRootNode.toString();
10991099

11001100
// Create the layout.
1101-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
1101+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
11021102
LogstashLayout layout = LogstashLayout
11031103
.newBuilder()
11041104
.setConfiguration(configuration)
@@ -1133,7 +1133,7 @@ public void test_custom_ObjectMapper_factory_method() throws IOException {
11331133
String eventTemplate = eventTemplateRootNode.toString();
11341134

11351135
// Create the layout.
1136-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
1136+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
11371137
LogstashLayout layout = LogstashLayout
11381138
.newBuilder()
11391139
.setObjectMapperFactoryMethod("com.vlkan.log4j2.logstash.layout.LogstashLayoutTest.getCustomObjectMapper")
@@ -1175,7 +1175,7 @@ public void test_event_template_additional_fields() throws IOException {
11751175
String eventTemplate = eventTemplateRootNode.toString();
11761176

11771177
// Create the layout.
1178-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
1178+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
11791179
KeyValuePair additionalField1 = new KeyValuePair("message", "${json:message}");
11801180
KeyValuePair additionalField2 = new KeyValuePair("@version", "1");
11811181
KeyValuePair[] additionalFieldPairs = {additionalField1, additionalField2};
@@ -1236,7 +1236,7 @@ public void test_timestamp_divisor() throws IOException {
12361236
String eventTemplate = eventTemplateRootNode.toString();
12371237

12381238
// Create the layout.
1239-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
1239+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
12401240
LogstashLayout layout = LogstashLayout
12411241
.newBuilder()
12421242
.setConfiguration(configuration)
@@ -1272,7 +1272,7 @@ public void test_level_severity() throws IOException {
12721272
String eventTemplate = eventTemplateRootNode.toString();
12731273

12741274
// Create the layout.
1275-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
1275+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
12761276
LogstashLayout layout = LogstashLayout
12771277
.newBuilder()
12781278
.setConfiguration(configuration)
@@ -1324,7 +1324,7 @@ public void test_exception_resolvers_against_no_exceptions() throws IOException
13241324
String eventTemplate = eventTemplateRootNode.toString();
13251325

13261326
// Create the layout.
1327-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
1327+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
13281328
LogstashLayout layout = LogstashLayout
13291329
.newBuilder()
13301330
.setConfiguration(configuration)
@@ -1363,7 +1363,7 @@ public void test_timestamp_resolver() throws IOException {
13631363
String eventTemplate = eventTemplateRootNode.toString();
13641364

13651365
// Create the layout.
1366-
BuiltConfiguration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
1366+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
13671367
LogstashLayout layout = LogstashLayout
13681368
.newBuilder()
13691369
.setConfiguration(configuration)
@@ -1442,4 +1442,39 @@ public void test_StackTraceTextResolver_with_maxStringLength() throws Exception
14421442

14431443
}
14441444

1445+
@Test
1446+
public void test_maxStringLength_with_emptyPropertyExclusionEnabled() throws Exception {
1447+
1448+
// Create the event template.
1449+
ObjectNode eventTemplateRootNode = JSON_NODE_FACTORY.objectNode();
1450+
eventTemplateRootNode.put("message", "${json:message}");
1451+
String eventTemplate = eventTemplateRootNode.toString();
1452+
1453+
// Create the layout.
1454+
int maxStringLength = eventTemplate.length();
1455+
Configuration configuration = ConfigurationBuilderFactory.newConfigurationBuilder().build();
1456+
LogstashLayout layout = LogstashLayout
1457+
.newBuilder()
1458+
.setConfiguration(configuration)
1459+
.setEventTemplate(eventTemplate)
1460+
.setMaxStringLength(maxStringLength)
1461+
.setEmptyPropertyExclusionEnabled(true)
1462+
.build();
1463+
1464+
// Create the log event.
1465+
SimpleMessage message = new SimpleMessage(Strings.repeat('m', maxStringLength) + 'x');
1466+
LogEvent logEvent = Log4jLogEvent
1467+
.newBuilder()
1468+
.setLoggerName(LogstashLayoutTest.class.getSimpleName())
1469+
.setMessage(message)
1470+
.build();
1471+
1472+
// Check the serialized event.
1473+
String serializedLogEvent = layout.toSerializable(logEvent);
1474+
JsonNode rootNode = OBJECT_MAPPER.readTree(serializedLogEvent);
1475+
String expectedMessage = message.getFormattedMessage().substring(0, maxStringLength);
1476+
assertThat(point(rootNode, "message").asText()).isEqualTo(expectedMessage);
1477+
1478+
}
1479+
14451480
}

0 commit comments

Comments
 (0)