Logstash配置詳解(不斷更新)
1. Input Plugin
1.1 從檔案輸入
從檔案讀取資料,如常見的日誌檔案。檔案讀取通常要解決幾個問題:
No. | 問題 | 解決辦法 |
---|---|---|
1 | 檔案內容如何只被讀取一次?即重啟Logstash時,從上次讀取的位置繼續 | sincedb |
2 | 如何即時讀取到檔案的新內容 | 定時檢查檔案是否有更新 |
3 | 如何發現新檔案並進行讀取 | 定時檢查是否有新檔案生成 |
4 | 如何檔案發生了歸檔(rotation)操作,是否影響當前的內容讀取 | 不影響,被歸檔的檔案內容可以繼續被讀取 |
1.1.1 logstash-input-file配置
配置:
配置項 | 說明 |
---|---|
path | 陣列型別,用於知名讀取的檔案路徑,基於glob匹配語法。 |
exclude | 陣列型別,排除不想監聽的檔案規則,基於glob匹配語法 |
sincedb_path | 字串型別,記錄sinceddb檔案路徑,預設路徑是當前使用者的home資料夾 |
start_position | 字串型別,可以配置為beginning/end,是否從頭讀取檔案 |
stat_interval | 數值型別,單位為秒,定時檢查檔案是否有更新,預設是1秒 |
discover_interval | 數值型別,單位為秒,定時檢查是否有新檔案待讀取,預設是15秒 |
ignore_older | 數值型別,單位為秒,掃描檔案列表時,如果該檔案上次更改時間超過設定的時長,則不做處理,但依然會監控是否有新內容,預設關閉 |
close_older | 數值型別,單位為秒,如果監聽的檔案在超過該設定時間內沒有新內容,會被關閉檔案控制代碼,釋放資源,但依然會監控是否有新內容,預設3600秒,即1小時 |
1.1.2 path
例如:
/var/log/*.log
:匹配/var/log
目錄下以.log
結尾的所有檔案/var/log/**/*.log
:匹配/var/log
所有子目錄下以.log
結尾的檔案/var/log/{app1,app2,app3}/*.log
:匹配/var/log
目錄下app1
,app2
,app3
子目錄中以.log
結尾的檔案
1.1.3 sincedb
通過logstash-input-file外掛匯入了一些本地日誌檔案時,logstash會通過一個名為sincedb的獨立檔案中來跟蹤記錄每個檔案中的當前位置。這使得停止和重新啟動Logstash成為可能,並讓它在不丟失在停止Logstashwas時新增到檔案中的行數的情況下繼續執行。sincedb預設儲存在當前使用者的Home目錄下。
在除錯的時候,我們可能希望取消sincedb的記錄功能,使檔案每次都能從頭開始讀取。此時,我們可以這樣來做:
input {
file {
path => ["檔案路徑"]
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
1.2 從HTTP輸入
input {
http {
port => 埠號
}
}
1.3 從TCP輸入
input {
tcp {
mode => "server"
host => "0.0.0.0"
port => 埠號
codec => json_lines
}
}
2. Codec Plugin
Codec Plugin作用於Input和Output Plugin,負責將資料在原始與Logstash Event之間轉換,常見的codec有:
- plain:讀取原始內容
- dots:將內容簡化為點進行輸出
- rubydebug:將Logstash Events按照ruby格式輸出,方便除錯
- line:處理帶有換行符的內容
- json:處理json格式的內容
- multiline:處理多行資料的內容
2.1 multiline
當一個Event的message由多行組成時,需要使用multiline,常見的情況是處理日誌資訊,如下所示:
Exception in thread "main" java.lang.NullPointerException
at com.example.myproject.Book.getTitle(Book.java:16)
at com.example.myproject.Author.getBookTitles(Author.java:25)
at com.example.myproject.Bootstrap.main(Bootstrap.java:14)
主要設定引數如下:
引數 | 說明 |
---|---|
pattern | 設定行匹配的正則表示式,可以使用grok |
what | 可設定為previous或next。表示當與pattern匹配成功的時候,匹配行是歸屬上一個事件還是下一個事件 |
negate | 布林值,表示是否對pattern的結果取反 |
例如,匹配日誌檔案:
input {
file {
path => ["檔案路徑"]
start_position => "beginning"
codec => multiline {
pattern => "^\s" #匹配以空格開頭的行
what => "previous"
}
}
}
3. Filter Plugin
Filter是Logstash功能強大的主要原因,它可以對Logstash Event進行豐富的處理,比如解析資料、刪除欄位、型別轉換等等,常見的有如下幾個:
外掛名稱 | 說明 |
---|---|
date | 日期解析 |
grok | 正則匹配解析 |
dissect | 分隔符解析 |
mutate | 對欄位作處理,比如重新命名、刪除、替換 |
json | 按照json解析欄位內容到指定欄位中 |
geoip | 增加地理位置資料 |
ruby | 利用ruby程式碼來動態修改Logstash Event |
3.1 date外掛
date外掛可以將日期字串解析為日期型別,然後替換@timestamp欄位或者指定其他欄位:
filter {
date {
match => ["logdate", "MM dd yyy HH:mm:ss"]
}
}
通過以上配置,我們可以將
{
"logdate": "Jan 01 2018 12:02:2018"
"target": "@timestamp"
}
轉換為:
{
"@version" => "1"
"host" => "..."
"logdate" => Jan01 2018 12:02:08
"@timestamp" => "2018-01-01T04:02:08.000Z"
}
3.2 grok外掛
grok外掛用於解析日誌內容,例如我們要將下面這一條日誌解析成json陣列。
83.149.9.216 [17/May/2015:10:05:03 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-search.png HTTP/1.1" 200 203023 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
那麼我們就可以這樣來配置grok:
%{IPORHOST:clientip} \[%{HTTPDATE:timestamp}\] "%{WORD:verb} %{DATA:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response:int} (?:-|%{NUMBER:bytes:int}) %{QS:referrer} %{QS:agent}
grok語法:
例子:%{SYNTAX:SEMANTIC}
SYNTAX為grok pattern的名稱,SEMANTIC為賦值欄位名稱。%{NUMBER:duration}可以匹配數值型別,但是grok匹配出的內容都是字串型別,可以通過在最後指定為int或者float來強轉型別:%{NUMBER:duration:int}
grok內建pattern:logstash-patterns-core
自定義grok pattern
我們通過pattern_definitions引數,以鍵值對的方式定義pattern名稱和內容。也可以通過pattern_dir引數,以檔案的形式讀取pattern。
filter {
grok {
match => {
"message" => "%{SERVICE:service}"
}
pattern_definitions => {
"SERVICE" => "[a-z0-9]{10,11}"
}
}
}
3.3 dissect外掛
基於分隔符原理解析資料,解決grok解析時消耗過多cpu資源的問題。
同樣的日誌資訊,dissect可以這樣來寫:
83.149.9.216 [17/May/2015:10:05:03 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-search.png HTTP/1.1" 200 203023 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
dissect配置:
%{clientip} [%{timestamp}] "%{request}" %{response} %{bytes} "%{referrer}" "%{agent}"
但是,正因為dissect語法簡單,因此它能處理的場景比較有限。它只能處理格式相似,且有分隔符的字串。它的語法如下:
- %{}裡面是欄位
- 兩個%{}之間是分隔符。
例子1:
有以下日誌:
Apr 26 12:20:02 localhost systemd[1]: Starting system activity accounting tool
我想要把前面的日期和時間解析到同一個欄位中,那麼就可以這樣來做:
filter {
dissect {
mapping => {
"message" => "%{ts} %{+ts} %{+ts} %{src} %{prog}[%{pid}]: %{msg}"
}
}
}
例子2:
如果有以下日誌:
name=hushukang&age=28
我想要把它解析成:
{
"name": "hushukang",
"age": 28
}
那麼,可以這樣來寫dissect:
filter {
dissect {
mapping => {
"message" => "%{?key1}=%{&key1}&%{?key2}=%{&key2}"
}
convert_datatype => {
age => "int"
}
}
}
%{?}
代表忽略匹配值,但是賦予欄位名,用於後續匹配用。%{&}
代表將匹配值賦到指定欄位中。convert_datatype
可以將指定字串轉為int或者float型別。
3.4 mutate外掛
mutate是使用最頻繁的外掛,可以對欄位進行各種操作,比如重新命名、刪除、替換、更新等,主要操作如下:
- convert型別轉換
- gsub字串替換
- split、join、merge字串切割、數組合併為字串、數組合併為陣列
- rename欄位重新命名
- update、replace欄位內容更新或替換。它們都可以更新欄位的內容,區別在於update只在欄位存在時生效,而replace在欄位不存在時會執行新增欄位的操作
- remove_field刪除欄位
mutate {
convert => {"age" => "integer"}
gsub => [
"birthday", "-", "/",
"image", "\/", "_"
]
split => {"hobities" => ","}
rename => {"hobities" => "hobityList"}
replace => {"icon" => "%{image}"}
remove_field => ["message"]
}
3.5 json外掛
將欄位內容為json格式的資料解析出來。
語法如下:
filter {
json {
source => "message"
target => "msg_json"
}
}
如果不指定target
的話,那麼filter會把解析出來的json資料直接放到根級別。
3.6 geoip外掛
常用的外掛,根據ip地址提供對應的地域資訊,比如經緯度、城市名等,方便進行地理資料分析。
語法如下:
filter {
geoip {
source => "clientIp"
}
}
4. Output Plugin
4.1 輸出到控制檯
多用於除錯
output {
stdout {
codec => rubydebug
}
}
4.2 輸出到檔案
實現將分散在多地的檔案統一到一處的需求,比如將所有web機器的web日誌收集到1個檔案中,從而方便查閱資訊
output {
file {
path => "檔案路徑"
codec => line {format => %{message}}
}
}
4.3 輸出到elasticsearch
output {
elasticsearch {
hosts => ["http://192.168.3.12:9200"]
index => "logstash-%{+YYYY.MM.dd}"
document_type => "_doc"
user => "使用者名稱"
password => "密碼"
}
}