title: 问题一、时区问题
date: 2020-4-15 21:20:39
categories: elk
将生产日志时间替换@timestamp
之前一直使用自带的时间戳,因为之前切割没有提取日志文件中的时间也就是如
2020-03-14 08:00:00.000||DEBUG|com.cq.test.core.executor.VisibleThreadPoolTaskExecutor|18|showThreadPoolInfo|async-service-, 2. do submit,taskCount [679372], completedTaskCount [679371], activeCount [1], queueSize [0]
这种2020-03-14时间。
这次使用grok+mapping提取出来作为一个单独的字段time。
1、发现问题:
查询索引test-2020.03.14
[图片上传失败...(image-1e8fc9-1614773555418)]
time 和@timestamp不一致如图:
这两个时间正好差8个小时,开始我怀疑是我转化time的时候转化时区错了
2、kibana显示
再次回到kibana,我们查询是使用kibana这个工具的,于是尝试设置kibana的时区,一般两个选项,一个是国际时间UTC,一个是北京时间一般可以去Asia/ShangHai.还有个选项是browser,也就是跟随浏览器:
将日志展开:
[图片上传失败...(image-c704b5-1614773555418)]
由上可以看到问题来了:
- 我们当天的索引日志是从国际时间的0点开始,也就是我们中国时区的8点!!
- 我们转化时间也出了问题,本来是北京时间08:00转变成了国际时间08:00,
根本原因是:
-
对于第一条logstash将我们的日志内容和处理时间都用UTC时间来处理了,也就是创建索引使用了自带的时间
output{ elasticsearch{ hosts => ["xxx.xxx.xxx.xx:9200"] index => "test-%{+YYYY.MM.dd}" codec=rubydebug } }
那么它就会将我们北京时区8点以前的日志放在前一天的索引,如2020.14 07:00 -> 2020.13 23:00
-
对于第二点,我们将string字段转化为date字段时(如下图是mapping的配置),elasticsearch会以默认方式UTC来处理,因此变成了utc时间。
"time"{ "type": "date", "format": "yyyy-MM-dd HH:mm:ss.SSS" }
3、解决方法
1、使用logstash提供的date插件
插件介绍
将上面描述翻译一下就是
日期过滤器用于解析字段中的日期,然后使用该日期或时间戳作为事件的logstash时间戳。
大概的意思就是我们可以自己来使用文本中的时间设置时间戳。
在conf文件中加入data的插件:
date {
match => ["time","yyyy-MM-dd HH:mm:ss.SSS"]
}
上面其实还有很多配置,如target,默认是@timestamp,所以可以替换时间戳
再看结果,自定义字段已经正常转化时间与实际能对上。(后面我们把这个time替换默认的@timestamp)
2、使用自定义字段来替换索引中默认日志adc-%{+YYYY.MM.dd}
完整解决方案如下:
filter {
json {
source => "message"
remove_field => ["agent","ecs","input","kubernetes.pod","kubernetes.replicaset","log","stream","tags","@version"]
}
grok {
patterns_dir => ["/software/logstash/config/my_patterns"]
match =>{"message"=> "%{index_date:indexdate} %{MYSELFTIMESTAMP:time} %{LOGLEVEL:level}\s?-\***%{TRACEID:traceId}\***- %{THREAD:threadId} %{LOGGER:logger} - %{INFO:info}"} ## 使用自定义模板,这里我们拆分成indexdate和time是为了后面使用我们自己的日期作为索引,当然可能有更优的解决方案
add_field =>{"timeDate"=> "%{indexdate} %{time}" } # 将日期和时间拼接
}
date {
match => ["timeDate","yyyy-MM-dd HH:mm:ss.SSS"] #将我们的时间戳替换event的
}
}
output{
elasticsearch{
hosts => ["xxx:xxx:xx:9092"]
index => "test-%{indexdate}" #使用如上定义的字段
codec=>rubydebug
template_name => "test-template"
template => "/software/logstash/config/test-template.json"
template_overwrite => true
}
其中 my_patterns配置如下:
INFO [\s\S]*
TRACEID [a-zA-Z0-9._-]*
THREAD \[.*\]
LOGGER [a-zA-Z\.]*
index_date 20\d\d-\d\d-\d\d
MYSELFTIMESTAMP \d\d:\d\d:\d\d\.\d\d\d
Tips:
- 更新pattern并不会使logstash重新加载,只有修改.conf文件才会
- pattern 必须要加字段才能在logstash中生成