在现今企业应用里面Nginx的应用基本是随处可见,尤其是业务系统的前置机大部分都会用它来做转发和负载分配。

 

但是它有个缺点就是日志管理不是很好,所有的日志都是写到access.log文件里且不拆分,如果系统访问量大,分分钟就是几个G的大文件,非常不利于后期复盘和日志分析,一般需要自己写脚本按天切割,这块无非就是一个脚本的任务量,可自行百度检索。

 

今天我们来探讨里面的日志分析和可视化,一般WEB请求无外乎POSTGET,打开百度网址,用chrome开发模式查看请求地址获取一个普通的gif文件,包含hostrequest methodrequest URLresonseagent等信息;

 

干货 | 金融深圳还是干不过杭州啊,“北上广深”要改名”北上广杭”了。。。...

当客户端通过HTTP协议访问服务器时,HTTP请求头、请求体以及响应信息就是我们要分析的对象。我们根据前期搭建部署的基于ELK的日志分析工具来讨论如何利用它来做nginx的日志分析,为了更直观的展现系统是由哪些地方发送的请求、每天的请求数量及请求客户端分布情况,我们采集了Nginxaccess日志并通过ELK做了如下的概览分析,其中包括:TPMTansaction per minute)、UV/PVtop 10 citiesTOP OSTOP 10 devicesTOP 10 browserTOP     IPsStatusTOP 10 Request,效果如下:

干货 | 金融深圳还是干不过杭州啊,“北上广深”要改名”北上广杭”了。。。...

 

这些可视化数据的实现主要分三步:

  1. 数据提取收集;

  2. 数据结构化;

  3.  数据可视化

数据结构化

 

我们从access.log文件中随便取一条来分析:

220.248.110.165- - [25/Jan/2019:21:27:18 +0800] "GET/appServer/account/login/accountLogin.json?jsonpCallback=checkLoginCode_1548422789887&mobile=138****2230&password=h%2FsAdzihQ26S046EA1ObAuRCcHC0binJw3ztpChJH%2F50SVvZbzSWQetW2sNJIM0CZh0OALX51z%2BEhGpTiREFaA%3D%3D&loginexplain=Mozilla/5.0%20(Windows%20NT%206.1;%20WOW64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/71.0.3578.98%20Safari/537.36&channel=mobileweb&_=1548422782082HTTP/1.1" 200 384 "https://xxx.xxxx.com/pages/asset.html""Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/71.0.3578.98 Safari/537.36"

 

这里如果根据nginx默认的结构化配置可以获得的字段有:

$remote_addr - $remote_user [$time_local]"$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"

 

我们知道ELK是流式的数据处理模式,Filebeat采集数据,Kafka做数据消息池,Elasticsearch存储数据,Logstash做数据的中转,所以数据的结构化处理在Logstash这里实现。

 

回忆下logstash的管道模式(输入、过滤器、输出),输入接受来自文件、kafkabeats等各方的数据、输出到ES,所以数据分析结构化的核心工作又都集中在了过滤器部分:

干货 | 金融深圳还是干不过杭州啊,“北上广深”要改名”北上广杭”了。。。...

 

Logstash是通过filter过滤器来进行数据处理的,并且提供了丰富的插件,本文使用了使用了jsongrokgeoipuseragentmutate这五个插件,简介如下:

  • Json:将json格式数据转化为field字段;

  • grok:将非结构化数据通过正则匹配结构化;

  • geoip:将IP地址国家城市化;

  • useragent:将请求的agent结构分析出来;

  • mutate:格式转换,比如字符串转化为浮点数;

 

其中grok的正则规则配置在logstash/vendor/bundle/jruby/x.x/gems/logstash-patterns-core-xxx/patterns/grok-patterns文件中,logstash自带的grok正则中有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的匹配格式:

NGINXACESS%{IPORHOST:clientip} (%{HTTPDUSER:ident}|-) (%{HTTPDUSER:auth}|-)\[%{HTTPDATE:timestamp}\] "(?:%{WORD:method} %{NOTSPACE:request}(?:HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response}(?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent}

 

不过到这里还只能获取基本的请求字段,还不能根据IP知道是哪个国家的哪个城市,也不能根据agent分析出用户使用的是什么手机、什么操作系统以及哪个浏览器,这部分使用了插件geoipuseragent,最终logstash的配置filter代码如下:

干货 | 金融深圳还是干不过杭州啊,“北上广深”要改名”北上广杭”了。。。...

数据结构化后如下:

{

  "_source": {

   "response": "200",

   "message": "220.248.110.165 - - [25/Jan/2019:21:27:18+0800] \"GET/appServer/account/login/accountLogin.json?jsonpCallback=checkLoginCode_1548422789887&mobile=138****2230&password=h%2FsAdzihQ26S046EA1ObAuRCcHC0binJw3ztpChJH%2F50SVvZbzSWQetW2sNJIM0CZh0OALX51z%2BEhGpTiREFaA%3D%3D&loginexplain=Mozilla/5.0%20(Windows%20NT%206.1;%20WOW64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/71.0.3578.98%20Safari/537.36&channel=mobileweb&_=1548422782082HTTP/1.1\" 200 384 \"https://xxx.xxx.com/pages/asset.html\"\"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/71.0.3578.98 Safari/537.36\"",

   "browseragent": {

     "name": "Chrome",

     "os": "Windows 7",

     "major": "71",

     "build": "",

     "patch": "3578",

     "os_name": "Windows 7",

     "minor": "0",

     "device": "Other"

   },

   "@timestamp": "2019-01-25T13:27:19.720Z",

   "method": "GET",

   "referrer":"\"https://xxx.xxx.com/pages/asset.html\"",

   "type": "xds_nginx",

   "ident": "-",

   "timestamp": "25/Jan/2019:21:27:18 +0800",

   "bytes": "384",

   "agent": "\"Mozilla/5.0 (Windows NT 6.1; WOW64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98Safari/537.36\"",

   "geoip": {

     "country_name": "China",

     "ip": "220.248.110.165",

     "latitude": 31.0456,

     "country_code3": "CN",

     "region_name": "Shanghai",

     "timezone": "Asia/Shanghai",

     "country_code2": "CN",

     "city_name": "Shanghai",

     "region_code": "31",

     "coordinates": [

       121.3997,

       31.0456

     ],

     "continent_code": "AS",

     "longitude": 121.3997,

     "location": {

       "lon": 121.3997,

       "lat": 31.0456

     }

   },

   "clientip": "220.248.110.165",

   "@version": "1",

   "offset": 34829616,

   "request":"/appServer/account/login/accountLogin.json?jsonpCallback=checkLoginCode_1548422789887&mobile=138****2230&password=h%2FsAdzihQ26S046EA1ObAuRCcHC0binJw3ztpChJH%2F50SVvZbzSWQetW2sNJIM0CZh0OALX51z%2BEhGpTiREFaA%3D%3D&loginexplain=Mozilla/5.0%20(Windows%20NT%206.1;%20WOW64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/71.0.3578.98%20Safari/537.36&channel=mobileweb&_=1548422782082",

   "auth": "-",

   "httpversion": "1.1",

    "highlight": {

   "request": [

     "jsonpCallback=checkLoginCode_1548422789887&[email protected]@138****[email protected]/[email protected]&password=h%2FsAdzihQ26S046EA1ObAuRCcHC0binJw3ztpChJH%2F50SVvZbzSWQetW2sNJIM0CZh0OALX51z%2BEhGpTiREFaA%3D%3D&loginexplain=Mozilla/5.0%20(Windows%20NT%206.1;%20WOW64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/71.0.3578.98%20Safari/537.36&channel=mobileweb&_=1548422782082"

    ]

}

 

 

数据可视化

有了字段的结构化后的数据后,通过Kibana来实现数据可视化部分,注意在配置各模块之前需要刷新下索引信息,否则进来的结构数据不会生效

干货 | 金融深圳还是干不过杭州啊,“北上广深”要改名”北上广杭”了。。。...

我们以访问IP所在地的城市数据为例:

干货 | 金融深圳还是干不过杭州啊,“北上广深”要改名”北上广杭”了。。。...根据上图设置便可以统计一段时间内的访问情况,我们设置的可视化模块如下:

 

干货 | 金融深圳还是干不过杭州啊,“北上广深”要改名”北上广杭”了。。。...

综上,Nginx或者500返回码说明系统有问题了也要引起警觉。

相关文章: