Logstash 时区问题

2021-03-03 10:45:54 浏览数 (1)

1. Date Filter 插件


  • 日期过滤器用于分析字段中的日期,然后使用该日期或时间戳作为事件的 logstash 时间戳。
1.1. 配置项

Setting

Input type

Required

Default

locale

string

No

No

match

array

No

[]

tag_on_failure

array

No

["_dateparsefailure"]

target

string

No

"@timestamp"

timezone

string

No

No

1.1.1 locate
1.1.2. match
1.1.3. tag_on_failure
  • Value type is array
  • Default value is ["_dateparsefailure"]

如果匹配失败,将值附加到 tag 字段。

1.1.4. target
  • Value type is string
  • Default value is "@timestamp"
  • 将匹配的时间戳存储到给定的目标字段中。如果未提供,则默认更新事件的@timestamp字段。
1.1.5. timezone

2. logstash @timestamp自定义


  • 在ELK组合中我们在 outputs/elasticsearch 中常用的 %{ YYYY.MM.dd} 来创建索引,而这种写法是必须要读 @timestamp 这个字段的。默认情况下 @timestamp 字段显示的是当前时间,但我们可能需要记录的是日志中的字符串类型的时间,所以我们需要把日志中字符串类型的时间覆盖掉 @timestamp 中的当前时间。
代码语言:javascript复制
input  {
     stdin{}
}
filter {
    grok {
        match => ["message", "%{TIMESTAMP_ISO8601:logdate}"] 
    }
    date {
        match => ["logdate", "yyyy-MM-dd HH:mm:ss.SSS"]
        target => "@timestamp"
    }
    mutate {
        remove => ["logdate"]
    }
}
output{
     stdout{
        codec=>rubydebug{}
     }
}
  • 附: logstash自带的正则 logstash-patterns

3. @timestamp 时间少 8 小时


3.1. 5.0 以下版本
代码语言:javascript复制
input { stdin {} }  
output { stdout { codec => rubydebug } }  
filter {  
  date {  
    match => ["message","UNIX_MS"] # message在实际应用中修改为自己的字段  
    target => "@timestamp"     
  }  
 ruby {   
   code => "event['timestamp'] = LogStash::Timestamp.new(event['@timestamp']  8*60*60)"   
 }  
 ruby {  
   code => "event['@timestamp']= event['timestamp']"  
 }  
 mutate {  
   remove_field => ["timestamp"]  
 }  
} 
3.2. 5.x 以上版本
代码语言:javascript复制
input { stdin {} }  
output { stdout { codec => rubydebug } }  
filter {  
  date {  
    match => ["message","UNIX_MS"]  
    target => "@timestamp"     
  }  
 ruby {   
   code => "event.set('timestamp', event.get('@timestamp').time.localtime   8*60*60)"   
 }  
 ruby {  
   code => "event.set('@timestamp',event.get('timestamp'))"  
 }  
 mutate {  
   remove_field => ["timestamp"]  
 }  
}

4. index 索引名称少 8 小时


代码语言:javascript复制
# 1. 增加一个字段,计算timestamp 8小时
ruby { 
    code => "event.set('index_date', event.get('@timestamp').time.localtime   8*60*60)" 
} 
# 2. 用mutate插件先转换为string类型,gsub只处理string类型的数据,在用正则匹配,最终得到想要的日期
mutate { 
    convert => ["index_date", "string"] 
    gsub => ["index_date", "T([Ss]*?)Z", ""] 
    gsub => ["index_date", "-", "."] 
}      
# 3.output配置
elasticsearch { 
  hosts => ["localhost:9200"] 
  index => "myindex_%{index_date}" 
}

5. 时区问题的解释


  • 很多中国用户经常提一个问题:为什么 @timestamp 比我们早了 8 个小时?怎么修改成北京时间?
  • 其实,Elasticsearch 内部,对时间类型字段,是统一采用 UTC 时间,存成 long 长整形数据的!对日志统一采用 UTC 时间存储,是国际安全/运维界的一个通识——欧美公司的服务器普遍广泛分布在多个时区里——不像中国,地域横跨五个时区却只用北京时间。
  • 对于页面查看,ELK 的解决方案是在 Kibana 上,读取浏览器的当前时区,然后在页面上转换时间内容的显示。
  • 所以,建议大家接受这种设定。否则,即便你用 .getLocalTime 修改,也还要面临在 Kibana 上反过去修改,以及 Elasticsearch 原有的 ["now-1h" TO "now"] 这种方便的搜索语句无法正常使用的尴尬。

0 人点赞