ELK採集之nginx 日誌高德地圖出城市IP分佈圖

最近確實忙得像狗一樣,很久沒有更新博客了。今天有點空閒時間寫一些相關的ELK stack的博客;本來想做成一些列,後面有時間的話再更新吧


1、採用拓撲:

wKioL1h3EzSSua9CAAArIrLMEjE551.png


角色扮演: 

Agent:採用logstash,IP:192.168.10.7

Redis隊列: IP:192.168.10.100

Indexer:logstash,IP:192.168.10.205

Es+kibana:放在192.168.10.100(大的日誌環境可以單獨存放)

 

說明:下面是一臺日誌服務器下面nginx的日誌格式

 

log_format backend '$http_x_forwarded_for [$time_local] '
                   '"$host" "$request" $status $body_bytes_sent '
                   '"$http_referer" "$http_user_agent"'



1、192.168.10.7上面agnet的配置:

[luohui@BJ-hua-h-web-07 ~]$ cat /etc/logstash-nginx.conf 
input {
    file {
        path =>["/home/data/logs/access.log"]
        type =>"nginx_access"
    } 
}
output {
if [type] == "nginx_access"{
   redis {
    host =>["192.168.10.100:6379"]
    data_type=>"list"
    key =>"nginx"
    }
  }
}

##說明:這裏的agent只是做日誌發送,對性能影響不大,讀取access.log日誌文件,並且發送到遠端redis。


2、192.168.10.205:indexer的配置:

[root@mail etc]# cat logstash_nginx.conf
input {
  redis {
    host =>"192.168.10.100"
    port => 6379
    data_type =>"list"
    key =>"nginx"
  }
}
filter {
        grok { 
              match=>
                {"message" =>"%{IPORHOST:clientip} \[%{HTTPDATE:timestamp}\] %                           {NOTSPACE:http_name}\"(?:%{WORD:verb} %{NOTSPACE:request}(?:HTTP/%                       {NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response}(?:%                      {NUMBER:bytes:float}|-) %{QS:referrer} %{QS:agent}"
            }
        }
    date {
        match => ["timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ]
    }
    geoip {
        source =>"clientip"
        target =>"geoip"
        database =>"/test/logstash-5.0.0/GeoLite2-City.mmdb"
        add_field => ["[geoip][coordinates]", "%{[geoip][longitude]}" ]
        add_field => ["[geoip][coordinates]", "%{[geoip][latitude]}"  ]
        }
    mutate {
            convert => [ "[geoip][coordinates]", "float"]
          }
    }
output {
     elasticsearch {
      action =>"index"
      hosts=>"192.168.10.100:9200"
      index =>"logstash-nginx-%{+yyyy.MM.dd}"
      }
}


##說明:這裏接收來自:redis的數據key爲nginx的。然後進行正則匹配篩選數據。

Geoip調用我們本地下載的庫,在linux版本下現在用:GeoLite2-City.mmdb,可以去網上下載。


備註:基本上操作的也就是logstash的相關操作,其他都是傻瓜安裝。但是記得要啓動elastic監聽端口,啓動redis監聽端口。最後面啓動logstash倒入數據。


這個比較簡單,調用city庫之後,選擇Tile map即可:

wKioL1h3FIyC1YLzAAFzrFYMC_A169.png-wh_50


這裏是kibana帶的地圖,可以看到是英文的城市名之類的,我們改成高德地圖,顯示中文城市名。


3、修改kibana.yml添加如下URL:

tilemap.url: "http://webrd02.is.autonavi.com/appmaptilelang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}"


4、重啓kibana即可得到如下圖形:

wKiom1h3FUjD0xbXAAKugZ2W72o406.png-wh_50


5、到這裏已經差不多完成了。然後還有剩下的相關圖表。大家熟悉kibana自己做聚合運算即可。


6、有一些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 ';



7、可以用如下的grok,默認一些正則表達式logstash已經提供,我們可以如下地址去查看:

vendor/bundle/jruby/1.9/gems/logstash-patterns-core-4.0.2/patterns


8、我們切換到這個目錄下,創建相關的正則:

[root@mail etc]#cd vendor/bundle/jruby/1.9/gems/logstash-patterns-core-4.0.2/patterns
[root@mail etc]#cat nginx
NGUSERNAME [a-zA-Z\.\@\-\+_%]+
NGUSER %{NGUSERNAME}
NGINXACCESS%{IPORHOST:clientip} - %{NGUSER:remote_user} \[%{HTTPDATE:timestamp}\]\"(?:%{WORD:verb} %{NOTSPACE:request}(?:HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response}(?:%{NUMBER:bytes:float}|-) %{QS:referrer} %{QS:agent}%{NOTSPACE:http_x_forwarded_for} %{NUMBER:request_time:float}


9、直接調用即可:

[root@controller etc]# catnginx.conf 
input {
  redis {
    host =>"192.168.10.100"
    port => 6379
    data_type =>"list"
    key =>"nginx"
  }
}
 
 filter { 
    grok {
        match => { "message" =>"%{NGINXACCESS}" }
    } 
    date {
        match => [ "timestamp" ,"dd/MMM/YYYY:HH:mm:ss Z" ]
    }
    geoip {
      source => "clientip"
      target => "geoip"
      database =>"/test/logstash-5.0.0/GeoLite2-City.mmdb"
      add_field => ["[geoip][coordinates]", "%{[geoip][longitude]}" ]
      add_field => ["[geoip][coordinates]", "%{[geoip][latitude]}"  ]
    }
    mutate {
      convert => ["[geoip][coordinates]", "float"]
    }   
  }
output { 
       stdout{codec=>rubydebug}
       elasticsearch {
       action => "index"
       hosts => "192.168.63.235:9200"
       index => "logstash-nginx-%{+yyyy.MM.dd}"
   } 
}

###到處已經可以手工了,剩下就是採集數據kibana聚合出圖的事情。


10、可以完善的,就是nginx我們可以再生成數據的時候以json的格式生成,這樣就不用grok去解析這麼消耗CPU了:


log_format json'{"@timestamp":"$time_iso8601",'
                '"host":"$server_addr",'
                '"clientip":"$remote_addr",'
                '"size":$body_bytes_sent,'
                '"responsetime":$request_time,'
                '"upstreamtime":"$upstream_response_time",'
                '"upstreamhost":"$upstream_addr",'
                '"http_host":"$host",'
                 '"url":"$uri",'
                '"xff":"$http_x_forwarded_for",'
                '"referer":"$http_referer",'
                '"agent":"$http_user_agent",'
                '"status":"$status"}';
access_log  /etc/nginx/logs/access.json  json;


11、然後我們生成的就是json格式的日誌了,還有一些需求的變量可以自己添加,logstask可以修改爲:

[root@controller logstash-5.0.0]#cat etc/nginx_json.conf 
input {
  file {             #從nginx日誌讀入
    type => "nginx-access"
    path =>"/etc/nginx/logs/access.json"
    start_position => "beginning" 
    codec => "json"  #這裏指定codec格式爲json
  }
}
 
filter {
   if [type] == "nginx-access"{
       geoip {
      source => "clientip"
      target => "geoip"
      database =>"/test/logstash-5.0.0/GeoLite2-City.mmdb"
      add_field => ["[geoip][coordinates]", "%{[geoip][longitude]}" ]
      add_field => [ "[geoip][coordinates]","%{[geoip][latitude]}"  ]
    } 
   }
}
 
output {
    if [type] == "nginx-access" {
    stdout{codec=>rubydebug}
    elasticsearch {
        action => "index"
        hosts => "192.168.63.235:9200"
        index => "mysql-slow-%{+yyyy.MM.dd}"
     }
  }
}



清爽好多,手工。注意GeoLite2-City.mmdb用這個庫,我之前用bat這個。是出不來圖的




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