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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM