如何在Elastic中正确存储ECS规范的event.duration字段
问题根因
你遇到的event.duration被归入flat字段的情况,通常是两类配置错误导致的:
- logback编码器的MDC字段输出规则默认将非内置ECS的MDC字段归入
flat结构 - Filebeat的JSON解析配置指定了
target为flat,导致所有解析字段被嵌套到该字段下
解决方案
方案1:调整logback编码器配置(适用使用ECS专用编码器的场景)
如果你使用的是EcsCompositeJsonEncoder,只需要在编码器配置中显式指定要提升到根级别的MDC键即可,示例配置如下:
<encoder class="net.logstash.logback.encoder.EcsCompositeJsonEncoder"> <!-- 其他原有配置 --> <includeMdcKeyName>event.duration</includeMdcKeyName> <!-- 如果有其他需要提升的自定义ECS字段,按同样格式添加即可 --> </encoder>
如果你使用的是通用的LoggingEventCompositeJsonEncoder,则需要调整MDC provider的配置,关闭非必要的打平逻辑:
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"> <providers> <!-- 其他原有provider配置,比如timestamp、message等 --> <mdc> <flatten>false</flatten> <!-- 只输出你需要的MDC字段,避免冗余字段污染 --> <includeMdcKeyName>event.duration</includeMdcKeyName> </mdc> </providers> </encoder>
注意:往MDC中写入
event.duration时请存入Long类型的纳秒数值,不要存入字符串,避免Elasticsearch生成错误的字段映射,不符合ECS规范要求。
方案2:调整Filebeat的JSON解析配置
如果你的Filebeat配置中使用了decode_json_fields处理器解析日志内容,请确认target参数设置为空字符串,这样所有解析出的JSON字段会直接放到文档根级别,不会嵌套到自定义字段下,示例配置如下:
filebeat.inputs: - type: filestream paths: - /path/to/your/logs/*.log processors: - decode_json_fields: fields: ["message"] target: "" # 此处不要设置为flat,空字符串代表根级别 overwrite_keys: true
内容的提问来源于stack exchange,提问作者Andrew Sokolov
相关产品推荐
相关产品推荐

