《Learning ELK Stack》3 使用Logstash採集、解析和轉換資料

yeedomliu發表於2020-07-30
  • 理解Logstash如何採集、解析並將各種格式和型別的資料轉換成通用格式,然後被用來為不同的應用構建多樣的分析系統

配置Logstash

  • 輸入外掛將源頭資料轉換成通用格式的事件,過濾外掛修改這些事件,最終輸出外掛將它們輸出到其他系統

image-20200625235030110


Logstash外掛

列出Logstash的所有外掛

bin/plugin list
  • 使用下面命令列出指定分組的外掛
bin/plugin list --group <group_name>
bin/plugin list --group output

外掛屬性的資料型別

陣列(Array

path => ["value1", "value2"]

布林值(Boolean

periodic_flush => false

編解碼器(Codec

  • 編解碼器實際上並不是一種資料型別,它是在輸入或輸出的時候對資料進行解碼或編碼的一種方式。上面例子指定在輸出時,編解碼器會將所有輸出資料編碼成json格式
codec => "json"

雜湊(Hash

  • 由一系列鍵值對組成的集合
match => {
    "key1" => "value1", "key2" => "value2"
}

字串(String

value => "welcome"

註釋(Comment

  • 以字元#開頭
# 這是一個註釋

欄位引用

  • 可使用[field_name]的方式引用,巢狀欄位可以使用[level1][level2]的方式指定

Logstash條件語句

  • 在某些條件下Logstash可以用條件語句來過濾事件或日誌記錄。Logstash中的條件處理和其他程式語言中的類似,使用ifif elseelse語句。多個if else語句塊可以巢狀
if <conditional expression1> {
# 一些處理語句
}
else if <conditional expression2> {
# 一些處理語句
}
else {
# 一些其他語句
}
  • 條件語句可以與比較運算子、邏輯運算子和單目運算子一起使用
  • 比較運算子包括以下幾種
  1. 相等運算子:==、!=、<、>、<=、>=
  2. 正規表示式:=、!
  3. 包含:innot in
  4. 邏輯運算子:andornandxor
  5. 單目運算子:!
filter {
  if [action] == "login" {
    mutate { remove => "password" }
  }
}
output {
    if [loglevel] == "ERROR" and [deployment] == "production" {
        email {}
    }
}

Logstash外掛的型別

  1. 輸入(Input
  2. 過濾器(Filter
  3. 輸出(Output
  4. 編解碼(Codec

輸入外掛

檔案(file

Logstash檔案輸入外掛將檔案讀取的最新位點儲存在$HOME/.sincdb*的檔案中。檔案路徑和重新整理頻率可以通過sincedb_path和sincdb_write_interval配置

input {
    file {
        path => "/GOOG.csv"
        add_field => {"input_time" => "%{@timestamp}"}
        codec => "json"
        delimiter => "\n"
        exclude => "*.gz"
        sincedb_path => "$HOME/.sincedb*"
        sincedb_write_interval => 15
        start_position => "end"
        tags => ["login"]
        type => ["apache"]
    }
}
選項 資料型別 是否必選 預設值 說明
add_field hash {} 增加欄位
codec string plain 用於指定編解碼器輸入
delimiter string `n ` 分隔符
exclude array [] 排除指定型別檔案
sincedb_path string $HOME/.sincedb 監視檔案當前讀取位點
sincedb_write_interval int 15 指定sincedb檔案寫入頻率
start_position string end 輸入檔案的初始讀取位點
tags array 給輸入事件增加一系列標籤
type string 給多個輸入路徑中配置的不同型別的事件指定type名稱
path array 日誌檔案路徑
input {
    file {
        path => ["/var/log/syslog/*"]
        type => "syslog"
    }
    file {
        path => ["/var/log/apache/*"]
        type => "apache"
    }
}
filter {
    if [type] == "syslog" {
        grok{}
    }
    if [type] == "apache" {
        grok{}
    }
    if "login" == tags[] {}
}
Redis
  • redis例項中讀取事件和日誌。經常用於輸入資料的訊息代理,將輸入資料快取到佇列,等待索引器讀取日誌
選項 資料型別 是否必選 預設值 說明
add_field hash {} 增加欄位
codec string plain 用於指定編解碼器輸入
data_type string list listBLPOP)、channelSUBSCRIBE命令訂閱key)、pattern_channelPSUBSCRIBE命令訂閱key
host string 127.0.0.1
key string
password string
port int 6379

文件連結:www.elastic.co/guide/en/logstash/c...

輸出

elasticsearch
  • 最重要的輸出外掛

image-20200626065529981

過濾器

  • 用於在輸出外掛輸出結果之前,對輸入外掛中讀取的事件進行中間處理。常用於識別輸入事件的欄位,並對輸入事件的部分內容進行條件判斷處理
csv
  • 用於將csv檔案輸入的資料進行解析,並將值賦給欄位
csv {
    columns => ["date_of_record","open","high","low","close","volume","adj_close"]
    separator => ","
}
date
  • 給事件賦予正確的時間戳非常重要,只有這樣才能在Kibana中使用時間過濾器對事件進行分析
date {
    match => ["date_of_record", "yyyy-MM-dd"]
}
drop
  • 將滿足條件的所有事件都丟棄掉,這個過濾外掛有下面這些配置選項
  1. add_field
  2. add_tag
  3. remove_field
  4. remove_tag
filter {
    if [fieldname == "test"] {
        drop {}
    }
}
geoip
  • 基於輸入事件中的IP地址給事件增加地理位置資訊。這些資訊從Maxmind資料庫中讀取

Maxmind是一個專門提供IP地址資訊產品的公司。GeoIP是它們開發的智慧IP產品,用於IP地址的位置跟蹤。所有Logstash版本都自帶一個Maxmind的GeoLite城市資料庫。這個地址資料庫可以從https://dev.maxmind.com/geoip/geoip2/geolite2/獲取

geoip {
    source => # 必選字串,需要使用geoip服務進行對映的ip地址或主機名
}
grok
  • 目前為止最流行、最強大的外掛。使用它可以解析任何非結構化的日誌事件,並將日誌轉化成一系列結構化的欄位,用於後續的日誌處理和分析
  • 可以用於解析任何型別的日誌,包括apachemysql、自定義應用日誌或者任何事件中非結構化的文字
  • Logstash預設包含了很多grok模式,可以直接用來識別特定型別的欄位,也支援自定義正規表示式
  • 所有可用grok模式從這裡獲取:https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns
HOSTNAME \b(?:[0-9A-Za-z][0-9A-Za-z-]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-]{0,62}))*(\.?|\b)
DAY (?:Mon(?:day)?|Tue(?:sday)?|Wed(?:nesday)?|Thu(?:rsday)?|Fri(?:day)?|Sat(?:urday)?|Sun(?:day)?)
YEAR (?>\d\d){1,2}
HOUR (?:2[0123]|[01]?[0-9])
MINUTE (?:[0-5][0-9])
  • 上面grok模式可以使用下面這樣的操作符直接識別這些型別的欄位。希望將日誌事件中代表主機名的文字賦值給host_name這個欄位
%{HOSTNAME:host_name}
  • 看一下如何用grok模式表示一行HTTP日誌
54.3.245.1 GET /index.html 14562 0.056
  • grok模式是這樣的
%{IP:client_ip} %{WORD:request_method} %{URIPATHPARAM:uri_path} %{NUMBER:bytes_transfered} %{NUMBER:duration}
filter {
    grok {
        match => { "message" => "%{IP:client_ip} %{WORD:request_method} %{URIPATHPARAM:uri_path} %{NUMBER:bytes_transfered} %{NUMBER:duration}" }
    }
}
  • 使用grok過濾器處理上面的事件後,可以看到事件中增加了如下欄位和值
  1. client_ip:54.3.245.1
  2. request_methodGET
  3. uri_path:/index.html
  4. bytes_transferred:14562
  5. duration:0.056
  • 如果grok模式中沒有需要的模式,可以使用正規表示式建立自定義模式

設計和測試grok模式

grokdebug.herokuapp.com/

grokconstructor.appspot.com/do/matc...

image-20200626073227543

mutate
  • 對輸入事件進行重新命名、移除、替換和修改欄位。也用於轉換欄位的資料型別、合併兩個欄位、將文字從小寫轉換為大寫等

image-20200626073755986

sleep
  • Logstash置於sleep模式,時間由引數指定,也可以基於事件指定sleep頻率
  • 如果希望每處理五個事件就sleep一秒,可以這樣配置
filter {
    sleep {
        time => "1"
        every => 5
    }
}

編解碼

  • 用於對輸入事件進行解碼,對輸出事件進行解碼,以流式過濾器的形式在輸入外掛和輸出外掛中工作,重要的編解碼外掛包括
  1. avro
  2. json
  3. line
  4. multiline
  5. plain
  6. rubydebug
  7. spool

輸入事件或輸出事件是完整的json文件,可以這樣配置(其中一種方式就可以)

input {
    stdin { codec => "json" }
    stdin { codec => json{} }
}

將每行輸入日誌作為一個事件,將每個輸出事件解碼成一行

input {
    stdin { codec => line{} }
    stdin { codec => "line" }
}

把多行日誌作為一個事件處理

input {
    file {
        path => "/var/log/someapp.log"
        codec => multiline {
            pattern => "^%{TIMESTAMP_ISO8601}"
            negate => true
            what => previous
        }
    }
}

rubydebug在輸出事件時使用,使用Ruby Awesome列印庫列印輸出事件

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章