打赏

星辰大海ゞ

That which does not kill us makes us stronger!

导航

日志收集时的时间戳处理

Logstash在处理数据的时候,会自动生成一个字段@timestamp,默认该字段存储的是Logstash收到消息/事件(event)的时间。很多时候我们用ELK是处理日志的,日志里面一般都是有时间的。而且很多时候我们只关注日志里面的时间,而不关注Logstash收到这条日志的时间。这个时候,一种方法是再增加一个字段,用来存储日志里面的时间,这种很简单;另一种方法是使用日志中的时间替换掉@timestamp字段默认的时间。本文介绍第二种方法并总结一些关键知识点。

一、Nginx配置$time_local

以Logstash采集Nginx日志为例,格式如下:

log_format main '$remote_addr - [$time_local] "$request_method $uri $query_string" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time $upstream_response_time';

175.167.136.165 - [19/May/2020:17:44:03 +0800] "POST /upload -" 200 65 "https://static.cam.com/2020/comicfood/v3/index.html" "Mozilla/5.0 (Linux; Android 10; WLZ-AL10 Build/HUAWEIWLZ-AL10; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.64 Mobile Safari/537.36 androidapp.foodle" 0.487 0.224 

@timestamp字段是内置的,和之前说的一样,时间是Logstash收到消息的时间,而且注意使用的是UTC时间

timestamp字段是我们解析规则里面定义的字段(字段名随便起,不能有特殊符号,比如@),该字段存储的是从日志里面解析出来的时间,注意这个时间格式完全是日志里面时间的格式。要注意我们使用的timestamp和系统内置的@timestamp不是同一个字段。

1、ISO8601形式以及时间戳转换覆盖

如上的日志格式时时在grok中可以这么写:

grok {
        match => { "message", "%{HTTPDATE:timestamp}"
}

2、时间转存覆盖@timestamp有两种写法可以供使用

date {
        match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
#timezone => "UTC" target => "@timestamp" }

上述配置的含义是,将time_field字段按照"dd/MMM/yyyy:HH:mm:ss Z"格式解析后存到target指定的字段end_time字段去。time_field必须是已经定义的字段,最常见的就是在grok里面解析出来的某个时间字段。时间格式可查看Date插件的文档。如果没有指定target,默认就是@timestamp字段,这就是为什么我们可以使用该插件来修改@timestamp字段值的原因。

或者是

date {
        match => ["timestamp", "ISO8601"]
    }

都可以实现ISO8601时间的匹配格式。

另外,timezone字段在某些场景下也非常重要,如果从时间的值里面解析不出来时区,而且我们也没有指定时区的话,程序就会认为我们的时间字段的时区就是系统所处时区。比如上面从timestamp转到@timestamp的时候,时间值里面没有时区,所以使用了系统的时区东八区。当然,我们可以使用该字段指定时区。 

二、Nginx配置$time_iso8601 (新加字段方式)

log_format json '{"@timestamp":"$time_iso8601",'
                        '"@version":"1",'
                        '"host":"$clientRealIp",'
                        '"size":$body_bytes_sent,'
                        '"reponsetime":$request_time,'
                        '"domain":"$host",'
                        '"url":"$uri",'
                        '"status":"$status"}';

 

获取到的日志通常为

{"@timestamp":"2018-06-26T15:39:56+08:00","@version":"1","host":"192.168.29.7","size":0,"reponsetime":0.000,"domain":"www.logstashtest.com","url":"/images/logo3.png","status":"304"}

时间格式:2018-06-26T15:39:56+08:00

此时logstash配置如下:

input { 
        file {  
                path => "/home/nginx/logs/logstash_iso_test_access.log"
        }
}

filter {
        json {  
                source => "message"
        }
        grok {  
                match => ["message","%{TIMESTAMP_ISO8601:isotime}"]
        }

        date {  
                locale => "en"
                match => ["isotime", "ISO8601"]
        }
#       mutate {
#               remove_field => ["@timestamp"]
#       }
}

output {
        stdout {
                codec => "rubydebug"
        }
}

 

此时访问nginx日志为:

{"@timestamp":"2018-06-26T15:45:43+08:00","@version":"1","host":"192.168.29.7","size":0,"reponsetime":0.000,"domain":"www.logstashtest.com","url":"/images/logo3.png","status":"304"}

logstash输出:

{
        "@version" => "1",
            "host" => "Sandos1",
      "@timestamp" => 2018-06-26T07:45:43.000Z,
         "message" => "192.168.29.7 - - [26/Jun/2018:15:45:43 +0800] \"GET /images/logo3.png HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:60.0) Gecko/20100101 Firefox/60.0\" \"-\" \"192.168.29.7\" \"0.000\"",
    "request_time" => "26/Jun/2018:15:45:43 +0800",
            "path" => "/home/nginx/logs/main_logstashtest_access.log"
}

 

 

附:时间匹配规则表

 

posted on 2020-05-19 18:54  星辰大海ゞ  阅读(3181)  评论(0编辑  收藏  举报