日志分析logstash插件-grok详解
? ? 一般系統或服務生成的日志都是一大長串。每個字段之間用空格隔開。logstash在獲取日志是整個一串獲取,如果把日志中每個字段代表的意思分割開來在傳給elasticsearch。這樣呈現出來的數據更加清晰,而且也能讓kibana更方便的繪制圖形。
? ? Grok 是 Logstash 最重要的插件。它的主要作用就是將文本格式的字符串,轉換成為具體的結構化的數據,配合正則表達式使用。
grok表達式
下面針對Apache日志來分割處理
filter?{if?[type]?==?"apache"?{grok?{match?=>?["message"?=>?"%{IPORHOST:addre}?%{USER:ident}?%{USER:auth}?\[%{HTTPDATE:timestamp}\]?\"%{WORD:http_method}?%{NOTSPACE:request}?HTTP/%{NUMBER:httpversion}\"?%{NUMBER:status}?(?:%{NUMBER:bytes}|-)?\"(?:%{URI:http_referer}|-)\"?\"%{GREEDYDATA:User_Agent}\""]remove_field?=>?["message"]}date?{match?=>?[?"timestamp",?"dd/MMM/YYYY:HH:mm:ss?Z"?]}} }
下面是apache日志
192.168.10.97?-?-?[19/Jul/2016:16:28:52?+0800]?"GET?/?HTTP/1.1"?200?23?"-"?"Mozilla/5.0?(Windows?NT?6.1;?WOW64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/45.0.2454.101?Safari/537.36"日志中每個字段之間空格隔開,分別對應message中的字段。
如:%{IPORHOST:addre} ?--> 192.168.10.197 ?
但問題是IPORHOST又不是正則表達式,怎么能匹配IP地址呢?
因為IPPRHOST是grok表達式,它代表的正則表達式如下:
IPV6?((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)? IPV4?(?<![0-9])(?:(?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])[.](?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5]))(?![0-9]) IP?(?:%{IPV6}|%{IPV4}) HOSTNAME?\b(?:[0-9A-Za-z][0-9A-Za-z-]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-]{0,62}))*(\.?|\b) IPORHOST?(?:%{IP}|%{HOSTNAME})IPORHOST代表的是ipv4或者ipv6或者HOSTNAME所匹配的grok表達式。
上面的IPORHOST有點復雜,我們來看看簡單點的,如USER
USERNAME [a-zA-Z0-9._-]+ ? ??
#USERNAME是匹配由字母,數字,“.”, "_", "-"組成的任意字符
USER %{USERNAME}
#USER代表USERNAME的正則表達式
第一行,用普通的正則表達式來定義一個 grok 表達式;
第二行,通過打印賦值格式,用前面定義好的 grok 表達式來定義另一個 grok 表達式。
grok的語法:
%{syntax:semantic}
syntax代表的是正則表達式替代字段,semantic是代表這個表達式對應的字段名,你可以自由命名。這個命名盡量能簡單易懂的表達出這個字段代表的意思。
logstash安裝時就帶有已經寫好的正則表達式。路徑如下:
/usr/local/logstash-2.3.4/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-2.0.5/patterns
或者直接訪問https://github.com/elastic/logstash/blob/v1.4.2/patterns/grok-patterns
上面IPORHOST,USER等都是在里面已經定義好的!當然還有其他的,基本能滿足我們的需求
日志匹配
當我們拿到一段日志,按照上面的grok表達式一個個去匹配時,我們如何確定我們匹配的是否正確呢?
http://grokdebug.herokuapp.com/ 這個地址可以滿足我們的測試需求。就拿上面apache的日志測試。
點擊后就出現如下數據,你寫的每個grok表達式都獲取到值了。為了測試準確,可以多測試幾條日志。
{"addre":?[["192.168.10.97"]],"HOSTNAME":?[["192.168.10.97","192.168.10.175"] ...........中間省略多行..........."http_referer":?[["http://192.168.10.175/"]],"URIPROTO":?[["http"]],"URIHOST":?[["192.168.10.175"]],"IPORHOST":?[["192.168.10.175"]],"User_Agent":?[["Mozilla/5.0?(Windows?NT?6.1;?WOW64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/45.0.2454.101?Safari/537.36"]] }每條日志總有些字段是沒有數據顯示,然后以“-”代替的。所有我們在匹配日志的時候也要判斷。
如:(?:%{NUMBER:bytes}|-) ?
但是有些字符串是在太長,如:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
我們可以使用%{GREEDYDATA browser}. ? ? ? ??
對應的grok表達式: GREEDYDATA ?.* ??
#GREEDYDATA表達式的意思能匹配任意字符串
自定義grok表達式
如果你感覺logstash自帶的grok表達式不能滿足需要,你也可以自己定義
如:
filter?{if?[type]?==?"apache"?{grok?{patterns_dir?=>?"/usr/local/logstash-2.3.4/ownpatterns/patterns"match?=>?{"message"?=>?"%{APACHE_LOG}"}remove_field?=>?["message"]}date?{match?=>?[?"timestamp",?"dd/MMM/YYYY:HH:mm:ss?Z"?]}} }patterns_dir為自定義的grok表達式的路徑。
自定義的patterns中按照logstash自帶的格式書寫。
APACHE_LOG %{IPORHOST:addre} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] \"%{WORD:http_method} %{NOTSPACE:request} HTTP/%{NUMBER:httpversion}\" %{NUMBER:status} (?:%{NUMBER:bytes}|-) \"(?:%{URI:http_referer}|-)\" \"%{GREEDYDATA:User_Agent}\"
我只是把apache日志匹配的grok表達式寫入自定義文件中,簡化conf文件。單個字段的正則表達式匹配你可以自己書寫測試。
參考:https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html
轉載于:https://blog.51cto.com/irow10/1828077
總結
以上是生活随笔為你收集整理的日志分析logstash插件-grok详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 泛型入门
- 下一篇: (3)-JSONObject的过滤设置