1. 程式人生 > >Logstash使用grok過濾nginx日誌(二)

Logstash使用grok過濾nginx日誌(二)

在生產環境中,nginx日誌格式往往使用的是自定義的格式,我們需要把logstash中的message結構化後再儲存,方便kibana的搜尋和統計,因此需要對message進行解析。

  本文采用grok過濾器,使用match正則表示式解析,根據自己的log_format定製。

1、nginx日誌格式

  log_format配置如下:

log_format  main  '$remote_addr - $remote_user [$time_local] $http_host $request_method "$uri" "$query_string" '
                  '
$status $body_bytes_sent "$http_referer" $upstream_status $upstream_addr $request_time $upstream_response_time ' '"$http_user_agent" "$http_x_forwarded_for"' ;

  對應的日誌如下:

1.1.1.1 - - [06/Jun/2016:00:00:01 +0800] www.test.com GET "/api/index" "?cms=0&rnd=1692442321" 200 4 "http://www.test.com/?cp=sfwefsc
" 200 192.168.0.122:80 0.004 0.004 "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" "-"

2、編寫正則表示式

  logstash中預設存在一部分正則讓我們來使用,可以訪問Grok Debugger來檢視,可以在 $logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-4.0.0/patterns/ 目錄裡面檢視。

  基本定義在grok-patterns中,我們可以使用其中的正則,當然並不是所有的都適合nginx欄位,這時就需要我們自定義正則,然後通過指定patterns_dir來呼叫。

  同時在寫正則的時候可以使用Grok Debugger或者Grok Comstructor工具來幫助我們更快的除錯。在不知道如何使用logstash中的正則的時候也可使用Grok Debugger的Descover來自動匹配。

  1)nginx標準日誌格式

    logstash自帶的grok正則中有Apache的標準日誌格式:

COMMONAPACHELOG %{IPORHOST:clientip} %{HTTPDUSER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)
COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %{QS:agent}

    對於nginx標準日誌格式,可以發現只是最後多了一個 $http_x_forwarded_for 變數。則nginx標準日誌的grok正則定義為:

MAINNGINXLOG %{COMBINEDAPACHELOG} %{QS:x_forwarded_for}

  2)自定義格式

    通過log_format來匹配對應的正則如下:

%{IPV4:remote_addr} - (%{USERNAME:user}|-) \[%{HTTPDATE:log_timestamp}\] (%{HOSTNAME1:http_host}|-) (%{WORD:request_method}|-) \"(%{URIPATH1:uri}|-|)\" \"(%{URIPARM1:param}|-)\" %{STATUS:http_status} (?:%{BASE10NUM:body_bytes_sent}|-) \"(?:%{GREEDYDATA:http_referrer}|-)\" (%{STATUS:upstream_status}|-) (?:%{HOSTPORT1:upstream_addr}|-) (%{BASE16FLOAT:upstream_response_time}|-) (%{STATUS:request_time}|-) \"(%{GREEDYDATA:user_agent}|-)\" \"(%{FORWORD:x_forword_for}|-)\"

    這裡面有幾個是我自定義的正則:

URIPARM1 [A-Za-z0-9$.+!*'|(){},[email protected]#%&/=:;^\\_<>`?\-\[\]]*
URIPATH1 (?:/[\\A-Za-z0-9$.+!*'(){},~:;[email protected]#% \[\]_<>^\-&?]*)+
HOSTNAME1 \b(?:[0-9A-Za-z_\-][0-9A-Za-z-_\-]{0,62})(?:\.(?:[0-9A-Za-z_\-][0-9A-Za-z-:\-_]{0,62}))*(\.?|\b)
STATUS ([0-9.]{0,3}[, ]{0,2})+
HOSTPORT1 (%{IPV4}:%{POSINT}[, ]{0,2})+
FORWORD (?:%{IPV4}[,]?[ ]?)+|%{WORD}

  message是每段讀進來的日誌,IPORHOST、USERNAME、HTTPDATE等都是patterns/grok-patterns中定義好的正則格式名稱,對照日誌進行編寫。

  grok pattren的語法為:%{SYNTAX:semantic},":" 前面是grok-pattrens中定義的變數,後面可以自定義變數的名稱。(?:%{SYNTAX:semantic}|-)這種形式是條件判斷。

  如果有雙引號""或者中括號[],需要加 \ 進行轉義。

  詳解自定義正則:

 URIPARAM \?[A-Za-z0-9$.+!*'|(){},[email protected]#%&/=:;_?\-\[\]<>]* 

 URIPARM1 [A-Za-z0-9$.+!*'|(){},[email protected]#%&/=:;^\\_<>`?\-\[\]]* grok-patterns中正則表示式,可以看到grok-patterns中是以“?”開始的引數,在nginx的 $query_string 中已經把“?”去掉了,所以我們這裡不再需要“?”。另外單獨加入日誌中出現的  ^ \ _ < > ` 特殊符號 

 URIPATH (?:/[A-Za-z0-9$.+!*'(){},~:;[email protected]#%&_\-]*)+ 

 URIPATH1 (?:/[\\A-Za-z0-9$.+!*'(){},~:;[email protected]#% \[\]_<>^\-&?]*)+ grok-patterns中正則表示式,grok-patterns中的URIPATH不能匹配帶空格的URI,於是在中間加一個空格。另外還有 \ [ ] < > ^ 特殊符號。

 HOSTNAME \b(?:[0-9A-Za-z][0-9A-Za-z-]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-]{0,62}))*(\.?|\b) 

 HOSTNAME1 \b(?:[0-9A-Za-z_\-][0-9A-Za-z-_\-]{0,62})(?:\.(?:[0-9A-Za-z_\-][0-9A-Za-z-:\-_]{0,62}))*(\.?|\b) 新增匹配 http_host 中帶有 "-" 的字元。

 HOSTPORT %{IPORHOST}:%{POSINT} 

 HOSTPORT1 (%{IPV4}:%{POSINT}[, ]{0,2})+ 在匹配 upstream_addr 欄位時發現,會出現多個IP地址的情況出現,匹配多個IP地址。

 STATUS ([0-9.]{0,3}[, ]{0,2})+ 該欄位是當出現多個 upstream_addr 欄位時匹配多個 http_status 。

 FORWORD (?:%{IPV4}[,]?[ ]?)+|%{WORD} 當 x_forword_for 欄位出現多個IP地址時匹配。

  nginx左右欄位都定義完成,可以使用Grok Debugger或者Grok Comstructor工具來測試。新增自定義正則的時候,在Grok Debugger中可以勾選“Add custom patterns”。

  以上日誌匹配結果為:

複製程式碼
{
  "remote_addr": [
    "1.1.1.1"
  ],
  "user": [
    "-"
  ],
  "log_timestamp": [
    "06/Jun/2016:00:00:01 +0800"
  ],
  "http_host": [
    "www.test.com"
  ],
  "request_method": [
    "GET"
  ],
  "uri": [
    "/api/index"
  ],
  "param": [
    "?cms=0&rnd=1692442321"
  ],
  "http_status": [
    "200"
  ],
  "body_bytes_sent": [
    "4"
  ],
  "http_referrer": [
    "http://www.test.com/?cp=sfwefsc"
  ],
  "port": [
    null
  ],
  "upstream_status": [
    "200"
  ],
  "upstream_addr": [
    "192.168.0.122:80"
  ],
  "upstream_response_time": [
    "0.004"
  ],
  "request_time": [
    "0.004"
  ],
  "user_agent": [
    ""Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36""
  ],
  "client_ip": [
    "2.2.2.2"
  ],
  "x_forword_for": [
    null
  ]
}
複製程式碼

3、logstash的配置檔案

  建立自定義正則目錄

# mkdir -p /usr/local/logstash/patterns
# vi /usr/local/logstash/patterns/nginx

  然後寫入上面自定義的正則

複製程式碼
URIPARM1 [A-Za-z0-9$.+!*'|(){},[email protected]#%&/=:;_?\-\[\]]*
URIPATH1 (?:/[A-Za-z0-9$.+!*'(){},~:;[email protected]#%&_\- ]*)+
URI1 (%{URIPROTO}://)?(?:%{USER}(?::[^@]*)[email protected])?(?:%{URIHOST})?(?:%{URIPATHPARAM})?
NGINXACCESS %{IPORHOST:remote_addr} - (%{USERNAME:user}|-) \[%{HTTPDATE:log_timestamp}\] %{HOSTNAME:http_host} %{WORD:request_method} \"%{URIPATH1:uri}\" \"%{URIPARM1:param}\" %{BASE10NUM:http_status} (?:%{BASE10NUM:body_bytes_sent}|-) \"(?:%{URI1:http_referrer}|-)\" (%{BASE10NUM:upstream_status}|-) (?:%{HOSTPORT:upstream_addr}|-) (%{BASE16FLOAT:upstream_response_time}|-) (%{BASE16FLOAT:request_time}|-) (?:%{QUOTEDSTRING:user_agent}|-) \"(%{IPV4:client_ip}|-)\" \"(%{WORD:x_forword_for}|-)\"
複製程式碼

  logstash.conf配置檔案內容

複製程式碼
input {
        file {
                path => "/data/nginx/logs/access.log"
                type => "nginx-access"
                start_position => "beginning"
                sincedb_path => "/usr/local/logstash/sincedb"
        }
}
filter {
        if [type] == "nginx-access" {
                grok {
                        patterns_dir => "/usr/local/logstash/patterns"        //設定自定義正則路徑
                        match => {
                                "message" => "%{NGINXACCESS}"
                        }
                }
                date {
                        match => [ "log_timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ]
                }
         urldecode {
                 all_fields => true
           }
         //把所有欄位進行urldecode(顯示中文)
        }
}
output {
        if [type] == "nginx-access" {
                elasticsearch {
                        hosts => ["10.10.10.26:9200"]
                        manage_template => true
                        index => "logstash-nginx-access-%{+YYYY-MM}"
                }
        }

}
複製程式碼

 4、啟動logstash,然後就可以檢視日誌是否寫入elasticsearch中。

相關推薦

Logstash使用grok過濾nginx日誌

在生產環境中,nginx日誌格式往往使用的是自定義的格式,我們需要把logstash中的message結構化後再儲存,方便kibana的搜尋和統計,因此需要對message進行解析。   本文采用grok過濾器,使用match正則表示式解析,根據自己的log_forma

JavaScript學習日誌:面向對象的程序設計

循環 理想 soft 日誌 傳遞 數組 用例 定義 基本類型 1,ECMAScript不像其他面向對象的語言那樣有類的概念,它的對象與其他不同。 2,ECMAScript有兩種屬性:數據屬性和訪問器屬性。([[]]這種雙中括號表示屬性為內部屬性,外部不可直接訪問) 1.數據

nginx+lua 請求分發

product include new fault 腳本 back () file res 比如對產品productId=143這個請求分發 現編寫lua腳本 distrib_product.lua local uri_args = ngx.req.get_uri_ar

YaolingJump開發者日誌

雷神 net 矛盾 lin dog body style cnblogs 在一起 ??熟悉了一點LGame裏的套路,可以正式開工了。 ??增加了一個信息欄,顯示得分、硬幣數、生命值和當前關卡(仿照了超級瑪麗的布局)。 ??準備瑤玲的各種動畫(靜止、奔跑、跳躍、趴下、休息和死

thinking in C++ 讀書日誌

  2007-08-01 第二章物件的建立與使用 第二章主要講述c++的一些基礎知識和基本語法,不過我們仍能從書中學到新的東西。這次儘量減小文章的篇幅。主要分兩方面寫:1.推薦知識點,從廣度上覆蓋本章精華;2.對特定某個知識點的進一步研究, 從深度上進行探索。  

3dContactPointAnnotationTool開發日誌

  今天看的時候發現其實www的方式是可以根據指定路徑讀取本地圖片到Image中的。也就是昨天提到的第二種方式。   隨便選了個圖片做示範: 修改後的程式碼如下: using System.Collections; using System.Collections.Generic; using Unit

高效能Nginx介紹

14.4 nginx內部 如前所述,nginx程式碼庫由核心和許多模組組成。 nginx的核心是負責提供Web伺服器,Web和郵件反向代理功能的基礎;它支援使用底層網路協議,構建必要的執行時環境,並確保不同模組之間的無縫互動。但是,大多數協議和應用程式特定的功能都是由nginx模組完成的,而不是

elk+filebeat的安裝 並 分析nginx日誌推薦

關於elk及其相關元件的介紹,參看此文https://boke.wsfnk.com/archives/67.html系統規劃 服務型別 OS版本 IP地址 主機名 elk端 centos7.4 192.168.1.26 elk-server log端 centos7.4 192.168.1.40 b

CoreJava讀書筆記--異常、斷言和日誌--斷言和日誌

使用斷言 在一個具有自我保護能力的程式中,斷言很常用。 (一)斷言的概念 斷言機制允許在測試期間向程式碼中插入一些檢查語句。當代碼釋出時,這些插入的檢測語句將會被自動地移走。Java語言引入了關鍵字assert。assert有兩種形式: assert 條件; 和

微信小程式踩坑日誌

indexOf 在wxml檔案中不能使用 Object.keys() toString() indexOf() ; 其中indexOf()方法在wxml中怎麼樣都返回undefined; textarea textarea在小程式中算是一個比較大的坑了;

小程式踩坑日誌--modal的使用

小程式踩坑日誌(二) 小程式彈出框modal的使用 modal彈出框經常用在提示一些資訊,比如退出應用,清除快取,修改資料。 常用屬性 屬性名 預設值 說明

asp.net core mcroservices 架構之 分散式日誌之自定義日誌開發

一   netcore日誌原理                                    &nbs

使用MONO在MAC OS上開發——同步日誌

上一篇使用MONO在MAC OS上開發——同步日誌(一)講述了在MAC OS讀取配置檔案以及寫日誌,那麼只算是完成了基本的配置,下面的才是重點。 由於時間關係,就簡單描述下,並不具體分析原始碼。最後奉上原始碼。 一:安裝 第一步,安裝MONO框架。你可以在MONO官網去下載。注意“MonoFramewo

阿里雲伺服器搭建 踩坑日誌配置https

嘗試配置https,解決有的瀏覽器提示不安全。 1、獲取免費的ssl證書 有很多文件是自己生成證書的,但是這個證書在很多地方還是報錯, 如果你有自己的域名,在阿里雲上是可以獲取免費的證書的。 證書獲取地址,https://common-buy.aliyun.com/?spm=5

logstash通過kafka傳輸nginx日誌

單個程序 logstash 可以實現對資料的讀取、解析和輸出處理。但是在生產環境中,從每臺應用伺服器執行 logstash 程序並將資料直接傳送到 Elasticsearch 裡,顯然不是第一選擇:第一,過多的客戶端連線對 Elasticsearch 是一種額外的壓力;第

Spring Boot學習日誌JPA操作Mysql

Spring Boot學習日誌(二)JPA基本操作 什麼是JPA Jpa簡單說就是一個ORM持久層框架,可以讓開發人員一行sql不寫,實現基本的增刪改查操作。 匯入依賴庫 在新建專案時,勾選Web,JPA和Mysql(因為我使用的Mysql測試,

NginxNginx安裝

首先從官網上http://nginx.org/下載最新的stable version原始碼,當前最新版本為nginx-1.10.2.tar.gz。2.1 configure解壓之後,會發現裡面有一個名為“configure”的檔案:configure本身是一個Shell指令碼,中間會呼叫<nginx-

nginx配置

#虛擬主機的配置 server { #監聽埠 listen 80; #域名可以有多個,用空格隔開 server_name www.ha97.com ha97.com; index index.html index.htm index.php; root /data/www/ha97; l

Java開發程式碼規範之異常日誌——日誌規約

文章通過學習《阿里巴巴Java開發手冊》整理 1。應用中不可直接使用日誌系統(Log4j、Logback)中的API,而應依賴使用日誌框架SLF4J中的API,使用門面模式的日誌框架,有利於維護和各個類的日誌處理方式統一。 import org.

python log日誌

上一篇文章已經介紹log簡單使用方法,本文介紹下另一種用法,可以列印日誌,同時記錄日誌檔案,可以控制日誌顏色import inspect import logging import logging.handlers import os from colorama imp