Skip to content

Commit 33ae6d4

Browse files
authored
Support pattern-formatting in additional properties (#24)
1 parent 43f3803 commit 33ae6d4

File tree

4 files changed

+41
-5
lines changed

4 files changed

+41
-5
lines changed

log4j2-ecs-layout/src/main/java/co/elastic/logging/log4j2/EcsLayout.java

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939
import org.apache.logging.log4j.core.layout.AbstractStringLayout;
4040
import org.apache.logging.log4j.core.layout.ByteBufferDestination;
4141
import org.apache.logging.log4j.core.layout.Encoder;
42+
import org.apache.logging.log4j.core.layout.PatternLayout;
4243
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
44+
import org.apache.logging.log4j.core.pattern.PatternFormatter;
4345
import org.apache.logging.log4j.core.util.KeyValuePair;
4446
import org.apache.logging.log4j.message.Message;
4547
import org.apache.logging.log4j.message.MultiformatMessage;
@@ -78,6 +80,7 @@ public void accept(final String key, final Object value, final StringBuilder str
7880
};
7981

8082
private final KeyValuePair[] additionalFields;
83+
private final PatternFormatter[][] fieldValuePatternFormatter;
8184
private final Set<String> topLevelLabels;
8285
private final boolean stackTraceAsArray;
8386
private String serviceName;
@@ -93,6 +96,15 @@ private EcsLayout(Configuration config, String serviceName, boolean includeMarke
9396
this.topLevelLabels.add("trace.id");
9497
this.topLevelLabels.add("transaction.id");
9598
this.additionalFields = additionalFields;
99+
fieldValuePatternFormatter = new PatternFormatter[additionalFields.length][];
100+
for (int i = 0; i < additionalFields.length; i++) {
101+
KeyValuePair additionalField = additionalFields[i];
102+
if (additionalField.getValue().contains("%")) {
103+
fieldValuePatternFormatter[i] = PatternLayout.createPatternParser(config)
104+
.parse(additionalField.getValue())
105+
.toArray(new PatternFormatter[0]);
106+
}
107+
}
96108
}
97109

98110
@PluginBuilderFactory
@@ -132,12 +144,21 @@ private StringBuilder toText(LogEvent event, StringBuilder builder, boolean gcFr
132144
}
133145

134146
private void serializeLabels(LogEvent event, StringBuilder builder) {
135-
if (!event.getContextData().isEmpty() || additionalFields.length > 0) {
136-
if (additionalFields.length > 0) {
147+
final int length = additionalFields.length;
148+
if (!event.getContextData().isEmpty() || length > 0) {
149+
if (length > 0) {
137150
final StrSubstitutor strSubstitutor = getConfiguration().getStrSubstitutor();
138-
for (KeyValuePair additionalField : additionalFields) {
151+
for (int i = 0; i < length; i++) {
152+
KeyValuePair additionalField = additionalFields[i];
153+
PatternFormatter[] formatters = fieldValuePatternFormatter[i];
139154
CharSequence value = null;
140-
if (valueNeedsLookup(additionalField.getValue())) {
155+
if (formatters != null) {
156+
StringBuilder buffer = EcsJsonSerializer.getMessageStringBuilder();
157+
formatPattern(event, formatters, buffer);
158+
if (buffer.length() > 0) {
159+
value = buffer;
160+
}
161+
} else if (valueNeedsLookup(additionalField.getValue())) {
141162
StringBuilder lookupValue = EcsJsonSerializer.getMessageStringBuilder();
142163
lookupValue.append(additionalField.getValue());
143164
if (strSubstitutor.replaceIn(event, lookupValue)) {
@@ -160,6 +181,13 @@ private void serializeLabels(LogEvent event, StringBuilder builder) {
160181
}
161182
}
162183

184+
private static void formatPattern(LogEvent event, PatternFormatter[] formatters, StringBuilder buffer) {
185+
final int len = formatters.length;
186+
for (int i = 0; i < len; i++) {
187+
formatters[i].format(event, buffer);
188+
}
189+
}
190+
163191
private void serializeTags(LogEvent event, StringBuilder builder) {
164192
List<String> contextStack = event.getContextStack().asList();
165193
Marker marker = event.getMarker();
@@ -169,7 +197,8 @@ private void serializeTags(LogEvent event, StringBuilder builder) {
169197
}
170198

171199
if (!contextStack.isEmpty()) {
172-
for (int i = 0; i < contextStack.size(); i++) {
200+
final int len = contextStack.size();
201+
for (int i = 0; i < len; i++) {
173202
builder.append('\"');
174203
JsonUtils.quoteAsString(contextStack.get(i), builder);
175204
builder.append("\",");

log4j2-ecs-layout/src/test/java/co/elastic/logging/log4j2/AbstractLog4j2EcsLayoutTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ void globalLabels() throws Exception {
5353
debug("test");
5454
assertThat(getLastLogLine().get("cluster.uuid").textValue()).isEqualTo("9fe9134b-20b0-465e-acf9-8cc09ac9053b");
5555
assertThat(getLastLogLine().get("node.id").textValue()).isEqualTo("foo");
56+
assertThat(getLastLogLine().get("empty")).isNull();
57+
assertThat(getLastLogLine().get("emptyPattern")).isNull();
58+
assertThat(getLastLogLine().get("clazz").textValue()).startsWith(getClass().getPackageName());
5659
assertThat(getLastLogLine().get("404")).isNull();
5760
}
5861

log4j2-ecs-layout/src/test/java/co/elastic/logging/log4j2/Log4j2EcsLayoutTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ void setUp() {
7373
new KeyValuePair("cluster.uuid", "9fe9134b-20b0-465e-acf9-8cc09ac9053b"),
7474
new KeyValuePair("node.id", "${node.id}"),
7575
new KeyValuePair("empty", "${empty}"),
76+
new KeyValuePair("clazz", "%C"),
77+
new KeyValuePair("emptyPattern", "%notEmpty{%invalidPattern}"),
7678
})
7779
.build();
7880

log4j2-ecs-layout/src/test/resources/log4j2-test.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
<KeyValuePair key="cluster.uuid" value="9fe9134b-20b0-465e-acf9-8cc09ac9053b"/>
1010
<KeyValuePair key="node.id" value="${node.id}"/>
1111
<KeyValuePair key="empty" value="${empty}"/>
12+
<KeyValuePair key="clazz" value="%C"/>
13+
<KeyValuePair key="emptyPattern" value="%notEmpty{%invalidPattern}"/>
1214
</EcsLayout>
1315
</List>
1416
</Appenders>

0 commit comments

Comments
 (0)