2017-02-16 488 views
1

我有一種ELK堆棧,使用fluentd而不是logstash,作爲Kubernetes集羣上的DaemonSet運行,並將所有容器中的所有日誌以logstash格式發送到Elasticsearch服務器。Kibana - 如何從現有的Kubernetes日誌中提取字段

走出Kubernetes集羣上運行的許多容器的一些是nginx的容器中以下列格式的輸出日誌:在Kibana

121.29.251.188 - [16/Feb/2017:09:31:35 +0000] host="subdomain.site.com" req="GET /data/schedule/update?date=2017-03-01&type=monthly&blocked=0 HTTP/1.1" status=200 body_bytes=4433 referer="https://subdomain.site.com/schedule/2589959/edit?location=23092&return=monthly" user_agent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0" time=0.130 hostname=webapp-3188232752-ly36o 

字段可見是按照此屏幕截圖:

kibana nginx log

是否有可能從這種類型的日誌中提取字段後,它被編入索引?

的fluentd集電極被配置爲與下面的源,它處理所有的容器,所以強制執行該階段的格式是不可能的,因爲從不同的容器中的非常不同的輸出:

<source> 
    type tail 
    path /var/log/containers/*.log 
    pos_file /var/log/es-containers.log.pos 
    time_format %Y-%m-%dT%H:%M:%S.%NZ 
    tag kubernetes.* 
    format json 
    read_from_head true 
</source> 

在理想情況下,我想用「主」,「請求」,「狀態」等元數據字段在上面的屏幕截圖中豐富可見的字段。

回答

0

在經過幾天的研究並習慣於EFK stack之後,我到達了EFK特定的解決方案,與Darth_Vader的答案相反,這隻能在ELK堆棧中實現。

所以總結一下,我使用Fluentd代替Logstash,因此,如果您還安裝Fluentd Grok Plugin,我決定不這樣做,因爲任何神交的解決方案將工作:

事實證明,Fluentd有其通過使用parser filters自己的字段提取功能。爲了解決這個問題,我的問題,<match **>前行吧,等以後日誌行對象是已經與kubernetes元數據字段和標籤充實,我增加了以下內容:

<filter kubernetes.var.log.containers.webapp-**.log> 
    type parser 
    key_name log 
    reserve_data yes 
    format /^(?<ip>[^-]*) - \[(?<datetime>[^\]]*)\] host="(?<hostname>[^"]*)" req="(?<method>[^ ]*) (?<uri>[^ ]*) (?<http_version>[^"]*)" status=(?<status_code>[^ ]*) body_bytes=(?<body_bytes>[^ ]*) referer="(?<referer>[^"]*)" user_agent="(?<user_agent>[^"]*)" time=(?<req_time>[^ ]*)/ 
</filter> 

爲了解釋:

<filter kubernetes.var.log.containers.webapp-**.log> - 在與此標籤匹配的所有行上應用該塊;在我的情況下,網絡服務器組件的容器稱爲webapp- {}東西

type parser - 告訴fluentd申請解析器過濾器

key_name log - 僅在日誌行的log財產應用模式,不整條生產線,這是一個JSON字符串

reserve_data yes - 非常重要的,如果沒有指定整個日誌行對象只從format提取屬性所取代,因此,如果您已經有其他屬性,如那些由加kubernetes_metadata過濾器,當不添加時會刪除這些過濾器個選項

format - 這是在log鍵的值加一個正則表達式來提取命名屬性

請注意,我使用Fluentd 1.12,所以這個語法是不符合新的1.14完全兼容語法,但該原則將適用於解析器聲明的微小調整。

0

爲了提取日誌行到字段中,則可能必須使用grok過濾器。你可以做的是有一個正則表達式模式,以匹配你需要的日誌行的確切部分。 神交過濾器可以是這個樣子:

grok { 
    patterns_dir => ["pathto/patterns"] 
    match => { "message" => "^%{LOGTIMESTAMP:logtimestamp}%{GREEDYDATA:data}" }   
}             ^-----------------------^ are the fields you would see in ES when log is being indexed 

--------------------------------- -------------------^LOGTIMESTAMP應該在你的模式文件中定義是這樣的:

LOGTIMESTAMP %{YEAR}%{MONTHNUM}%{MONTHDAY} %{TIME} 

一旦你擁有了匹配字段,那麼你可以簡單地使用他們爲filtering的目的,或者你仍然可以保持原樣,如果主要導致它從日誌行提取字段。

if "something" in [message]{ 
    mutate { 
     add_field => { "new_field" => %{logtimestamp} } 
    }   
} 

以上只是一個示例,以便您可以重現它以滿足您的需求。你可以使用this工具,以測試你的模式以及你想要匹配的字符串!

Blog post,可能會得心應手!希望這可以幫助。

+0

感謝您的回答,@ Darth_vader。我知道這可以用logstash來完成,但我使用fluentd進行日誌收集,請參閱我的問題中的配置。你知道這可以通過開箱即可完成嗎? – bedeabza

相關問題