1. 程式人生 > 其它 >使用filebeat解析nginx的json格式日誌,並且儲存原始message欄位的值,輸出到es中並通過grafana圖形化顯示

使用filebeat解析nginx的json格式日誌,並且儲存原始message欄位的值,輸出到es中並通過grafana圖形化顯示

1.nginx日誌調成json樣式

log_format json '{"@timestamp":"$time_iso8601",'
                '"server_addr":"$server_addr",'
                '"server_name":"$server_name",'
                '"server_port":"$server_port",'
                '"server_protocol":"$server_protocol",'
                '"client_ip":"$remote_addr",'
                '"client_user":"$remote_user",'
                '"status":"$status",'
                '"request_method": "$request_method",'
                '"request_length":"$request_length",'
                '"request_time":"$request_time",'
                '"request_url":"$request_uri",'
                '"request_line":"$request",'
                '"send_client_size":"$bytes_sent",'
                '"send_client_body_size":"$body_bytes_sent",'
                '"proxy_protocol_addr":"$proxy_protocol_addr",'
                '"proxy_add_x_forward":"$proxy_add_x_forwarded_for",'
                '"proxy_port":"$proxy_port",'
                '"proxy_host":"$proxy_host",'
                '"upstream_host":"$upstream_addr",'
                '"upstream_status":"$upstream_status",'
                '"upstream_cache_status":"$upstream_cache_status",'
                '"upstream_connect_time":"$upstream_connect_time",'
                '"upstream_response_time":"$upstream_response_time",'
                '"upstream_header_time":"$upstream_header_time",'
                '"upstream_cookie_name":"$upstream_cookie_name",'
                '"upstream_response_length":"$upstream_response_length",'
                '"upstream_bytes_received":"$upstream_bytes_received",'
                '"upstream_bytes_sent":"$upstream_bytes_sent",'
                '"http_host":"$host",'
                '"http_cookie":"$http_cooke",'
                '"http_user_agent":"$http_user_agent",'
                '"http_origin":"$http_origin",'
                '"http_upgrade":"$http_upgrade",'
                '"http_referer":"$http_referer",'
                '"http_x_forward":"$http_x_forwarded_for",'
                '"http_x_forwarded_proto":"$http_x_forwarded_proto",'
                '"https":"$https",'
                '"http_scheme":"$scheme",'
                '"invalid_referer":"$invalid_referer",'
                '"gzip_ratio":"$gzip_ratio",'
                '"realpath_root":"$realpath_root",'
                '"document_root":"$document_root",'
                '"is_args":"$is_args",'
                '"args":"$args",'
                '"connection_requests":"$connection_requests",'
                '"connection_number":"$connection",'
                '"ssl_protocol":"$ssl_protocol",'
                '"ssl_cipher":"$ssl_cipher"}';

凡是需要使用nginx日誌的均採用如下寫法:

# 事前建立儲存nginx日誌的資料夾
# mkdir -p /var/log/nginx/

access_log /var/log/nginx/test.access.log json;

2.使用filebeat收集nginx的日誌

注意:這裡不採用自帶的模組形式,也就是不開啟nginx的module收集功能

注意:方式1和方式2的其他配置都相同,這裡只列出不同的地方,後面會具體分析這倆不同的配置有啥不同的效果

設定方式1

- type: log
  enabled: true
  paths:
    - /var/log/nginx/test.access.log
  fields:
    log_source: nginx
    log_type: www
  fields_under_root: true
  tags: ["nginx"]
  json:
    keys_under_root: true
    overwrite_keys: true
    message_key: "message"
    add_error_key: true

使用方式1的設定後,nginx的日誌就會輸出到es中,且日誌中的每個鍵值對就是頂級欄位,如下圖所示

但是有一個問題,原有message欄位的值是空的,導致在kibana日誌導航中無法顯示ngixn的日誌(具體是access日誌,error日誌因為還是原來的設定仍會顯示).

這種設定在grafana中會正常顯示資料出來的。

設定方式2

- type: log
  enabled: true
  paths:
    - /var/log/nginx/test.access.log
  fields:
    log_source: nginx
    log_type: www
  fields_under_root: true
  tags: ["nginx"]

processors:
  - add_host_metadata:
      when.not.contains.tags: forwarded
  - decode_json_fields:
      fields: ['message']
      target: "" 
      overwrite_keys: false 
      process_array: false 
      max_depth: 1

使用方式2的設定後,nginx的日誌就會輸出到es中,且日誌中的每個鍵值對就是頂級欄位,並且原有message欄位的值仍存在,在kibana日誌導航中還可以繼續顯示ngixn的日誌(具體是access日誌,error日誌因為還是原來的設定仍會顯示).

這種設定在grafana中會正常顯示資料出來的。

綜合方式1和方式2,方式2的方式是符合需求的,既能繼續查詢日誌,還能把日誌資訊圖形化顯示出來(不使用自帶的nginx module收集方式)

3.es中設定索引模式

filebeat-*

4.grafana中新增dashboard

開啟 Grafana 頁面,登入後,在 Data Sources 新增型別為 Elasticsearch 的資料來源
在 HTTP 段,把 es 機器的IP地址和埠填寫到 URL 輸入框中,比如: http://localhost:9200,訪問有密碼的話需要加上密碼
在 Elasticsearch details 段
把上面 filebeat 配置的nginx索引名稱填寫到 Index name 輸入框中,比如: filebeat-*
Version 選擇 7.0+
儲存測試

匯入Dashboard,ID: 14913

6.上述方式1和方式2的欄位含義

方式1
json 這些選項使得Filebeat將日誌作為JSON訊息來解析。例如:

json.keys_under_root: true
json.add_error_key: true
json.message_key: log
為了啟用JSON解析模式,你必須至少指定下列設定項中的一個:
keys_under_root: 預設情況下,解碼後的JSON被放置在一個以"json"為key的輸出文件中。如果你啟用這個設定,那麼這個key在文件中被複製為頂級。預設是false。
overwrite_keys: 如果keys_under_root被啟用,那麼在key衝突的情況下,解碼後的JSON物件將覆蓋Filebeat正常的欄位
add_error_key: 如果啟用,則當JSON反編排出現錯誤的時候Filebeat新增 "error.message" 和 "error.type: json"兩個key,或者當沒有使用message_key的時候。
message_key: 一個可選的配置,用於在應用行過濾和多行設定的時候指定一個JSON key。指定的這個key必須在JSON物件中是頂級的,而且其關聯的值必須是一個字串,否則沒有過濾或者多行聚集傳送。
ignore_decoding_error: 一個可選的配置,用於指定是否JSON解碼錯誤應該被記錄到日誌中。如果設為true,錯誤將被記錄。預設是false。

方式2

用filebeat想對收集到的日誌進行這樣的解析:如果為json的話,就將json物件中的每個子欄位解析成頂級結構下的一個欄位,但是發現,解析後,儲存日誌完整內容的message欄位(也即完整的json串)消失了,最終找到如下解決方法:
用processors中的decode_json_fields處理器進行處理,它類似logstash中的filter,具體格式如下:

processors:
  - add_host_metadata:
      when.not.contains.tags: forwarded
  - decode_json_fields:
      fields: ['message'] #要進行解析的欄位
      target: ""  #json內容解析到指定的欄位,如果為空(""),則解析到頂級結構下
      overwrite_keys: false #如果解析出的json結構中某個欄位在原始的event(在filebeat中傳輸的一條資料為一個event)中也存在,是否覆蓋event中該欄位的值,預設值:false
      process_array: false  #陣列是否解碼,預設值:false
      max_depth: 1 #解碼深度,預設值:1