logstash处理nginx日志并绘图


首先自定义一下nginx日志格式

①、方式一
 log_format log_json '{"@timestamp": "$time_iso8601","remote_addr": "$remote_addr","remote_user": "$remote_user","request_method": "$request_met
hod","uri": "$uri","query_string": "$query_string","status": "$status","body_bytes_sent": "$body_bytes_sent","http_referrer": "$http_referer","upstr
eam_status": "$upstream_status","upstream_addr" : "$upstream_addr","request_time": "$request_time","upstream_response_time": "$upstream_response_tim
e","request": "$request","http_user_agent": "$http_user_agent","http_x_forwarded_for": "$http_x_forwarded_for"}';
 ②、方式二
   log_format json '{"@timestamp":"$time_iso8601",''"host":"$server_addr",''"clientip":"$remote_addr",''"remote_user":"$remote_user",''"request_method":"$request_method",''"request":"$request",''"uri":"$uri",''"query_string":"$query_string",''"http_user_agent":"$http_user_agent",''"size":$body_bytes_sent,''"responsetime":$request_time,''"upstreamtime":"$upstream_response_time",''"upstreamhost":"$upstream_addr",''"url":"$uri",''"domain":"$host",''"client_realip":"$http_x_forwarded_for",''"referer":"$http_referer",''"status":"$status"}';

    access_log  logs/access.log  log_json(json);    #红色字体部分的值取决于定义日志时log_format后面值的设定

 

注:使用json日志格式,可自定义要写入到elasticsearch中的字段,不必在进行过滤,在写入es之前,可先打印到屏幕进行测试,看是否是自己想要的数据结构

 

非json数据 

其他完整格式

//日志格式
1.1.1.1 - - [06/Jun/2016:00:00:01 +0800] www.test.com GET "/api/index" "?cms=0&rnd=1692442321" 200 4 "http://www.test.com/?cp=sfwefsc" 200 192.168.0.122:80 0.004 0.004 "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" "-"
//自定义匹配规则 URIPARM1 [A-Za-z0-9$.+!*'|(){},~@#%&/=:;_?\-\[\]]* URIPATH1 (?:/[A-Za-z0-9$.+!*'(){},~:;=@#%&_\- ]*)+ URI1 (%{URIPROTO}://)?(?:%{USER}(?::[^@]*)?@)?(?:%{URIHOST})?(?:%{URIPATHPARAM})? NGINXACCESS %{IPORHOST:remote_addr} - (%{USERNAME:user}|-) \[%{HTTPDATE:log_timestamp}\] %{HOSTNAME:http_host} %{WORD:request_method} \"%{URIPATH1:uri}\" \"%{URIPARM1:param}\" %{BASE10NUM:http_status} (?:%{BASE10NUM:body_bytes_sent}|-) \"(?:%{URI1:http_referrer}|-)\" (%{BASE10NUM:upstream_status}|-) (?:%{HOSTPORT:upstream_addr}|-) (%{BASE16FLOAT:upstream_response_time}|-) (%{BASE16FLOAT:request_time}|-) (?:%{QUOTEDSTRING:user_agent}|-) \"(%{IPV4:client_ip}|-)\" \"(%{WORD:x_forword_for}|-)\"

 

默认自带的apache日志相对于nginx只是少了一个x_forward_for

//log_format配置
log_format  main  '$remote_addr - $remote_user [$time_local] $http_host $request_method "$uri" "$query_string" '
                  '$status $body_bytes_sent "$http_referer" $upstream_status $upstream_addr $request_time $upstream_response_time '
                  '"$http_user_agent" "$http_x_forwarded_for"' ;


//日志格式 1.1.1.1 - - [06/Jun/2016:00:00:01 +0800] www.test.com GET "/api/index" "?cms=0&rnd=1692442321" 200 4 "http://www.test.com/?cp=sfwefsc" 200 192.168.0.122:80 0.004 0.004 "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36" "-" //apache匹配规则
COMMONAPACHELOG %{IPORHOST:clientip} %{HTTPDUSER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)
COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %{QS:agent}

//修改后的nginx匹配规则
MAINNGINXLOG %{COMBINEDAPACHELOG} %{QS:x_forwarded_for}

 

 

本示例日志格式

103.77.56.226 - - [23/Aug/2018:16:04:54 +0800] "GET /favicon.ico HTTP/1.1" 404 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"

 

filebeats设置

[root@nginx filebeat-5.4.3-linux-x86_64]# cat filebeat.yml|grep -v "^$\|^#\|^  #"
filebeat.prospectors: - input_type: log paths: - /root/test.log #- c:\programdata\elasticsearch\logs\* fields: service: nginx_access output.logstash: hosts: ["10.20.200.107:5044"]


//启动方法
./filebeat -e -c filebeat.yml

 

Logstash设置

input {
  beats {
    port => "5044"
    codec  => json
  }
}

filter {
   if [fields][service] == "nginx_access" {          #①
      grok {
        match => {
            "message" => "%{NGINXACCESS}"          #②
        }
      }
      geoip {
            source => "remote_ip"               #③
            target => "geoip"
      #database => "/root/logstash-6.3.2/GeoLiteCity.dat"
            database => "/root/logstash-6.3.2/GeoLite2-City_20180807/GeoLite2-City.mmdb"    #④
            add_field => [ "[geoip][coordinates]", "%{[geoip][longitude]}" ]
            add_field => [ "[geoip][coordinates]", "%{[geoip][latitude]}" ]
    }
  
if
"_geoip_lookup_failure" in [tags] { drop { } }         #有无法解析的地址就删除

        mutate {
            convert => [ "[geoip][coordinates]", "float" ]        #⑤
            #convert => [ "status","integer" ]
            #convert => [ "bytes","integer" ]
            remove_field => [ "host","tags","beat","@version","prospector","fields","input","timestamp","message"]    #⑥
        }
   }
}

output {
  if [fields][service] == "nginx_access" {
     elasticsearch {
       hosts => ["10.20.200.107:9200"]
       index => "logstash-nginx_access-%{+YYYY.MM.dd}"      #如果要做map图形展示,这里索引必须以logstash开头
     }

  }
  #stdout { codec => rubydebug }            #这里表示将过滤的日志信息打印到屏幕输出,测试专用
}


//启动方法
bin/logstgash -f config/log.conf

说明:

  上述中①表示 从filebeat配置文件中选择[fields][service] == "nginx_access" 的日志进行过滤

    上述中②表示 对日志的过滤规则为NGINXACCESS,此过滤规则默认不存在需要自己根据日志实际情况进行匹配规则编写,logststash默认从${LOGSTASH_HOME}/vendor/bundle/jruby/2.3.0/gems/logstash-patterns-core-4.1.2/patterns/目录进行匹配规则的查找与使用,这里我将匹配规则放在了 grok-patterns 文件中,如下    

//匹配规则
WZ ([^ ]*) NGINXACCESS %{IP:remote_ip} \- \- \[%{HTTPDATE:timestamp}\] "%{WORD:method} %{WZ:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:status} %{NUMBER:bytes} %{QS:referer} %{QS:agent}

//如果自定义了patterns的目录文件,可使用如下方法指定(grok下与match下message同级)
parttens_dir="/../../xxx"      #xxx为定义的parttens的文件

  

   上述中③表示 根据remote_ip(匹配规则里已经指定,如果有cdn,最好用x_forward_for)进行地理位置判定

   上述中④表示 免费的IP地理位置数据库,下载地址(https://dev.maxmind.com/geoip/geoip2/geolite2/),详细信息看这里

   上述中⑤表示 修改指定字段的内容的类型

   上述中⑥表示 移除不需要的字段

 

检测配置文件是否有问题

bin/logstash -t -f config/log.conf        #检测配置文件是否正确

 

kibana匹配索引并绘图

 

注意:下图中方框内索引名(在es中创建索引时定义的)必须以logstash开头(要过要做map图形的话)

否则会报错

  报错“No Compatible Fields: The “[nginx-access-]YYYY-MM” index pattern does not contain any of the following field types: geo_point”

  解释说明

    在 elasticsearch 中,所有的数据都有一个类型,什么样的类型,就可以在其上做一些对应类型的特殊操作。geo信息中的   location字段是经纬度,我们需要使用经纬度来定位地理位置;在 elasticsearch 中,对于经纬度来说,要想使用 elasticsearch 提供的地理位置查询相关的功能,就需要构造一个结构,并且将其类型属性设置为geo_point,此错误明显是由于我们的geo的location字段类型不是geo_point。

  **解决方法:**Elasticsearch 支持给索引预定义设置和 mapping(前提是你用的 elasticsearch 版本支持这个 API,不过估计应该都支持)。其实ES中已经有一个默认预定义的模板,只要使用预定的模板即可,默认预定义的模板必须只有匹配 logstash-* 的索引才会应用这个模板,所以需要修改索引名字以logstash开头

 

                        

 

默认情况下的地图显示为英文,要使其转化为英文,需要修改kibana.yml配置文件

#在文件底部加上下面一句话

tilemap.url: 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'

 

最终结果

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM