如何正确配置ELK栈?替换@timestamp为logtime后日志消失求助
我之前在维护ELK栈的时候碰到过一模一样的坑!你说的这个情况,90%以上是date过滤器的配置和logtime字段的实际格式不匹配,或者logtime字段本身不存在,导致Logstash解析时间失败,进而让这些日志没有被正确输出到Elasticsearch。下面给你一步步的排查和解决方法:
你得先确认日志里的logtime字段到底是什么样的——是2024-05-20 14:30:45这种常规格式,还是带时区的2024-05-20T14:30:45+08:00,甚至是其他自定义格式?
可以先临时注释掉10-java-filter.conf里的date过滤器,然后修改30-elasticsearch-output.conf,临时加一个控制台输出:
output { elasticsearch { hosts => ["localhost:9200"] index => "your-app-logs-%{+YYYY.MM.dd}" } # 临时输出到控制台查看字段详情 stdout { codec => rubydebug } }
重启Logstash后,看控制台输出的日志内容,找到logtime字段的具体值和格式,把它记下来。
回到10-java-filter.conf,调整date过滤器的配置,核心是让match参数里的格式和你刚查到的logtime格式完全匹配。举几个常见例子:
- 如果logtime是
2024-05-20 14:30:45:
filter { date { # 第一个参数是要解析的字段名,第二个是对应的格式 match => [ "logtime", "yyyy-MM-dd HH:mm:ss" ] # 指定把解析后的时间赋值给@timestamp,替换默认值 target => "@timestamp" # 可选:给解析成功的事件打标签,方便后续排查 add_tag => [ "date_parsed_success" ] # 如果解析失败,Logstash会自动加_tag => "_dateparsefailure",不用手动加 } }
- 如果logtime是带时区的ISO8601格式,比如
2024-05-20T14:30:45.123Z:
filter { date { match => [ "logtime", "ISO8601" ] target => "@timestamp" } }
- 如果logtime是自定义格式,比如
05/20/2024 2:30 PM:
filter { date { match => [ "logtime", "MM/dd/yyyy h:mm a" ] target => "@timestamp" } }
⚠️ 重点提醒:一定要确保你写的字段名和日志里的完全一致——比如别把log_time写成logtime,大小写也不能错!
默认情况下,Logstash不会直接丢弃解析失败的事件,但如果你没配置对应输出,就看不到它们。可以在输出配置里单独给失败的日志建一个索引,方便排查:
output { # 把解析失败的日志输出到单独索引 if "_dateparsefailure" in [tags] { elasticsearch { hosts => ["localhost:9200"] index => "failed-logs-%{+YYYY.MM.dd}" } } else { # 正常日志输出到原索引 elasticsearch { hosts => ["localhost:9200"] index => "your-app-logs-%{+YYYY.MM.dd}" } } }
这样你就能在Kibana里找到failed-logs-*索引,看看哪些日志解析失败了,进而调整date过滤器的格式。
修改完配置后,记得重启Logstash生效:
sudo systemctl restart logstash
同时可以查看Logstash的日志有没有报错:
sudo tail -f /var/log/logstash/logstash-plain.log
如果有格式不匹配的问题,日志里会明确提示类似Failed parsing date from field [logtime]的错误,根据提示调整格式就行。
另外,Ubuntu16.04上的Logstash版本可能偏旧,个别格式的支持可能有差异,但核心逻辑都是匹配格式一定要和字段值完全一致。
内容的提问来源于stack exchange,提问作者Mihail Gogol

