前言



本来只是想写一篇Nginx日志的常用统计分析命令填充一下线上文档,虽然有点用但是觉得光写命令,文档太水了
于是就顺便总结一下,在nginx或web服务中,需要有哪些进行分析的内容以及为什么有这些需求


ps:
统计命令的原因 在于不是每个公司或web所在的服务器上都有配置elk或其他开源日志分析工具的,而且即使有工具有时也不能筛出自己想要的内容,这是个基础操作
虽然文档里直接cat access.log,但是这是个演示。如果日志很小,没什么问题。10多个G直接cat,内存和cpu资源又很小,系统会直接卡死,记得切片



日志格式



无论进行哪种日志的分析,首先要注意日志输出的格式,不要网上的拿来就直接用
以nginx来说,默认情况下没有特殊需求的,日志的配置如下:

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';
$remote_addr                客户端IP地址
$remote_user                客户端用户名称,一般为空
[$time_local]               访问时间
"$request"                  记录请求HTTP的方式以及URL
$status                     状态码
$body_bytes_sent            发送给客户端的文件大小
"$http_referer"             记录从哪个页面访问过来的
"$http_user_agent"          记录客户端相关信息
"http_x_forwarded_for"      客户端的ip地址
日志输出示例:
下面的IP,url仅为示例,如有雷同,纯属巧合

111.111.111.111 - - [28/Apr/2021:14:44:11 +0800] "GET /api/channel/unread.jsp?callback=jQuery17106116_1651126328463&action=bannerinfo&_=1651128251884 HTTP/1.1" 200 65 "https://www.xxxx.cn/group/" www.xxxx.cn "123.123.123.123" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" "-"
222.222.222.222 - - [28/Apr/2021:14:44:12 +0800] "GET /api/channel/message/unread.jsp?callback=jQuery1710046845505286&action=bannerinfo&_=1651 HTTP/1.1" 200 686 "https://www.xxxx.cn/group/" www.xxxx.cn "123.123.123.123" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3870.400 QQBrowser/10.8.4405.400" "-"
110.110.110.110 - - [28/Apr/2021:14:44:12 +0800] "GET /api/channel/message/unread.jsp?callback=jQuery1710342055625248369&action=bannerinfo&_=16511289 HTTP/1.1" 200 765 "https://www.xxxx.cn/group/" www.xxxx.cn "123.123.123.123" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" "-"


PV 和 UV



通常情况下对一个网站的价值进行评估,如果要详尽的讨论,不同的行业人会给出不同的划分。但是大致的来说,主要是从 网站的内容本身和产品的价值,网站流量带来的附加值,网站的网络排名,以及访问量(PV UV)这些方便进行评估。而网络上大多数排名网站,例如Alexa对网站排名,主要是对网站的pv,uv,存续时间等多种因素等进行排名。

PV指的是访问量,即页面浏览量或点击量,用户每次刷新即被计算一次,用户对同一页面的多次访问,访问量值会累计,也就是说可以不断的请求,以作弊的方式提升网站的pv,提升Alexa排名

UV指的是独立访客数(访问网站的一台电脑客户端为一个访客;00:00-24:00内相同的客户端只被计算一次)每一个固定的访客只代表一个唯一的用户,一天内无论他访问这个网站多少次,都只记录为一次。独立访客数越多,通常越证明网站内容有价值,推广行为越有成效。

虽然独立访客很接近我们需要的数据但实际上统计出来的数据并不完全都是真实独立的人。因为
独立访客这个指标也会受浏览器设置的影响;当更换了IP,但不清除cookies,再访问相同网站,该网站的统计中UV数是不变的;当不保存cookies访问、清除了cookies或者更换设备访问时,计数会加1;并且随着爬虫的兴起,常有人用大量的代理IP去刷uv

pv和uv虽然并不能完全的代表网站的价值,但是通常情况下仍是向客户展示网站价值的重要指标。最常见的是统计uv的一段时间内数据与用户访问频率较高网址,去展示用户的行为趋势,业务的相关人员再根据情况调整业务和推广



根据访问IP统计UV

awk '{print $1}'  access.log|sort | uniq -c |wc -l
or
cat access.log |awk '{print $1}' |sort | uniq -c |wc -l


根据访问url统计PV

awk '{print $7}' access.log | wc -l
or
cat access.log | awk '{print $7}' |wc -l


根据时间段统计查看日志
注意自己的时间的格式
为避免日志太大,注意日志切割

统计某时间段UV
cat  access.log| sed -n '/28\/Apr\/2021:14/,/28\/Apr\/2021:20/p'  |awk '{print $1}' |sort | uniq -c |wc -l
or
统计某时间段PV
cat  access.log| sed -n '/28\/Apr\/2021:14/,/28\/Apr\/2021:20/p'  | awk '{print $7}' |wc -l


IP 和 URL



这2个数据通常不会单独统计,单一的数据无法证明是否异常

常见于分析某断时间内对网站频繁访问的ip和url,判断是否受到其攻击或某些接口存在bug.被频繁的请求。通常在网站流量报警时,进行排查



查询访问最频繁的URL

awk '{print $7}' access.log|sort | uniq -c |sort -n -k 1 -r|more


查询访问最频繁的IP

awk '{print $1}' access.log |sort | uniq -c |sort -n -k 1 -r|more


查看某时间段访问频繁的IP和url

统计某时间段频繁访问的URL
cat  access.log| sed -n '/28\/Apr\/2021:14/,/28\/Apr\/2021:20/p'  | awk '{print $7}' |sort | uniq -c |sort -n -k 1 -r|more
or
统计某时间段频繁访问的IP
cat  access.log| sed -n '/28\/Apr\/2021:14/,/28\/Apr\/2021:20/p'  | awk '{print $1}'  |sort | uniq -c |sort -n -k 1 -r|more


查看指定的ip在某时间段访问了什么url

cat access.log | grep /28/Apr/2021" | grep "111.111.111.111" | awk '{print $7}' | sort | uniq -c | sort -nr 


备注:
实际上可通过计划任务或elk等方式监控日志,当5分钟或10分钟内的pv,超过平时正常的阈值,就列出该段时间内频繁访问的IP和url的top10,并展示ip所属地址

如果发现异常的访问,例如:
发现爬虫或大量IP请求不存在的网址的,要用iptables或配置nginx屏蔽IP或IP段



爬虫和每秒请求数



统计爬虫目的是确认是否是因不讲规矩的爬虫的大量访问,出现了访问的报警或功能异常

对请求数的统计,排列时间段内不同时间点的请求数(和前面的排列一段时间内的pv有些像),这个是以时间为重点,目的是查看具体从哪个时间点请求较大可能存在异常



统计蜘蛛抓取次数

grep 'spider' access.log |wc -l


统计每秒的请求数并根据请求数排列(前20)

awk '{print $4}' access.log |cut -c 14-21|sort|uniq -c|sort -nr|head -n 20

统计每分钟的请求数并根据请求数排列(前20)

awk '{print $4}' access.log |cut -c 14-18|sort|uniq -c|sort -nr|head -n 20

备注:
cut -c 指的 取第几个字节的区间



传输时间



要在nginx的日志配置中最后一个字段加入$request_time
$request_time 是nginx开始收到client 请求,到将请求发回给client 期间过去的时间

通过对不同页面或接口的响应时间的统计,来分析不同接口的性能,排查接口是否有问题,是否需要优化



列出传输时间超过 3 秒的url,显示前10条

cat access.log |awk '(substr($NF,2,5) > 3){print $4,$7,substr($NF,2,5)}' | awk -F '"' '{print $1,$2,$3}' |sort -k3 -rn | head -10


列出某个接口请求时间超过3秒的时间点

/user/search/
cat access.log |awk '(substr($NF,2,5) > 3 && $7~//user/search/){print $4,$7,substr($NF,2,5)}' | awk -F '"' '{print $1,$2,$3}' |sort -k3 -rn | head -10


获取前10条最耗时的请求时间、url、耗时

cat access.log |awk '{print $4,$7,substr($NF,2,5)}' | awk -F '"' '{print $1,$2,$3}' | sort -k3 -rn 


备注:

substr($NF,20)     是从最后一个字段里的第20个字符开始,一直到设定的分隔符结束
substr($NF,2,5)    是从最后一个字段里的第2个字符开始,截取5个字符结束
substr($3,6)       是从第3个字段里的第6个字符开始,一直到设定的分隔结束


连接数和并发量



统计当前80端口的TCP连接数(并发)

netstat -tan | grep "ESTABLISHED" | grep ":80" | wc -l


查看当前TCP连接中的各个状态的数据

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
CLOSED:无连接是活动的或正在进行
LISTEN:服务器在等待进入呼叫
SYN_RECV:一个连接请求已经到达,等待确认
SYN_SENT:应用已经开始,打开一个连接
ESTABLISHED:正常数据传输状态
FIN_WAIT1:应用说它已经完成
FIN_WAIT2:另一边已同意释放
ITMED_WAIT:等待所有分组死掉
CLOSING:两边同时尝试关闭
TIME_WAIT:另一边已初始化一个释放
LAST_ACK:等待所有分组死掉
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐