如何使用 logstash 將日誌處理成 JSON 格式(nginx)

命令行參數
Logstash 提供了一個 shell 腳本叫 logstash 方便快速運行。它支持一下參數:

-e
意即執行。我們在 “Hello World” 的時候已經用過這個參數了。事實上你可以不寫任何具體配置,直接運行 bin/logstash -e ‘’ 達到相同效果。這個參數的默認值是下面這樣:

input {
    stdin { }
}
output {
    stdout { }
}

–config 或 -f
意即文件。真實運用中,我們會寫很長的配置,甚至可能超過 shell 所能支持的 1024 個字符長度。所以我們必把配置固化到文件裏,然後通過 bin/logstash -f agent.conf 這樣的形式來運行。

此外,logstash 還提供一個方便我們規劃和書寫配置的小功能。你可以直接用 bin/logstash -f /etc/logstash.d/ 來運行。logstash 會自動讀取 /etc/logstash.d/ 目錄下所有的文本文件,然後在自己內存裏拼接成一個完整的大配置文件,再去執行。

–configtest 或 -t
意即測試。用來測試 Logstash 讀取到的配置文件語法是否能正常解析。Logstash 配置語法是用 grammar.treetop 定義的。尤其是使用了上一條提到的讀取目錄方式的讀者,尤其要提前測試。

–log 或 -l
意即日誌。Logstash 默認輸出日誌到標準錯誤。生產環境下你可以通過 bin/logstash -l logs/logstash.log 命令來統一存儲日誌。

–filterworkers 或 -w
意即工作線程。Logstash 會運行多個線程。你可以用 bin/logstash -w 5 這樣的方式強制 Logstash 爲過濾插件運行 5 個線程。

注意:Logstash目前還不支持輸入插件的多線程。而輸出插件的多線程需要在配置內部設置,這個命令行參數只是用來設置過濾插件的!

提示:Logstash 目前不支持對過濾器線程的監測管理。如果 filterworker 掛掉,Logstash 會處於一個無 filter 的僵死狀態。這種情況在使用 filter/ruby 自己寫代碼時非常需要注意,很容易碰上 NoMethodError: undefined method ‘*’ for nil:NilClass 錯誤。需要妥善處理,提前判斷。

–pluginpath 或 -P
可以寫自己的插件,然後用 bin/logstash --pluginpath /path/to/own/plugins 加載它們。

–verbose
輸出一定的調試日誌。

小貼士:如果你使用的 Logstash 版本低於 1.3.0,你只能用 bin/logstash -v 來代替。

–debug
輸出更多的調試日誌。

小貼士:如果你使用的 Logstash 版本低於 1.3.0,你只能用 bin/logstash -vv 來代替。

1.修改nginx.conf文件

在http字段內添加如下內容
        log_format json '{"@timestamp":"$time_iso8601",'	#用來標記事件的發生時間
               '"@version":"1",'	
               '"host":"$server_addr",'
               '"client":"$remote_addr",'
               '"size":$body_bytes_sent,'
               '"responsetime":$request_time,'
               '"domain":"$host",'
               '"url":"$uri",'
               '"status":"$status"}';
        access_log /var/log/nginx/access.log_json json;

注意:$body_bytes_sent和$request_time 變量兩頭沒有雙引號 ",這兩個數據在 JSON 裏應該是數值類型

2.修改logstash文件

創建修改logstash-nginx.conf文件
添加如下內容:
input {
    file {
        path => "/var/log/nginx/access.log_json"
        codec => "json"
    }
}
output {
    stdout {
        codec => json
    }
}

運行測試:

sudo /usr/share/logstash/bin/logstash -f /etc/logstash/logstash-nginx.conf
瀏覽器訪問nginx,logstash會輸出內容
{"responsetime":0.0,"url":"/index.html","status":"304","path":"/var/log/nginx/access.log_json","client":"xxx.xxx.xxx.xxx","@version":"1","size":0,"domain":"xxx.xxx.xxx.xxx","@timestamp":"2020-04-15T03:42:12.000Z","host":"xxx.xxx.xxx.xxx"}

對於一個 web 服務器的訪問日誌,已經可以很好的工作了。不過如果 Nginx 是作爲一個代理服務器運行的話,訪問日誌裏有些變量,比如說 $upstream_response_time,可能不會一直是數字,它也可能是一個 “-” 字符串!這會直接導致 logstash 對輸入數據驗證報異常。
有兩個辦法解決這個問題:

用 sed 在輸入之前先替換 - 成 0。
運行 logstash 進程時不再讀取文件而是標準輸入,這樣命令就成了下面這個樣子:

tail -F /var/log/nginx/proxy_access.log_json
| sed ‘s/upstreamtime":-/upstreamtime":0/’
| /usr/local/logstash/bin/logstash -f /usr/local/logstash/etc/proxylog.conf

日誌格式中統一記錄爲字符串格式(即都帶上雙引號 "),然後再在 logstash 中用 filter/mutate 插件來變更應該是數值類型的字符字段的值類型。
幫助文檔:https://doc.yonyoucloud.com/doc/logstash-best-practice-cn/codec/json.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章