1. 程式人生 > >ELK技術棧-Logstash的詳細使用

ELK技術棧-Logstash的詳細使用

本文作者:羅海鵬,叩丁狼高階講師。原創文章,轉載請註明出處。 

前言

在第九章節中,我們已經安裝好Logstash元件了,並且啟動例項測試它的資料輸入和輸出,但是用的是最簡單的控制檯標準輸入和標準輸出,那這節我們就來深入的學習Logstash的詳細使用。

常用啟動引數

我們在上一節中演示了啟動Logstash的例項,其中我們啟動的時候給Logstash指令碼傳入了-e的引數,但實際上,Logstash的啟動引數有很多,我們來看一下各個啟動引數的作用:

  • -e #立即啟動例項,例如:./logstash -e "input {stdin {}} output {stdout {}}"
  • -f #指定啟動例項的配置檔案,例如:./logstash -f config/test.conf
  • -t #測試配置檔案的正確性,例如:./logstash -f config/test.conf -t
  • -l #指定日誌檔名稱,例如:./logstash -f config/test.conf -l logs/test.log
  • -w #指定filter執行緒數量,不指定預設是5,例如:./logstash-f config/test.conf -w 8

配置檔案語法

檔案結構

我們剛剛知道,啟動引數可以指定一個配置檔案,那麼接下來就有必要來了解一下配置檔案的結構:Logstash通過{}來定義區域,區域內可以定義外掛,一個區域內可以定義多個外掛,如下:

input {
    #標準輸入源外掛
    stdin {
    }
    #普通檔案源外掛
    file {
        path => ["/var/log/*.log", "/var/log/message"]
       ....
    }
   ......
}
filter {
      #grok過濾外掛
      grok {
            match => ["message", "%{HTTPDATE:logdate}"]
            .....
      }
     #date過濾外掛
     date {
            match => ["logdate", "dd/MMM/yyyy:HH:mm:ss Z"]
           .....
    }
   .....
}
output {
     stdout {
     }
     elasticsearch {
        hosts => ["127.0.0.1:9200"]
        ....
    }
    .....
}

我們先大概瞭解一下配置檔案的結構,接下來我們再詳細看這些外掛的配置。

資料型別

Logstash配置檔案支援的資料型別有: 1、Boolean,例如:ssl_enable => true 2、Number,例如:port => 33 3、String,例如:name => “Hello world” 4、hash,例如:options => {key1 => “value1”, key2 => “value2”} 5、array,例如:match => [“datetime”, “UNIX”, “ISO8601”]

欄位引用

Logstash資料流中的資料被稱之為Event物件,Event以JSON結構構成,Event的屬性被稱之為欄位,如果你想在配置檔案中引用這些欄位,只需要把欄位的名字寫在中括號[]

裡就行了,如[type],對於巢狀欄位每層欄位名稱都寫在[]裡就可以了,比如:[tags][type];除此之外,對於Logstash的arrag型別支援下標與倒序下表,如:[tags][type][0][tags][type][-1]以下的內容就是一個Event物件:

{
      "message" => "hello logstash",
      "@version" => "1",
      "@timestamp" => 2018-08-13T17:32:01.122Z,
      "host" => "localhost.localdomain"
}

條件判斷

Logstash支援下面的操作符: 1、==(等於), !=(不等於), <(小於), >(大於), <=(小於等於), >=(大於等於) 2、=~(匹配正則), !~(不匹配正則) 3、in(包含), not in(不包含) 4、and(與), or(或), nand(非與), xor(非或) 5、()(複合表示式), !()(對複合表示式結果取反)例如以下的條件判斷:

if "_grokparsefailure" not in [tags] {
} 
else if [status] !~ /^2\d\d/ or ( [url] == "/noc.gif" nand [geoip][city] != "beijing" ) {
} 
else {
}

環境變數引用

Logstash支援引用系統環境變數,環境變數不存在時可以設定預設值,例如:

export TCP_PORT=12345
input {
  tcp {
    port => "${TCP_PORT:54321}"
  }
}

常用輸入外掛

在第九章中,我們已經使用是標準輸入,以鍵盤的輸入資料作為Logstash資料來源,但實際上我們也知道,Logstash的資料來源有很多,每種資料來源都有相應的配置,在Logstash中,這些資料來源的相應配置稱為外掛,我們常用的輸入外掛有:file、jdbc、redis、tcp、syslog,這些輸入外掛會監聽資料來源的資料,如果新增資料,將資料封裝成Event程序處理或者傳遞,更多的輸入外掛大家可以看Logstash官網,接下來我們以file和jdbc兩個輸入外掛作為例子,來學習輸入外掛的使用,其他輸入外掛使用起來大同小異,大家自行擴充套件。

file輸入外掛

讀取檔案外掛主要用來抓取檔案的資料變化資訊,以此作為Logstash的資料來源。

  • 配置示例:
    input{
    file {
      path => ["/var/log/*.log", "/var/log/message"]
      type => "system"
      start_position => "beginning"
    }
    }
    output{
    stdout{}
    }
    
  • 常用引數
引數名稱 資料型別 預設值 描述
path array 用於匹配被監控的檔案,如”/var/logs\/*.log”或者 “/var/log/message”,必須使用絕對路徑
type string Event的type欄位,如果採用elasticsearch做store,在預設情況下將作為elasticsearch的type
sincedb_path string “$HOME/.sincedb*” 檔案讀取記錄,必須指定一個檔案而不是目錄,檔案中儲存沒個被監控的檔案等當前inode和byteoffset
sincedb_write_interval number 15 間隔多少秒寫一次sincedb檔案
start_position string “end” 值為“beginning”和“end”,從檔案等開頭還是結尾讀取檔案內容,預設是結尾,如果需要匯入檔案中的老資料,可以設定為“beginning”,該選項只在第一次啟動logstash時有效,如果檔案已經存在於sincedb的記錄內,則此配置無效
stat_interval number 1 間隔多少秒檢查一下檔案是否被修改,加大此引數將降低系統負載,但是增加了發現新日誌的間隔時間
close_older number 3600 設定檔案多少秒內沒有更新就關掉對檔案的監聽
codec string “plain” 輸入資料之後對資料進行解碼
add_field hash {} 用於向Event中新增欄位
delimiter string “\n” 檔案內容的行分隔符,預設按照換行進行Event物件封裝,也就是說一行資料就一個Event物件
discover_interval number 15 間隔多少秒檢視一下path匹配的路徑下是否有新檔案產生
exclude array path匹配的檔案中指定例外,如:path => “/var/log/“;exclude =>”*.gz”
id string 區分兩個相同型別的外掛,比如兩個filter
ignore_older number 忽略歷史修改,如果設定3600秒,logstash只會發現一小時內被修改過的檔案,一小時之前修改的檔案的變化不會被讀取,如果再次修改該檔案,所有的變化都會被讀取,預設被禁用
tags array 可以在Event中增加標籤,以便於在後續的處理流程中使用

jdbc輸入外掛

該外掛可以使用jdbc把關係型資料庫的資料作為Logstash的資料來源

  • 配置示例:
    input {
    jdbc {
      jdbc_driver_library => "/opt/logstash/mysql-connector-java-5.1.36-bin.jar"
      jdbc_driver_class => "com.mysql.jdbc.Driver"
      jdbc_connection_string => "jdbc:mysql://localhost:3306/mydb"
      jdbc_user => "mysql"
      jdbc_password => "123456"
      parameters => { "favorite_artist" => "Beethoven" }
      schedule => "* * * * *"
      statement => "SELECT * from songs where artist = :favorite_artist"
    }
    }
    output{
    stdout{}
    }
    
  • 常用引數(空 = 同上)
引數名稱 資料型別 預設值 描述
jdbc_driver_library string jdbc連線驅動的jar包位置
jdbc_driver_class string jdbc驅動類
jdbc_connection_string string 資料庫的連線地址
jdbc_user string 資料庫的使用者名稱
jdbc_password string 資料庫的密碼
jdbc_paging_enabled boolean false 開啟分頁
jdbc_page_size number 100000 每頁查詢多少條資料
statement string 執行的SQL查詢語句
parameters hash {} 設定SQL查詢語句的引數
use_column_value boolean false 是否需要在程式中使用查詢出來的列
tracking_column string 需要在程式中使用哪個查詢出來的列
clean_run boolean false 是否應該保留先前的執行狀態
colums_charset hsah {} 特定列的字元編碼。此選項將覆蓋指定列的原來charset配置
schedule string 定時執行資料讀取的任務,使用cornexpression表示式:分、時、天、月、年,全部為*預設含義為每分鐘執行任務,該cornexpression表示式於Linux系統的crontab使用方式一樣,如果不會使用cornexpression表示式,可以檢視crontab相關文件。不設定的話,只執行一次資料的讀取
lowercase_column_names boolean true 是否需要把查詢出來的列名轉換成小寫,也就是說即使列名是駝峰的,也會轉成全部都是小寫的,預設為轉小寫,如果不需要,則設定為false
record_last_run boolean true 是否記錄資料庫中最後一條資料的位置
last_run_metadata_path string 記錄資料庫中最後一條資料的位置資訊存放路徑
add_field
codec
id
tags
type

常用過濾外掛

豐富的過濾器外掛的是 logstash威力如此強大的重要因素,過濾器外掛主要處理流經當前Logstash的事件資訊,可以新增欄位、移除欄位、轉換欄位型別,通過正則表示式切分資料等,也可以根據條件判斷來進行不同的資料處理方式。我們常用的過濾外掛有:grok、date、geoip、mutate、json、Split、ruby,更多的過濾外掛大家可以看Logstash官網,接下來我們以grok、date和geoip這3個過濾外掛作為例子,來學習過濾外掛的使用,其他過濾外掛使用起來大同小異,大家自行擴充套件。

grok正則外掛

grok正則捕獲是Logstash中將非結構化資料解析成結構化資料以便於查詢的最好工具,非常適合解析system log,web log, database log等任意的 log檔案。

  • 內建正則表示式呼叫 grok提供100多個常用正則表示式可供使用,這100多個正則表示式定義在logstash/vendor/bundle/jruby/x.x/gems/logstash-patterns-core-xxx/patterns/grok-patterns檔案中,想要靈活的匹配各種資料,那麼必須檢視該檔案,大概瞭解grok提供了什麼內建的正則表示式。呼叫它們的語法如下:%{SYNTAX:SEMANTIC} SYNTAX:表示內建的正則表示式的名稱 SEMANTIC:表示在Event中建立該欄位名來儲存匹配到的值 例如:輸入的資料內容為“[debug] 127.0.0.1 - test log content”,我們想提取127.0.0.1這個IP地址,那麼可以使用以下語法來匹配:%{IP:client},將獲得“client: 127.0.0.1”的結果,該結果將成為Event的一個新的欄位和欄位值;如果你在捕獲資料時想進行資料型別轉換可以使用%{NUMBER:num:int}這種語法,預設情況下,所有的返回結果都是string型別,當前Logstash所支援的轉換型別僅有“int”和“float”;

  • 自定義表示式呼叫 與預定義表示式相同,你也可以將自定義的表示式配置到Logstash中,然後就可以像於定義的表示式一樣使用;以下是操作步驟說明: 1、在Logstash根目錄下建立資料夾“patterns”,在“patterns”資料夾中建立檔案“extra”(檔名稱無所謂,可自己選擇有意義的檔名稱); 2、在檔案“extra”中新增表示式,格式:patternName regexp,名稱與表示式之間用空格隔開即可,例如:POSTFIX_QUEUEID [0-9A-F]{10,11} 3、使用自定義的表示式時需要在grok外掛配置“patterns_dir”屬性,屬性值為extra檔案所在的目錄。

  • 配置示例 日誌檔案http.log每行內容為:55.3.244.1 GET /index.html 15824 0.043 message-id:BEF25A72965 grok表示式:表示式:%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration} 配置檔案內容:

    input {
    file {
      path => "/var/log/http.log"
    }
    }
    filter {
    grok {
      patterns_dir => ["./patterns"]
      match => {"message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration} message\-id:%{POSTFIX_QUEUEID:queueid}"}
    }
    }
    output{
      stdout{}
    }
    

    輸出結果:

    client: 55.3.244.1
    method: GET
    request: /index.html
    bytes: 15824
    duration: 0.043
    queueid: BEF25A72965
    
  • 示例解析 1、/var/log/http.log檔案每一行的格式為55.3.244.1 GET /index.html 15824 0.043 message-id:BEF25A72965,到時候會把每一行資料封裝成一個Event。 2、使用grok過濾外掛處理該檔案,match為匹配Event中的message,message就是該檔案的一行資料,比如55.3.244.1 GET /index.html 15824 0.043 message-id:BEF25A72965。 3、匹配message的內容使用%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration} message\-id:%{POSTFIX_QUEUEID:queueid}表示式,把一條message拆成client、method、request、bytes、duration、queueid這6個欄位,並新增到Event中。 4、其中%{POSTFIX_QUEUEID:queueid}為自定義表示式的呼叫,其他5個是grok內建的表示式呼叫,如果需要使用自定義表示式,則需要在grok外掛配置patterns_dir屬性,屬性值資料型別為array,就是自定義表示式定義的檔案所在的目錄。 5、在表示式中,特殊字元需要使用\來轉義,比如-""[]這些特殊字元,所以我們上面例項中的message-id資料在用表示式匹配的時候是使用了message\-id去匹配了。
  • 常用引數(空 = 同上)
引數名稱 資料型別 預設值 描述
match array {} 設定pattern陣列
patterns_dir array [] 指定自定義的pattern檔案存放目錄,Logstash在啟動時會讀取資料夾內所有檔案,但前提是這些檔案的內容是按照grok語法語法來定義的表示式變數
patterns_files_glob string “*” 用於匹配patterns_dir中的檔案
add_field
add_tag
id
break_on_match boolean true match欄位存在多個pattern時,當第一個匹配成功後結束後面的匹配,如果想匹配所有的pattern,將此引數設定為false
keep_empty_captures boolean false 如果為true,捕獲失敗的欄位獎設定為空值
clean_run boolean false 是否應該保留先前的執行狀態
colums_charset hsah {} 特定列的字元編碼。此選項將覆蓋指定列的原來charset配置
overwrite array [] 覆蓋欄位內容: match=> { “message” => “%{SYSLOGBASE} %{DATA:message}” } overwrite=> [ “message” ]
periodic_flush boolean false 定期呼叫filter的flush方法
remove_field array [] 從Event中刪除指定欄位: remove_field=> [ “fieldname” ]
remove_tag array [] 刪除“tags”中的值: remove_tag=> [ “tagname” ]
tag_on_failure array [“_grokparsefailure”] 當沒有匹配成功時,將此array新增到“tags”欄位內
tag_on_timeout string “_groktimeout” 當匹配超時時,將此字串內容新增到“tags”欄位內
timeout_millis number 30000 設定單個match到超時時間,單位:毫秒,如果設定為0,則不啟用超時設定

date時間處理外掛

在講date外掛的使用前,我們需要先講解一下Logstash的時間記錄方式。在Logstash產生了一個Event物件的時候,會給該Event設定一個時間,欄位為“@timestamp”,同時,我們的日誌內容一般也會有時間,但是這兩個時間是不一樣的,因為日誌內容的時間是該日誌打印出來的時間,而“@timestamp”欄位的時間是input外掛接收到了一條資料並建立Event的時間,所有一般來說的話“@timestamp”的時間要比日誌內容的時間晚一點,因為Logstash監控資料變化,資料輸入,建立Event導致的時間延遲。這兩個時間都可以使用,具體要根據自己的需求來定。 但是不管“@timestamp”欄位的時間還是日誌內容中的時間,其時間格式一般都不是我們想要的,所以我們就需要使用date外掛,把時間格式轉成我們想要的格式,比如:比如將Apr 17 09:32:01(MMM dd HH:mm:ss)轉換為04-17 09:32:01 (MM-dd HH:mm:ss)

  • 配置示例:
    filter {
      date {
          match => ["timestamp","dd/MMM/YYYY:HH:mm:ss Z"]
      } 
    }
    
  • 示例解析timestamp是自定義的Event欄位,用於存放通過grok解析到的日誌內容中的時間,dd/MMM/YYYY:HH:mm:ss Z是日誌內容中的時間格式,比如:16/Sep/2018:00:42:38 +0800,匹配到了之後,date外掛會預設把該時間轉成本地格式的時間,並且覆蓋掉Event為我們建立的欄位中的時間。
  • 常用引數(空 = 同上)
引數名稱 資料型別 預設值 描述
add_field
add_tag
periodic_flush
id
remove_field
remove_tag
remove_tag
tag_on_failure
match array [] 時間欄位匹配,可自定多種格式,直到匹配到或者匹配結束,格式:[ field,formats… ],如:match=> [ “logdate”, “MMM dd yyyy HH:mm:ss”, “MMM d yyyy HH:mm:ss”, “ISO8601” ]
target string 指定match匹配並且轉換為date型別的儲存位置(欄位),預設覆蓋到“@timestamp
timezone string 指定時間格式化的時區

geoip外掛

  • 配置示例:
    filter {
       if [remote_ip] !~ "^127\.|^192\.168\.|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[01]\.|^10\." {
          geoip {
               source => "remote_ip"
               database => "/usr/share/GeoIP/GeoLite2-Country.mmdb"
          }
      }
    }
    
  • 示例解析 由於geoip使用的ip資料庫不能匹配私網地址,所以在使用geoip外掛前,先判斷一下ip地址是否為私網ip,如果不是,這使用geoip外掛。source為指定一個ip地址,為其查詢歸屬地等資訊,remote_ip為Event中儲存ip地址的自定義欄位,database為IP地址資料庫所在的位置,不指定的話,使用geoip外掛內建的GeoLite2-City預設資料庫。
  • 常用引數(空 = 同上)
引數名稱 資料型別 預設值 描述
add_field
add_tag
periodic_flush
id
remove_field
remove_tag
remove_tag
source string 要通過geoip外掛查詢的IP地址所在的欄位
tag_on_failure array [“_geoip_lookup_failure”] 如果ip地址查詢不到地理位置資訊,這在標籤中新增該值
cache_size number 1000 由於geoip查詢很耗時間,所以預設情況下,查詢過一次的ip地址會快取起來,目前geoip沒有記憶體資料驅逐策略,設定的快取用完了就不能在快取新的資料了,所以快取需要設定一個合理值,太小查詢效能增加不明顯,太大就很佔用伺服器的記憶體
target string “geoip” 把IP地址匹配到的資訊放到該欄位中
database string 使用的Maxmind資料庫檔案的路徑。 如果不指定,則預設資料庫是GeoLite2-City。 GeoLite2-City,GeoLite2-Country,GeoLite2-ASN是Maxmind支援的免費資料庫。 GeoIP2-City,GeoIP2-ISP,GeoIP2-Country是Maxmind支援的商業資料庫。
default_database_type string “City” 該欄位的值只能接受”City”和”ASN”,GeoLite2資料庫下細分為GeoLite2-City,GeoLite2-ASN和GeoLite2-Country,geoip外掛內嵌了GeoLite2-City和GeoLite2-ASN,預設使用GeoLite2-City,如果需要使用GeoLite2-ASN,則需設定該欄位並設定為ASN
fields array 要包含在Event中的geoip欄位的資訊(每個資料庫的資訊都不一樣)。 預設情況下,所有資訊都會列出。對於內建的GeoLite2-City資料庫,可以使用以下資訊:city_name, continent_code, country_code2, country_code3, country_name, dma_code, ip, latitude, longitude, postal_code, region_name 和 timezone

常用輸出外掛

經過以上的學習,我們已經學習了Logstash三大主件中的其中兩個了,分別是input和filter,那現在我們就來學習最後一個元件:output。 每個資料流經過input和filter後,最終要由output輸出,以上的內容我們都是使用最簡單的標準輸出:stdout,把資料輸出到顯示器,但實際上stdout只是Logstash的其中一個輸出外掛而已,它的常用輸出外掛有:Elasticsearch,Redis,File,TCP等等,更多的輸出外掛大家可以看Logstash官網,接下來我們以Elasticsearch和Redis輸出外掛作為例子,來學習輸出外掛的使用,其他過濾外掛使用起來大同小異,大家自行擴充套件。

elasticsearch輸出外掛

用於將Event資訊寫入到Elasticsearch中,官方推薦外掛,ELK技術棧必備外掛。

  • 配置示例
    output {
      elasticsearch {
          hosts => ["127.0.0.1:9200"]
          index => "logstash-%{type}-%{+YYYY.MM.dd}"
          document_type => "%{type}"
      }
    }
    
  • 常用引數(空 = 同上)
引數名稱 資料型別 預設值 描述
add_field
add_tag
periodic_flush
flush_size
id
remove_field
remove_tag
codec
enable_metric
hosts array elasticsearch伺服器叢集所在的地址
index string [無] 文件索引庫名稱
document_type string [無] 文件型別,不指定的話,型別名為“doc”
document_id string [無] 文件id,不指定的話,由elasticsearch自動生成
user string [無] elasticsearch使用者名稱
password string [無] elasticsearch叢集訪問密碼
parent string “nil” 為文件子節點指定父節點的id
pool_max number 1000 elasticsearch最大連線數
pool_max_per_route number 100 每個“endpoint”的最大連線數
proxy string 代理URL
template string 設定自定義的文件對映模版存放路徑
template_name string 設定使用的默版名稱
template_overwrite boolean false 是否始終覆蓋現有模版
manage_template boolean true 是否啟用elasticsearch模版,Logstash自帶一個模版,但是隻有名稱匹配“logstash-*”的索引才會應用該默版
parameters hash 新增到elasticsearch URL後面的引數鍵值對
timeout number 60 網路超時時間

redis輸出外掛

用於將Event寫入Redis中進行快取,由於Redis資料庫是先把資料存在記憶體的,所以效率會非常高,是一個常用的logstash輸出外掛

  • 配置示例
    output {
      redis {
          host => ["127.0.0.1"]
          port => 6379
          data_type => "list"
          key => "logstash-list"
      }
    }
    
  • 常用引數(空 = 同上)
引數名稱 資料型別 預設值 描述
add_field
add_tag
periodic_flush
flush_size
id
remove_field
remove_tag
codec
enable_metric
hosts array [“127.0.0.1”] redis服務列表,如果配置多個,將隨機選擇一個,如果當前的redis服務不可用,將選擇下一個
port number 6379 文件索引庫名稱
db number 0 使用的redis資料庫編號,預設使用0號資料庫
password string redis的密碼
data_type string 儲存在redis中的資料型別,只能使用“list”和“channel”這兩個值。如果使用“list”,將採用“RPUSH”操作,如果是“channel”,將採用“PUBLISH”操作
key string 給redis設定一個key,來儲存收集到的資料庫
batch boolean false 是否啟用redis的batch模式,僅在data_type=”list”時有效
batch_events number 50 batch大小,batch達到此大小時執行“RPUSH”

後記

那到這裡,我們已經介紹了Logstash配置檔案的語法和常用外掛的配置方式了,這些常用的外掛都是使用頻率非常高的,所有我們後面需要來做一個Logstash的實戰案例,綜合運用我們這章所學的內容。