在现今企业应用里面Nginx的应用基本是随处可见,尤其是业务系统的前置机大部分都会用它来做转发和负载分配。
但是它有个缺点就是日志管理不是很好,所有的日志都是写到access.log文件里且不拆分,如果系统访问量大,分分钟就是几个G的大文件,非常不利于后期复盘和日志分析,一般需要自己写脚本按天切割,这块无非就是一个脚本的任务量,可自行百度检索。
今天我们来探讨里面的日志分析和可视化,一般WEB请求无外乎POST和GET,打开百度网址,用chrome开发模式查看请求地址获取一个普通的gif文件,包含host、request method、request URL、resonse、agent等信息;
当客户端通过HTTP协议访问服务器时,HTTP请求头、请求体以及响应信息就是我们要分析的对象。我们根据前期搭建部署的基于ELK的日志分析工具来讨论如何利用它来做nginx的日志分析,为了更直观的展现系统是由哪些地方发送的请求、每天的请求数量及请求客户端分布情况,我们采集了Nginx的access日志并通过ELK做了如下的概览分析,其中包括:TPM(Tansaction per minute)、UV/PV、top 10 cities、TOP OS、TOP 10 devices、TOP 10 browser、TOP IPs、Status及TOP 10 Request,效果如下:
这些可视化数据的实现主要分三步:
数据提取收集;
数据结构化;
数据可视化;
第一点系统的架构和采集检索分析参见前文(大数据 | 打鱼,你是用鱼网还是鱼竿呢?),本次主要分享第二点和第三点,即如何将收集到的数据结构化和可视化。
数据结构化
我们从access.log文件中随便取一条来分析:
220.248.110.165- - [25/Jan/: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 "/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的管道模式(输入、过滤器、输出),输入接受来自文件、kafka、beats等各方的数据、输出到ES,所以数据分析结构化的核心工作又都集中在了过滤器部分:
Logstash是通过filter过滤器来进行数据处理的,并且提供了丰富的插件,本文使用了使用了json、grok、geoip、useragent和mutate这五个插件,简介如下:
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分析出用户使用的是什么手机、什么操作系统以及哪个浏览器,这部分使用了插件geoip和useragent,最终logstash的配置filter代码如下:
数据结构化后如下:
{
"_source": {
"response": "200",
"message": "220.248.110.165 - - [25/Jan/: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 \"/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": "-01-25T13:27:19.720Z",
"method": "GET",
"referrer":"\"/pages/asset.html\"",
"type": "xds_nginx",
"ident": "-",
"timestamp": "25/Jan/: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&mobile=@kibana-highlighted-field@138****2230@/kibana-highlighted-field@&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的日志分析和可视化基本完成。有了可视化的信息展示不仅可以方便业务分析,比如我们常说的“北上广深”,从实际的访问情况(近一周内)来看被“北上广杭”替代,除了上海、北京、广州外,杭州的用户购买基金理财诉求比深圳要高些哦,看来这几年由于阿里的带动使得杭州高资产用户崛起了!也可以用作一些应急处理,比如某个请求在短时间内大量访问可以给系统管理员提供一些提示或者分析(参见上文探讨 | 拼多多事件,技术人员到底有没有责任的风险控制),还有如果出现了大量的404或者500返回码说明系统有问题了也要引起警觉。
本文仅是数据分析的冰山一角,大部分数据分析的商用系统在小团队中使用感觉不是很必要而且成本高昂,而ELK开源免费推荐小团队可以试一试哦
参考:
Logstash的Filter官网:https://www.elastic.co/guide/en/logstash/6.2/filter-plugins.html
Logstash的grok过滤:/Orgliny/p/5592186.html
附.常用返回码