2017-05-08 25 views
1

我用fluentd更換logstash的時候,我用in-tail插件尾nginx access日誌,訪問日誌的格式是這樣的:如何使用fluentd正則表達式滿足nginx的錯誤請求

log_format main '$remote_addr - $remote_user [$time_local] $request ' 
'"$status" $body_bytes_sent "$http_referer" ' 
'"$http_user_agent" "$http_x_forwarded_for" $request_time'; 

fluentd的conf就像

format /^(?<host>\S+)\s-\s(?<user>\S+)\s\[(?<time>[^\]]*)\]\s(?<method>\S+)\s(?<url>\S+)\s(?<http_version>\S+)\s"(?<status>[^\"]+)"\s(?<bytes>\d+)\s"(?<rfc>[^\"]+)"\s"(?<agent>[^\"]+)"\s"(?<x_forward>[^\"]+)"\s(?<time_spent>\S+).*$/ 

當請求是正確的,它工作正常,但是當請求是壞的,就像下面這滿足錯誤:

172.31.33.157 - - [08/May/2017:16:30:20 +0800] - "400" 0 "-" "-" "-" 0.000 

不良要求錯過了methodrfc字段,所以fluentd運行錯誤。我如何修改format以便我不關心請求是否不正確或不正確?

任何答案可以理解

運行到另一個場景中,提交的agentrfc是沒有的,它運行錯誤。就像

172.31.44.196 - - [08/May/2017:18:47:31 +0800] GET /click?mb_pl=ios&version=1.1 HTTP/1.1 "302" 5 "-" "" "100.38.38.149, 54.224.136.60" 0.004 

172.31.44.196 - - [08/May/2017:18:47:31 +0800] GET /click?mb_pl=ios&version=1.1 HTTP/1.1 "302" 5 "" "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E304" "100.38.38.149, 54.224.136.60" 0.004 

如何解決這種情況?

+0

正確的請求是什麼樣的? –

+0

172.31.44.196 - [08/May/2017:18:47:31 +0800] GET /click?mb_pl=ios&version=1.1 HTTP/1.1「302」5「 - 」「Mozilla/5.0(iPhone; CPU iPhone OS 10_3_1像Mac OS X)AppleWebKit/603.1.30(KHTML,如Gecko)Mobile/14E304「」100.38.38.149,54.224.136.60「0.004 –

回答

1

,你可以換的是可選的非捕獲組內是可選模式的部分,(?:...)?

^(?<host>\S+)\s-\s(?<user>\S+)\s\[(?<time>[^\]]*)\](?:\s(?<method>\S+))?(?:\s(?<url>\S+))?\s(?<http_version>\S+)\s"(?<status>[^\"]+)"\s(?<bytes>\d+)(?:\s"(?<rfc>[^\"]+)")?\s"(?<agent>[^\"]+)"\s"(?<x_forward>[^\"]+)"\s(?<time_spent>\S+).*$ 

regex demo

在這裏,我包了以下幾個部分:

(?:\s(?<method>\S+))? 
(?:\s(?<url>\S+))? 
(?:\s"(?<rfc>[^\"]+)")? 

這意味着,整個子模式序列將是optiona,一個空格和命名的捕獲組模式。

注意:當您有更多可選字段時,您可能會發現自己處於某種情況,即模式組開始匹配不需要的屬於其他組的輸入部分。在這種情況下,請確保限制通用模式並使用可選模式:將+替換爲*以匹配0個或多個匹配項,而不是1個或多個匹配項,並使用上面顯示的可選組,並確保只匹配字符/預期的模式。

參見下面的增強的圖案:

^(?<host>\S+)\s-\s(?<user>\S+)\s\[(?<time>[^\]]*)\](?:\s(?<method>\w+))?(?:\s(?<url>\/\S+))?\s(?<http_version>\S+)\s"(?<status>\d+)"\s(?<bytes>\d+)(?:\s"(?<rfc>[^\"]*)")?(?:\s"(?<agent>[^\"]*)")?\s"(?<x_forward>[^\"]*)"\s(?<time_spent>[\d.]+).*$ 

regex demo

一些興趣點這裏:

  • (?<method>\w+))? - 在這裏,我們只匹配單詞字符(\S>\w,你甚至可以考慮使用[A-Z]
  • (?:\s(?<url>\/\S+))? - 添加/,因爲你的URL與/
  • 啓動
  • (?<status>\d+) - \S更改爲\d(因爲狀態碼只包含數字)
  • (?<rfc>[^\"]*)")? - 所述+改變爲*(該值可以爲空)
  • (?:\s"(?<agent>[^\"]*)")? - 同樣在這裏,與rfc
  • \s"(?<x_forward>[^\"]*)" - 同上
  • (?<time_spent>[\d.]+ - 所述time_spent值僅包含數字和點。
+1

如果您有其他可選字段,請嘗試將'\ s' +'子模式'與可選的非捕獲組。 –