-
Notifications
You must be signed in to change notification settings - Fork 80
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
MDC values for event.type and event.category are not properly serialized as JSON arrays #301
Comments
Hi @thomastrinn , thanks for opening this suggestion. I think there are a few challenges here:
As an alternative, I would suggest to keep your serialization logic as-is with calls to |
Hi @SylvainJuge , thank you for your response, I completely understand your point of view! Because I’m using SLF4J, and its MDC accepts only string values, my initial thought was simply to produce the desired string representation — like For fields like From my perspective, it’s important to generate ECS-compatible logs directly in the application, but there’s no built-in solution for handling arrays. Because of that, I’d have to apply extra processing steps for That’s why I decided to explore alternative options, and I ended up choosing the logstash-logback-encoder library. It’s flexible, and with the following <!-- logback.xml configuration -->
<configuration>
<property name="SERVICE_NAME" value="${logging.structured.service.name:-application}" />
<property name="SERVICE_VERSION" value="${logging.structured.service.version:-1.0.0}" />
<property name="SERVICE_ENVIRONMENT" value="${logging.structured.service.environment:-development}" />
<property name="SERVICE_NODE_NAME" value="${logging.structured.service.node.name:-${SERVICE_NAME}}" />
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<timestampPattern>yyyy-MM-dd'T'HH:mm:ss.SSS'Z'</timestampPattern>
<timeZone>UTC</timeZone>
<fieldNames>
<timestamp>@timestamp</timestamp>
<level>log.level</level>
<logger>log.logger</logger>
<thread>process.thread.name</thread>
<message>message</message>
<!-- Disable default logstash fields -->
<levelValue>[ignore]</levelValue>
<version>[ignore]</version>
<tags>[ignore]</tags>
</fieldNames>
<customFields>
{
"ecs.version": "1.2.0",
"service.name": "${SERVICE_NAME}",
"service.version": "${SERVICE_VERSION}",
"service.environment": "${SERVICE_ENVIRONMENT}",
"service.node.name": "${SERVICE_NODE_NAME}",
"event.dataset": "${SERVICE_NAME}"
}
</customFields>
<includeMdc>true</includeMdc>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration> And here’s a straightforward example in code: package com.example
import net.logstash.logback.marker.Markers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.slf4j.Marker;
public class MyClass {
private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
public void someMethod() {
try {
MDC.put("event.kind", "event");
Marker marker = Markers.aggregate(
Markers.append("event.category", List.of("library")),
Markers.append("event.type", List.of("info"))
);
logger.info(marker, "some event to log");
} finally {
MDC.remove("event.kind");
}
}
} Hopefully this example will be useful for anyone else who needs to generate valid ECS logs. Thank you for considering my suggestion—I hope it might be revisited in the future so we can handle arrays out-of-the-box without additional processing. |
Thanks for your exhaustive response, I am happy to learn that you've managed to find an alternative implementation, this would definitely be useful to anyone trying to do the same on their own application. Also, this issue can be used to gather feedback to anyone having a similar challenge so it helps prioritize properly (if you read this and are interested, +1 or adding a comment would help). |
Description
When using logback-ecs-encoder with SLF4J's MDC to set array-type fields (like event.type and event.category), the values are serialized as string literals instead of proper JSON arrays. While MDC only supports String values by design, the ECS encoder could detect and properly format string values that represent arrays for fields that are defined as arrays in the ECS specification.
Current Behavior
When setting an array value in MDC (which only accepts strings):
The current output in logs:
Expected Behaviour
The log output should contain a proper JSON array according to ECS specification:
Technical Details
The issue is in
EcsJsonSerializer.serializeMDC()
where all MDC values are treated as string literals:While we understand that MDC only supports string values, the ECS encoder could detect and properly format these string values for fields that are defined as arrays in the ECS specification.
Impact
This limitation affects any field that should be an array according to ECS specification, particularly:
This makes it difficult to use the library with standard Java collections for fields that should be arrays according to the ECS specification.
Suggested Solution
The serializer could:
Example implementation approach:
Environment
The text was updated successfully, but these errors were encountered: