Skip to content

Commit b508db5

Browse files
Extract CustomField Handling for Logback
1 parent f83d8a3 commit b508db5

File tree

5 files changed

+175
-53
lines changed

5 files changed

+175
-53
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.sap.hcp.cf.logback.converter;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.HashMap;
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
import ch.qos.logback.core.Context;
10+
11+
public class CustomFieldsAdapter {
12+
13+
public static final String OPTION_MDC_CUSTOM_FIELDS = "customFieldMdcKeyNames";
14+
15+
private List<String> customFieldMdcKeyNames = Collections.emptyList();
16+
17+
public void initialize(Context context) {
18+
if (context == null) {
19+
return;
20+
}
21+
Object object = context.getObject(OPTION_MDC_CUSTOM_FIELDS);
22+
if (object instanceof List) {
23+
List<?> list = (List<?>) object;
24+
customFieldMdcKeyNames = new ArrayList<>(list.size());
25+
for (Object current : list) {
26+
customFieldMdcKeyNames.add(current.toString());
27+
}
28+
}
29+
}
30+
31+
public Map<String, String> selectCustomFields(Map<String, String> in) {
32+
if (in == null) {
33+
return Collections.emptyMap();
34+
}
35+
HashMap<String, String> result = new HashMap<>(in.size());
36+
for (Map.Entry<String, String> current : in.entrySet()) {
37+
if (customFieldMdcKeyNames.contains(current.getKey())) {
38+
result.put(current.getKey(), current.getValue());
39+
}
40+
}
41+
return result;
42+
}
43+
44+
}
Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package com.sap.hcp.cf.logback.converter;
22

3-
import java.util.ArrayList;
4-
import java.util.Collections;
5-
import java.util.HashMap;
6-
import java.util.List;
73
import java.util.Map;
84

95
import com.sap.hcp.cf.logging.common.LogContext;
@@ -12,7 +8,6 @@
128

139
import ch.qos.logback.classic.pattern.ClassicConverter;
1410
import ch.qos.logback.classic.spi.ILoggingEvent;
15-
import ch.qos.logback.core.Context;
1611

1712
/**
1813
* This is a simple {@link ClassicConverter} implementation that converts
@@ -27,17 +22,20 @@
2722

2823
public class CustomFieldsConverter extends ClassicConverter {
2924

30-
public static final String OPTION_MDC_CUSTOM_FIELDS = "customFieldMdcKeyNames";
3125
public static final String WORD = "args";
3226

3327
private DefaultCustomFieldsConverter converter = new DefaultCustomFieldsConverter();
34-
35-
private List<String> customFieldMdcKeyNames = Collections.emptyList();
28+
private CustomFieldsAdapter customFieldsAdapter = new CustomFieldsAdapter();
29+
3630

3731
void setConverter(DefaultCustomFieldsConverter converter) {
3832
this.converter = converter;
3933
}
4034

35+
void setCustomFieldsAdapter(CustomFieldsAdapter customFieldsAdapter) {
36+
this.customFieldsAdapter = customFieldsAdapter;
37+
}
38+
4139
@Override
4240
public String convert(ILoggingEvent event) {
4341
Object[] argumentArray = event.getArgumentArray();
@@ -50,36 +48,13 @@ public String convert(ILoggingEvent event) {
5048
private Map<String, String> getMdcCustomFields(ILoggingEvent event) {
5149
LogContext.loadContextFields();
5250
Map<String, String> mdcPropertyMap = event.getMDCPropertyMap();
53-
HashMap<String, String> result = new HashMap<>();
54-
for (Map.Entry<String, String> current : mdcPropertyMap.entrySet()) {
55-
if (customFieldMdcKeyNames.contains(current.getKey())) {
56-
result.put(current.getKey(), current.getValue());
57-
}
58-
}
59-
return result;
51+
return customFieldsAdapter.selectCustomFields(mdcPropertyMap);
6052
}
6153

6254
@Override
6355
public void start() {
6456
converter.setFieldName(getFirstOption());
65-
customFieldMdcKeyNames = getCustomFieldMdcKeyNames();
57+
customFieldsAdapter.initialize(getContext());
6658
super.start();
6759
}
68-
69-
private List<String> getCustomFieldMdcKeyNames() {
70-
Context context = getContext();
71-
if (context == null) {
72-
return Collections.emptyList();
73-
}
74-
Object object = context.getObject(OPTION_MDC_CUSTOM_FIELDS);
75-
if (object instanceof List) {
76-
List<?> list = (List<?>) object;
77-
ArrayList<String> result = new ArrayList<>(list.size());
78-
for (Object current : list) {
79-
result.add(current.toString());
80-
}
81-
return result;
82-
}
83-
return Collections.emptyList();
84-
}
8560
}

cf-java-logging-support-logback/src/main/java/com/sap/hcp/cf/logback/encoder/JsonEncoder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77

88
import org.slf4j.Marker;
99

10-
import com.sap.hcp.cf.logback.converter.CustomFieldsConverter;
1110
import com.sap.hcp.cf.logback.converter.CategoriesConverter;
1211
import com.sap.hcp.cf.logback.converter.ContextPropsConverter;
12+
import com.sap.hcp.cf.logback.converter.CustomFieldsAdapter;
13+
import com.sap.hcp.cf.logback.converter.CustomFieldsConverter;
1314
import com.sap.hcp.cf.logback.converter.JsonMessageConverter;
1415
import com.sap.hcp.cf.logback.converter.LogbackStacktraceConverter;
1516
import com.sap.hcp.cf.logback.converter.TimestampConverter;
@@ -126,7 +127,7 @@ public void addCustomFieldMdcKeyName(String name) {
126127

127128
@Override
128129
public void start() {
129-
context.putObject(CustomFieldsConverter.OPTION_MDC_CUSTOM_FIELDS, customFieldMdcKeyNames);
130+
context.putObject(CustomFieldsAdapter.OPTION_MDC_CUSTOM_FIELDS, customFieldMdcKeyNames);
130131

131132
JsonLayout jsonLayout = new JsonLayout();
132133
jsonLayout.setContext(context);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
2+
package com.sap.hcp.cf.logback.converter;
3+
4+
import static com.sap.hcp.cf.logback.converter.CustomFieldsAdapter.OPTION_MDC_CUSTOM_FIELDS;
5+
import static java.util.Arrays.asList;
6+
import static org.hamcrest.Matchers.allOf;
7+
import static org.hamcrest.Matchers.empty;
8+
import static org.hamcrest.Matchers.hasEntry;
9+
import static org.hamcrest.Matchers.is;
10+
import static org.hamcrest.Matchers.not;
11+
import static org.junit.Assert.assertThat;
12+
import static org.mockito.Mockito.when;
13+
14+
import java.util.Collections;
15+
import java.util.HashMap;
16+
import java.util.Map;
17+
18+
import org.junit.Test;
19+
import org.junit.runner.RunWith;
20+
import org.mockito.InjectMocks;
21+
import org.mockito.Mock;
22+
import org.mockito.runners.MockitoJUnitRunner;
23+
24+
import ch.qos.logback.core.Context;
25+
26+
@RunWith(MockitoJUnitRunner.class)
27+
public class CustomFieldsAdapterTest {
28+
29+
@SuppressWarnings("serial")
30+
private static final Map<String, String> ALL_ENTRIES = new HashMap<String, String>() {
31+
{
32+
put("this key", "this value");
33+
put("that key", "that value");
34+
put("other key", "other value");
35+
}
36+
};
37+
38+
@Mock
39+
private Context context;
40+
41+
@InjectMocks
42+
private CustomFieldsAdapter adapter;
43+
44+
45+
@Test
46+
public void rejectsAllFieldsWithoutContext() throws Exception {
47+
adapter.initialize(null);
48+
49+
Map<String, String> selected = adapter.selectCustomFields(ALL_ENTRIES);
50+
51+
assertThat(selected.entrySet(), is(empty()));
52+
}
53+
54+
@Test
55+
public void rejectsAllFieldsWithoutConfigObject() throws Exception {
56+
adapter.initialize(context);
57+
58+
Map<String, String> selected = adapter.selectCustomFields(ALL_ENTRIES);
59+
60+
assertThat(selected.entrySet(), is(empty()));
61+
}
62+
63+
@Test
64+
public void rejectsAllFieldsWithImproperConfigObject() throws Exception {
65+
when(context.getObject(OPTION_MDC_CUSTOM_FIELDS)).thenReturn(new Object());
66+
adapter.initialize(context);
67+
68+
Map<String, String> selected = adapter.selectCustomFields(ALL_ENTRIES);
69+
70+
assertThat(selected.entrySet(), is(empty()));
71+
}
72+
73+
@Test
74+
public void rejectsAllFieldsWithEmptyList() throws Exception {
75+
when(context.getObject(OPTION_MDC_CUSTOM_FIELDS)).thenReturn(Collections.emptyList());
76+
adapter.initialize(context);
77+
78+
Map<String, String> selected = adapter.selectCustomFields(ALL_ENTRIES);
79+
80+
assertThat(selected.entrySet(), is(empty()));
81+
}
82+
83+
@Test
84+
public void selectsConfiguredFields() throws Exception {
85+
when(context.getObject(OPTION_MDC_CUSTOM_FIELDS)).thenReturn(asList("this key", "that key"));
86+
adapter.initialize(context);
87+
88+
Map<String, String> selected = adapter.selectCustomFields(ALL_ENTRIES);
89+
90+
assertThat(selected,
91+
allOf(hasEntry("this key", "this value"), hasEntry("that key", "that value"),
92+
not(hasEntry("other key", "other value"))));
93+
}
94+
95+
@Test
96+
public void selectsEmptyMapOnNullInput() throws Exception {
97+
Map<String, String> selected = adapter.selectCustomFields(null);
98+
99+
assertThat(selected.entrySet(), is(empty()));
100+
}
101+
}

cf-java-logging-support-logback/src/test/java/com/sap/hcp/cf/logback/converter/CustomFieldsConverterTest.java

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import static org.hamcrest.Matchers.sameInstance;
1111
import static org.junit.Assert.assertThat;
1212
import static org.mockito.Matchers.any;
13+
import static org.mockito.Matchers.eq;
1314
import static org.mockito.Mockito.verify;
1415
import static org.mockito.Mockito.when;
1516

@@ -35,6 +36,13 @@
3536
@RunWith(MockitoJUnitRunner.class)
3637
public class CustomFieldsConverterTest extends AbstractConverterTest {
3738

39+
@SuppressWarnings("serial")
40+
private static Map<String, String> MDC_PROPERTIES = new HashMap<String, String>() {
41+
{
42+
put("mdc key", "mdc value");
43+
}
44+
};
45+
3846
@Mock
3947
private ILoggingEvent event;
4048

@@ -44,6 +52,9 @@ public class CustomFieldsConverterTest extends AbstractConverterTest {
4452
@Mock
4553
private DefaultCustomFieldsConverter defaultConverter;
4654

55+
@Mock
56+
private CustomFieldsAdapter customFieldsAdapter;
57+
4758
@Captor
4859
private ArgumentCaptor<Map<String, String>> mdcFields;
4960

@@ -57,6 +68,7 @@ public class CustomFieldsConverterTest extends AbstractConverterTest {
5768
public void initConverter() {
5869
converter.setContext(context);
5970
converter.setConverter(defaultConverter);
71+
converter.setCustomFieldsAdapter(customFieldsAdapter);
6072
}
6173

6274
@Test
@@ -117,38 +129,27 @@ public void singleUnconfiguredMdcField() throws Exception {
117129
verfiyConverterCall(emptyMap(), nullValue());
118130
}
119131

120-
@SuppressWarnings("serial")
121132
@Test
122133
public void singleConfiguredMdcField() throws Exception {
123-
when(context.getObject(CustomFieldsConverter.OPTION_MDC_CUSTOM_FIELDS))
124-
.thenReturn(asList("configured mdc key"));
134+
Map<String, String> someMap = new HashMap<>();
135+
when(event.getMDCPropertyMap()).thenReturn(someMap);
136+
when(customFieldsAdapter.selectCustomFields(eq(someMap))).thenReturn(MDC_PROPERTIES);
125137
converter.start();
126138

127-
when(event.getMDCPropertyMap()).thenReturn(new HashMap<String, String>() {
128-
{
129-
put("configured mdc key", "some value");
130-
}
131-
});
132-
133139
converter.convert(event);
134140

135-
verfiyConverterCall(hasEntry("configured mdc key", "some value"), nullValue());
141+
verfiyConverterCall(hasEntry("mdc key", "mdc value"), nullValue());
136142
}
137143

138-
@SuppressWarnings("serial")
139144
@Test
140145
public void mergesMdcFieldsAndArguments() throws Exception {
141-
when(context.getObject(CustomFieldsConverter.OPTION_MDC_CUSTOM_FIELDS))
142-
.thenReturn(asList("mdc key"));
146+
Map<String, String> someMap = new HashMap<>();
147+
when(event.getMDCPropertyMap()).thenReturn(someMap);
148+
when(customFieldsAdapter.selectCustomFields(eq(someMap))).thenReturn(MDC_PROPERTIES);
143149
converter.start();
144150

145151
CustomField customField = customField("some key", "some value");
146152
mockArgumentArray(event, customField);
147-
when(event.getMDCPropertyMap()).thenReturn(new HashMap<String, String>() {
148-
{
149-
put("mdc key", "mdc value");
150-
}
151-
});
152153

153154
converter.convert(event);
154155

0 commit comments

Comments
 (0)