Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add configuration option to EventJsonLayoutBaseFactory to flatten MDC #2293

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -31,6 +31,11 @@
* <td>(empty)</td>
* <td>Set of MDC keys which should be included in the JSON map. By default includes everything.</td>
* </tr>
* <tr>
* <td>{@code flattenMdc}</td>
* <td>{@code false}</td>
* <td>Whether the MDC should be included under the key "mdc" or flattened into the map.</td>
* </tr>
* </table>
*/
@JsonTypeName("json")
Expand All @@ -41,6 +46,7 @@ public class EventJsonLayoutBaseFactory extends AbstractJsonLayoutBaseFactory<IL
EventAttribute.EXCEPTION, EventAttribute.TIMESTAMP);

private Set<String> includesMdcKeys = ImmutableSet.of();
private boolean flattenMdc = false;

@JsonProperty
public EnumSet<EventAttribute> getIncludes() {
Expand All @@ -62,12 +68,22 @@ public void setIncludesMdcKeys(Set<String> includesMdcKeys) {
this.includesMdcKeys = includesMdcKeys;
}

@JsonProperty
public boolean isFlattenMdc() {
return flattenMdc;
}

@JsonProperty
public void setFlattenMdc(boolean flattenMdc) {
this.flattenMdc = flattenMdc;
}

@Override
@SuppressWarnings("unchecked")
public LayoutBase<ILoggingEvent> build(LoggerContext context, TimeZone timeZone) {
final EventJsonLayout jsonLayout = new EventJsonLayout(createDropwizardJsonFormatter(),
createTimestampFormatter(timeZone), createThrowableProxyConverter(), includes, getCustomFieldNames(),
getAdditionalFields(), includesMdcKeys);
getAdditionalFields(), includesMdcKeys, flattenMdc);
jsonLayout.setContext(context);
return jsonLayout;
}
Expand Down
Expand Up @@ -28,18 +28,20 @@ public class EventJsonLayout extends AbstractJsonLayout<ILoggingEvent> {
private final Map<String, String> customFieldNames;

private ImmutableSet<String> includesMdcKeys;
private final boolean flattenMdc;

public EventJsonLayout(JsonFormatter jsonFormatter, TimestampFormatter timestampFormatter,
ThrowableHandlingConverter throwableProxyConverter, Set<EventAttribute> includes,
Map<String, String> customFieldNames, Map<String, Object> additionalFields,
Set<String> includesMdcKeys) {
Set<String> includesMdcKeys, boolean flattenMdc) {
super(jsonFormatter);
this.timestampFormatter = timestampFormatter;
this.additionalFields = ImmutableMap.copyOf(additionalFields);
this.customFieldNames = ImmutableMap.copyOf(customFieldNames);
this.throwableProxyConverter = throwableProxyConverter;
this.includes = ImmutableSet.copyOf(includes);
this.includesMdcKeys = ImmutableSet.copyOf(includesMdcKeys);
this.flattenMdc = flattenMdc;
}

@Override
Expand All @@ -56,18 +58,23 @@ public void stop() {

@Override
protected Map<String, Object> toJsonMap(ILoggingEvent event) {
return new MapBuilder(timestampFormatter, customFieldNames, additionalFields, 16)
final MapBuilder mapBuilder = new MapBuilder(timestampFormatter, customFieldNames, additionalFields, 16)
.addTimestamp("timestamp", isIncluded(EventAttribute.TIMESTAMP), event.getTimeStamp())
.add("level", isIncluded(EventAttribute.LEVEL), String.valueOf(event.getLevel()))
.add("thread", isIncluded(EventAttribute.THREAD_NAME), event.getThreadName())
.add("mdc", isIncluded(EventAttribute.MDC), filterMdc(event.getMDCPropertyMap()))
.add("logger", isIncluded(EventAttribute.LOGGER_NAME), event.getLoggerName())
.add("message", isIncluded(EventAttribute.MESSAGE), event.getFormattedMessage())
.add("context", isIncluded(EventAttribute.CONTEXT_NAME), event.getLoggerContextVO().getName())
.add("version", jsonProtocolVersion != null, jsonProtocolVersion)
.add("exception", isIncluded(EventAttribute.EXCEPTION) && event.getThrowableProxy() != null,
throwableProxyConverter.convert(event))
.build();
throwableProxyConverter.convert(event));
final boolean includeMdc = isIncluded(EventAttribute.MDC);
if (flattenMdc) {
filterMdc(event.getMDCPropertyMap()).forEach((k,v) -> mapBuilder.add(k, includeMdc, v));
} else {
mapBuilder.add("mdc", includeMdc, filterMdc(event.getMDCPropertyMap()));
}
return mapBuilder.build();
}

private Map<String, String> filterMdc(Map<String, String> mdcPropertyMap) {
Expand Down
Expand Up @@ -74,6 +74,7 @@ public void testDeserializeJson() throws Exception {
EventAttribute.LOGGER_NAME,
EventAttribute.EXCEPTION,
EventAttribute.TIMESTAMP);
assertThat(factory.isFlattenMdc()).isTrue();
assertThat(factory.getCustomFieldNames()).containsOnly(entry("timestamp", "@timestamp"));
assertThat(factory.getAdditionalFields()).containsOnly(entry("service-name", "user-service"),
entry("service-build", 218));
Expand Down
Expand Up @@ -41,7 +41,7 @@ public class EventJsonLayoutTest {
EventAttribute.THREAD_NAME, EventAttribute.MDC, EventAttribute.LOGGER_NAME, EventAttribute.MESSAGE,
EventAttribute.EXCEPTION, EventAttribute.TIMESTAMP);
private EventJsonLayout eventJsonLayout = new EventJsonLayout(jsonFormatter, timestampFormatter, throwableProxyConverter,
includes, ImmutableMap.of(), ImmutableMap.of(), ImmutableSet.of());
includes, ImmutableMap.of(), ImmutableMap.of(), ImmutableSet.of(), false);

@Before
public void setUp() {
Expand Down Expand Up @@ -109,7 +109,7 @@ public void testLogVersion() {
public void testReplaceFieldName() {
Map<String, Object> map = new EventJsonLayout(jsonFormatter, timestampFormatter, throwableProxyConverter, includes,
ImmutableMap.of("timestamp", "@timestamp", "message", "@message"), ImmutableMap.of(),
ImmutableSet.of())
ImmutableSet.of(), false)
.toJsonMap(event);
assertThat(map).containsOnly(entry("@timestamp", timestamp),
entry("thread", "main"),
Expand All @@ -123,7 +123,7 @@ public void testReplaceFieldName() {
public void testAddNewField() {
Map<String, Object> map = new EventJsonLayout(jsonFormatter, timestampFormatter, throwableProxyConverter, includes,
ImmutableMap.of(), ImmutableMap.of("serviceName", "userService", "serviceBuild", 207),
ImmutableSet.of())
ImmutableSet.of(), false)
.toJsonMap(event);
assertThat(map).containsOnly(entry("timestamp", timestamp),
entry("thread", "main"),
Expand All @@ -139,7 +139,7 @@ public void testAddNewField() {
public void testFilterMdc() {
Map<String, Object> map = new EventJsonLayout(jsonFormatter, timestampFormatter, throwableProxyConverter, includes,
ImmutableMap.of(), ImmutableMap.of(),
ImmutableSet.of("userId", "orderId")).toJsonMap(event);
ImmutableSet.of("userId", "orderId"), false).toJsonMap(event);
assertThat(map).containsOnly(entry("timestamp", timestamp),
entry("thread", "main"),
entry("level", "INFO"),
Expand All @@ -148,6 +148,20 @@ public void testFilterMdc() {
entry("mdc", ImmutableMap.of("userId", "18", "orderId", "24")));
}

@Test
public void testFlattensMdcMap() {
Map<String, Object> map = new EventJsonLayout(jsonFormatter, timestampFormatter, throwableProxyConverter,
includes, ImmutableMap.of(), ImmutableMap.of(), ImmutableSet.of(), true).toJsonMap(event);
assertThat(map).containsOnly(entry("timestamp", timestamp),
entry("thread", "main"),
entry("level", "INFO"),
entry("logger", logger),
entry("message", message),
entry("userId", "18"),
entry("serviceId", "19"),
entry("orderId", "24"));
}

@Test
public void testStartThrowableConverter() {
eventJsonLayout.start();
Expand Down
Expand Up @@ -18,4 +18,5 @@ layout:
service-name: "user-service"
service-build: 218
includesMdcKeys: [userId]
flattenMdc: true