ELK採集之nginx 之高德地圖出城市IP分佈圖
1、採用拓撲:
角色扮演:
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-huasuan-h-web-07 ~]$ cat /home/luohui/logstash-5.0.0/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即可:
這裡是kibana帶的地圖,可以看到是英文的城市名之類的,我們改成高德地圖,顯示中文城市名。
3、修改kibana.yml添加如下URL:
tilemap.url: "http://webrd02.is.autonavi.com/appmaptilelang=zh_cn&size=1&scale=1&stylex=8&x={x}&y={y}&z={z}"
4、重啟kibana即可得到如下圖形:
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";
7、可以用如下的grok,默認一些正則表達式logstash已經提供,我們可以如下地址去查看:
vendor/bundle/jruby/1.9/gems/logstash-patterns-core-4.0.2/patterns
8、我們切換到這個目錄下,創建相關的正則:
[root@controller logstash-5.0.0]# cd vendor/bundle/jruby/1.9/gems/logstash-patterns-core-4.0.2/patterns[root@controller patterns]# 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、直接調用即可:
###到處已經可以手工了,剩下就是採集數據kibana聚合出圖的事情。
[root@controller etc]# cat nginx.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}"
}
}
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_nginx.json json;
11、這樣就省去了很多解析的部分,直接用json格式解析即可。
[root@controller logstash-5.0.0]# cat etc/nginx_json.conf
input {
file { #從nginx日誌讀入
type => "nginx-access"
path => "/etc/nginx/logs/access_nginx.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這個。是出不來圖的
ELK相關課程:日誌分析之 ELK stack 實戰
推薦閱讀: