ELK导入旧日志时@timestamp显示当前时间,如何用自定义日志时间字段替换?
Logstash @timestamp替换失效解决方案
问题根因
你的配置存在3处核心错误导致时间替换不生效:
- 过滤器执行顺序错误:你将date过滤器放在了grok、json解析步骤之前,此时日志内容还未被解析,
datetime字段根本不存在,匹配直接失效 - 字段路径不匹配:json解析配置中指定了
target => "payload",所有解析出的日志字段都会放在payload嵌套字段下,你直接匹配根级的datetime字段必然返回空 - 时间格式匹配错误:日志中
datetime字段带毫秒后缀,167,你配置的时间格式只精确到秒,格式完全不匹配无法解析
修正后的完整配置
input { stdin { type => "stdin-type" } file { type => "json" path => [ "/home/testuser/mylogs/*.log", "/home/testuser/mylogs/*/*.log" ] start_position => "beginning" sincedb_path => "/dev/null" # 调试时加这行可以重复读取同一份日志,正式环境可删除 } } filter { # 由于你的日志每行都是完整JSON结构,无需额外grok,直接解析message字段即可 json { source => "message" # 去掉target配置,解析后的字段直接放到根级,无需嵌套在payload下 } mutate { remove_field => [ "message" ] } # 放在解析步骤之后,匹配正确的时间格式 date { match => ["datetime", "yyyy-MM-dd HH:mm:ss,SSS"] target => "@timestamp" # 替换默认的@timestamp字段 timezone => "Asia/Shanghai" # 注意和你的日志时区对齐,避免时间偏移 } } output { stdout { codec => rubydebug } elasticsearch { hosts => "localhost:9200" } }
配置说明
- 删掉了冗余的grok步骤:如果你的日志每行都是标准JSON格式,直接用json过滤器解析
message即可,不需要额外提取JSON字符串 - 调整了date过滤器的执行顺序:放在JSON解析完成之后,确保能读到
datetime字段 - 修正了时间格式:新增了
,SSS匹配毫秒部分,保证格式完全对齐 - 新增时区配置:避免日志时间和UTC时间转换时出现8小时偏移,可根据你实际的日志时区调整
- 调试阶段可以给file input加上
sincedb_path => "/dev/null"配置,避免logstash记录文件读取位置,方便重复读取同一份日志测试
内容的提问来源于stack exchange,提问作者akhil kandari
相关产品推荐
相关产品推荐

