Skip to content

Commit 16e8e3c

Browse files
#135 Fix UOE when using Custom Fields (#136)
Log4j can provide different context data depending on its configuration. In one case the provided context map is unmodifiable. In that case an exception occurred, when a custom field was used as a message parameter. This change guards against that issue, by defensively creating a modifiable map of properties. Then the custom fields can be added safely.
1 parent a387108 commit 16e8e3c

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

cf-java-logging-support-log4j2/src/main/java/com/sap/hcp/cf/log4j2/converter/ContextPropsConverter.java

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.sap.hcp.cf.log4j2.converter;
22

33
import java.util.Arrays;
4+
import java.util.HashMap;
45
import java.util.Map;
56

67
import org.apache.logging.log4j.core.LogEvent;
@@ -47,30 +48,38 @@ public static ContextPropsConverter newInstance(final String[] options) {
4748

4849
@Override
4950
public void format(LogEvent event, StringBuilder toAppendTo) {
50-
Map<String, String> contextData = event.getContextData().toMap();
51-
addCustomFieldsFromArguments(contextData, event);
51+
Map<String, String> contextData = event.getContextData().toMap();
52+
contextData = addCustomFieldsFromArguments(contextData, event);
5253
int lengthBefore = toAppendTo.length();
53-
converter.convert(toAppendTo, contextData);
54+
converter.convert(toAppendTo, contextData);
5455
// remove comma from pattern, when no properties are added
5556
// this is to avoid a double comma in the JSON
5657
// Do not do this on empty messages
5758
if (toAppendTo.length() == lengthBefore && lengthBefore > 0 && toAppendTo.charAt(lengthBefore - 1) == ',') {
5859
toAppendTo.setLength(lengthBefore - 1);
5960
}
60-
}
61+
}
6162

62-
private void addCustomFieldsFromArguments(Map<String, String> contextData, LogEvent event) {
63-
Message message = event.getMessage();
64-
Object[] parameters = message.getParameters();
65-
if (parameters == null) {
66-
return;
67-
}
68-
for (Object current : parameters) {
69-
if (current instanceof CustomField) {
70-
CustomField field = (CustomField) current;
71-
contextData.put(field.getKey(), field.getValue());
72-
}
73-
}
74-
}
63+
private Map<String, String> addCustomFieldsFromArguments(Map<String, String> contextData, LogEvent event) {
64+
Message message = event.getMessage();
65+
Object[] parameters = message.getParameters();
66+
if (parameters == null) {
67+
return contextData;
68+
}
69+
boolean unchangedContextData = true;
70+
Map<String, String> result = contextData;
71+
for (Object current: parameters) {
72+
if (current instanceof CustomField) {
73+
CustomField field = (CustomField) current;
74+
if (unchangedContextData) {
75+
// contextData might be an unmodifiable map
76+
result = new HashMap<>(contextData);
77+
unchangedContextData = false;
78+
}
79+
result.put(field.getKey(), field.getValue());
80+
}
81+
}
82+
return result;
83+
}
7584

7685
}

0 commit comments

Comments
 (0)