Logstash filter 插件之 date

使用 date 插件解析字段中的日期,然后使用该日期或时间戳作为事件的 logstash 时间戳。对于排序事件和导入旧数据,日期过滤器尤其重要。如果您在事件中没有得到正确的日期,那么稍后搜索它们可能会出现问题。

如果时间戳尚未在事件中设置,logstash 将根据第一次看到事件(在输入时)创建一个时间戳。例如,对于文件输入,时间戳设置为每次读取的时间。

本文演示如何把现有的日志数据导入到 elasticsearch 中,并用日志中的时间信息设置事件的时间戳。

拆分日志信息

比如我们的日志格式如下:

[Trace] [e1a618cf-186f-49c5-b486-111e1e5f0023] [2019/03/25] [23:47:20 618]

第一个字段为 loglevel,第二个字段标识 SessionID,第三个字段是产生日志的日志,第四个字段是产生日志的时间,第三、四字段记录的是本地时间,即东八区区时(哈哈,居然不是记一个 UTC 时间戳!)。

我们先使用下面的 grok 规则切分出日志中的字段:

filter {
    grok {
        match => {
            "message" => "[%{LOGLEVEL:loglevel}]s*[(?<SessionID>.*)]s*[(?<Date>%{YEAR}/%{MONTHNUM}/%{MONTHDAY})]s*[(?<Time>%{HOUR}:%{MINUTE}:%{SECOND} %{INT})]"
        }
    }
}

得到 json 格式的日志记录如下(Grok Debugger 的输出):

{
  "loglevel": [
    [
      "Trace"
    ]
  ],
  "SessionID": [
    [
      "e1a618cf-186f-49c5-b486-111e1e5f0023"
    ]
  ],
  "Date": [
    [
      "2019/03/25"
    ]
  ],
  "Time": [
    [
      "23:47:20 618"
    ]
  ]
}

合并日期和时间字段

把分散的两个字段合并为时间戳字段,并移除 Date 和 Time 字段:

filter {
    mutate {
        add_field => { "Datetime" => "%{Date} %{Time}" }
    }
    mutate {
        remove_field => ["Date"]
    }
    mutate {
        remove_field => ["Time"]
    }
}

拼出来的 DateTime 字段中的内容格式为:

"2019/03/25 23:47:20 618"

为事件设置时间戳

下面使用 date 插件解析字段中的日期,然后使用该日期或时间戳作为事件的 logstash 时间戳:

filter {
    mutate {
      add_field => { "logtime" => "%{Datetime}" }
    }
    date {
      timezone => "Asia/Chongqing"
      match => ["logtime", "yyyy/MM/dd HH:mm:ss SSS"]
      target => "@timestamp"
      remove_field => [ "logtime" ]
    }
}

这里使用了一个临时字段 logtime 来保存时间戳,原因是 date 插件会把该字段的类型转换为 date,使用一个临时的字段就不会影响到 Datetime 字段的类型(这也是自定义 @timestamp 时的常用手法)。
注意上面的 timezone 配置,如果日志中的信息是以 UTC 格式保存的,就不需要指定时区。但是笔者处理的日志中,时间信息保存的是东八区的区时,因此需要指定时区信息,date 插件才能把它转换为 UTC 时间。
下图是该记录导入后在 Kibana 中显示的情况,可以看到日期信息和时间戳是一致的:

参考:
Date filter plugin

原文地址:https://www.cnblogs.com/sparkdev/p/11073924.html