1. 程式人生 > >(ELK/EFK)之Fluentd日誌過濾解析與客戶端IP地址地理位置處理

(ELK/EFK)之Fluentd日誌過濾解析與客戶端IP地址地理位置處理

1 背景與說明

日誌收集我們主要採用 ELK/EFK 方案,具體為什麼採用這種方案本篇不進行更多闡述;本篇主要針對把業務日誌進行解析並相關處理後推送到 Elasticsearch 中更方便進行檢索與資料統計檢視,本篇日誌推送源來自於 DockerFluentd Log Driver,非 Docker 環境操作的僅作為參考。

2 目的效果圖

image

3 主要三樣外掛

3.1 內建 Parser 外掛

這個外掛在最新的 Fluentd 中已經內建了,直接使用即可。參考地址

3.2 Elasticsearch 外掛

Fluentd 收集到的日誌資訊推到 ES 進行儲存,

參考地址

3.3 地理位置外掛

根據客戶端 IP 地址獲取到更多地理相關的資訊,這樣可以在 kibana 上使用地圖與位置的統計圖方式更直觀檢視資訊,參考地址

4 開始

4.1 解析日誌資料到對應屬性

4.1.1 日誌原始資料

以下是 Docker 的輸出標準日誌資料格式內容。

2017-03-03T10:46:21+08:00   1806d6c91569    {"log":"2017-03-03 10:46:21 HKT  INFO AccessInterceptor:80 - {time=1488509181152, method=POST, action=/nakedhub/adminx/auth/welcome, locale=zh_CN, cost=4, userId=185713, user-agent=null, header-security-token=null, clientIp=139.196.12.22, clientType=null, params={password=111111, username=maomao}, status=200, paramsOfJson=null}"
,"container_id":"1806d6c91569612cdd746651eeb808591e0176befe565820a339294fc2a9ea0d","container_name":"/nhbackend-st.1.d7r1qsa35zwfxtsmyh5np61ft","source":"stdout"}

4.1.2 核心解析格式配置

<filter **>
    @type parser
    time_format %Y-%m-%d %H:%M:%S %Z
    key_name log
    suppress_parse_error_log true
    reserve_data true
    format
/.*(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} \w+?).+AccessInterceptor(.+time=(?<requesttime>.+?),)(.+method=(?<method>.+?),)(.+action=(?<action>.+?),)(.*locale=(?<locale>.+?),)(.+cost=(?<cost>.+?),)(.*userId=(?<userId>.*?),)(.*agent=(?<user-agent>.*?),)(.+token=(?<token>.*?),)(.+clientIp=(?<clientIp>.+?),)(.+clientType=(?<clientType>.+?),)(.*params={(?<params>.*?)})(.+status=(?<status>.*?),)(.*Json=(?<paramsOfJson>.*?)})/ types cost:integer,status:integer </filter>

這裡我採用 Fluentd 中的 filter 對資料進行過濾處理,主要的格式化配置都在 format 這段配置中,主要採用正則表示式拆分資料到自定義的以 <> 包圍起來的屬性中,測試表達式格式可以點開線上格式解析表示式,測試完畢後再把表示式配置就好了;另外值得注意的是 time 這個屬性值,這個值解析器會自動識別為時間型別,會按照 time_format 配置定義的格式轉換至時間型別;key_name 配置在官方文件中並沒有提及(但這個配置是必須的),我得出來的結論是這個配置會把外層 JSONlog 內容拿出來後再去做解析;types 則是把自定義的屬性進行型別指定,推送到 Elasticsearch 中也是相應型別(否則通過 kibana 做統計計算的時候由於不是 Number 型別會有問題);reserve_data 配置則表示原始 log 的內容是否保留到輸出項中。

4.1.3 最後日誌輸出項

2017-03-03T10:46:21+08:00   1806d6c91569    {"log":"2017-03-03 10:46:21 HKT  INFO AccessInterceptor:80 - {time=1488509181152, method=POST, action=/nakedhub/adminx/auth/welcome, locale=zh_CN, cost=4, userId=185713, user-agent=null, header-security-token=null, clientIp=139.196.12.22, clientType=null, params={password=111111, username=maomao}, status=200, paramsOfJson=null}","container_id":"1806d6c91569612cdd746651eeb808591e0176befe565820a339294fc2a9ea0d","container_name":"/nhbackend-st.1.d7r1qsa35zwfxtsmyh5np61ft","source":"stdout","requesttime":"1488509181152","method":"POST","action":"/nakedhub/adminx/auth/welcome","locale":"zh_CN","cost":4,"userId":"185713","user-agent":"null","token":"null","clientIp":"139.196.12.22","clientType":"null","params":"password=111111, username=maomao","status":200,"paramsOfJson":"null"}

4.2 推送到 ElasticSearch 核心配置

<match>
      @type elasticsearch
      host 10.47.121.12
      port 9200
      user elastic
      password 123456
      scheme http
      index_name fluentd
      type_name fluentd
      logstash_format true
      logstash_prefix docker
      reload_connections false
</match>

由於我的 ES 安裝了 XPACK 所以我使用了賬號與密碼項配置內容,另外注意 password 這裡不用使用特殊字元,否則會出現 Fluentd 連線 ElasticSearch 的時候字元編碼不對導致認為賬戶與密碼不對的錯誤問題。

4.3 客戶端 IP 地理位置處理

4.3.1 注意

這個 filter 的配置項必須要在以上日誌解析的配置項下面,要先解析到了 clientIp 屬性,我們才能方便配置從而讓外掛獲取客戶端IP地址處理地理位置屬性。

4.3.2 核心配置

<filter **>
    type geoip
    geoip_lookup_key clientIp
    geoip_database /home/fluent/GeoLiteCity.dat
    <record>
      latitude        ${latitude["clientIp"]}
      longitude       ${longitude["clientIp"]}
      country_code3   ${country_code3["clientIp"]}
      country         ${country_code["clientIp"]}
      country_name    ${country_name["clientIp"]}
      dma             ${dma_code["clientIp"]}
      area            ${area_code["clientIp"]}
      region          ${region["clientIp"]}
      city            ${city["clientIp"]}
      location        '[${longitude["clientIp"]},${latitude["clientIp"]}]'
    </record>
    skip_adding_null_record  true
    log_level         info
    flush_interval    1s
</filter>

GeoLiteCity.dat 參考GITHUB專案地址去下載,location 會自動轉換為 geo_point 型別。

4.3.3 Kibana 型別 geo_point 問題

No Compatible Fields: The "xxx" index pattern does not contain any of the following field types: geo_point

location 屬性值已經存在ES中了就算配置後依然無法自動轉成 geo_point 型別,我們需要手動進行處理了,先刪除相關的所以索引,然後手動建立型別模板定義 location 的型別,然後建立測試索引檢視。

4.3.3.1 建立模板型別

開啟 Shell 控制檯建立檔案 json ,檔案內容為以下。

{
  "template": "docker-*",
  "mappings": {
    "_default_": {
      "properties" : {
        "location": { "type": "geo_point"}
      }
    }
  }
}
curl -u elastic:123456 -XPUT 'http://10.47.121.12:9200/_template/docker' -d @json

4.3.3.2 建立測試索引

curl -u elastic:123456 -XPUT 'http://10.47.121.12:9200/docker-test/fluentd/2' -d '{"host":"8.8.8.8","location":[1.23,4.56]}'

4.3.3.3 檢視索引屬性型別

curl -u elastic:123456 -XGET http://10.47.121.12:9200/docker-test/fluentd/_mapping?pretty

4.3.3.4 原始問題參考地址

4.3.4 最後日誌輸出內容

2017-03-03T10:46:21+08:00   1806d6c91569    {"log":"2017-03-03 10:46:21 HKT  INFO AccessInterceptor:80 - {time=1488509181152, method=POST, action=/nakedhub/adminx/auth/welcome, locale=zh_CN, cost=4, userId=185713, user-agent=null, header-security-token=null, clientIp=139.196.12.22, clientType=null, params={password=111111, username=maomao}, status=200, paramsOfJson=null}","container_id":"1806d6c91569612cdd746651eeb808591e0176befe565820a339294fc2a9ea0d","container_name":"/nhbackend-st.1.d7r1qsa35zwfxtsmyh5np61ft","source":"stdout","requesttime":"1488509181152","method":"POST","action":"/nakedhub/adminx/auth/welcome","locale":"zh_CN","cost":4,"userId":"185713","user-agent":"null","token":"null","clientIp":"139.196.12.22","clientType":"null","params":"password=111111, username=maomao","status":200,"paramsOfJson":"null","latitude":30.29360008239746,"longitude":120.1613998413086,"country_code3":"CHN","country":"CN","country_name":"China","dma":null,"area":null,"region":"02","city":"Hangzhou","location":[120.1613998413086,30.29360008239746]}

5 最後

本篇相關的內容到這裡就結束了,有什麼問題的話給我留言,我會盡量回復,如果有不正確的地方還望不吝賜教,我會作出相應的改進,避免誤導更多人,謝謝。