Nginx日志自动切割分析

2017年3月6日16:41:33Nginx日志自动切割分析已关闭评论 11

Nginx的日志文件没有rotate功能。如果你不处理,日志文件将变得越来越大,还好我们可以写一个nginx日志切割脚本来自动切割日志文件。

Nginx日志自动切割分析

第一步就是重命名日志文件,不用担心重命名后nginx找不到日志文件而丢失日志。在你未重新打开原名字的日志文件前,nginx还是会向你重命名的文件写日志,linux是靠文件描述符而不是文件名定位文件。

第二步向nginx主进程发送USR1信号。

nginx主进程接到信号后会从配置文件中读取日志文件名称,重新打开日志文件(以配置文件中的日志名称命名),并以工作进程的用户作为日志文件的所有者。

重新打开日志文件后,nginx主进程会关闭重名的日志文件并通知工作进程使用新打开的日志文件。

工作进程立刻打开新的日志文件并关闭重名名的日志文件。

然后你就可以处理旧的日志文件了。

方案一

Nginx日志按日期自动切割脚本如下

#nginx日志切割脚本

#设置日志文件存放目录
logs_path=/home/wwwlogs/

#设置pid文件
pid_path=/usr/local/nginx/logs/nginx.pid

#重命名日志文件
mv ${logs_path}access.log ${logs_path}access_$(date +"%Y%m%d").log

mv ${logs_path}www.yfyyu.com.log ${logs_path}www.yfyyu.com.log_$(date +"%Y%m%d").log

#向nginx主进程发信号重新打开日志
kill -USR1 `cat ${pid_path}`

exit 0

crontab 设置定时作业

 

crontab -e

0 0 * * 7 bash /home/nginx_log.sh

 

这样就每周的星期日0点0分把nginx日志重命名为日期格式,并重新生成今天的新日志文件。使用 crontab -l 可以检查设置的定时

方案二

#!/bin/bash
# nginx 日记目录
log_files_path="/home/wwwlogs/"
log_files_dir=${log_files_path}$(date -d "yesterday" +"%Y")/$(date -d "yesterday" +"%m")
# nginx 日记名(这是默认是 access.log ,不须要 .log)
log_files_name="access"
# nginx 进程位置
nginx_sbin="/usr/local/nginx/sbin/nginx"
#这里设置分割天数
save_days=30
#新建分割目录(安装日期)
mkdir -p $log_files_dir

log_files_num=${#log_files_name[@]}

#搜索日记并分割
for((i=0;i<$log_files_num;i++));do
mv ${log_files_path}${log_files_name[i]}.log ${log_files_dir}/${log_files_name[i]}_$(date -d "yesterday" +"%Y%m%d").log
done

#删除设置天数的日记
find $log_files_path -mtime +$save_days -exec rm -rf {} \;

$nginx_sbin -s reload
Exit 0

 

按上面的设置计划定时任务

Nginx 日记分析

以nginx默认的日志格式为例:

$remote_addr – $remote_user [$time_local] “$request” $status $body_bytes_sent “$http_referer” “$http_user_agent”

各字段的含义分别是:

$remote_addr 请求者IP

$remote_user HTTP授权用户,如果不使用Http-based认证方式,其值为空

[$time_local] 服务器时间戳

"$request” HTTP请求类型(如GET,POST等)+HTTP请求路径(不含参数)+HTTP协议版本

$status 服务器返回的状态码(如200,404,5xx等)

$body_bytes_sent 服务器响应报文大小,单位byte

"$http_referer” referer字段值

"$http_user_agent” User Agent字段

以下列举常用的日志分析命令

根据状态码进行请求次数排序

cat access.log | cut -d ‘”‘ -f3 | cut -d ‘ ‘ -f2 | sort | uniq -c | sort –r

输出样例:

210433 200

38587 302

17571 304

4544 502

2616 499

1144 500

706 404

355 504

355 301

252 000

9 403

6 206

2 408

2 400

或者使用awk:

awk '{print $9}' access.log | sort | uniq -c | sort –r

上例显示有704次404请求,接下来是如何找到这些请求的URL

awk '($9 ~ /404/)' access.log | awk '{print $7}' | sort | uniq -c | sort –r

输出样列:

21 /members/katrinakp/activity/2338/

19 /blogger-to-wordpress/robots.txt

14 /rtpanel/robots.txt

接下来考虑如果找到这些请求的IP地址,使用命令:

awk -F\" '($2 ~ "/wp-admin/install.php"){print $1}' access.log | awk '{print $1}' | sort | uniq -c | sort -r

输出样例:

14 50.133.11.248

12 97.106.26.244

11 108.247.254.37

10 173.22.165.123

php后缀的404请求(通常是嗅探)

awk '($9 ~ /404/)' access.log | awk -F\" '($2 ~ "^GET .*\.php")' | awk '{print $7}' | sort | uniq -c | sort -r | head -n 20

按URL的请求数排序

awk -F\" '{print $2}' access.log | awk '{print $2}' | sort | uniq -c | sort –r

url包含XYZ:

awk -F\" '($2 ~ "ref"){print $2}' access.log | awk '{print $2}' | sort | uniq -c | sort –r

百度蜘蛛抓取分析

1.百度蜘蛛爬行的次数

cat access.log | grep Baiduspider | wc

最左面的数值显示的就是爬行次数

2.百度蜘蛛的详细记录(Ctrl C可以终止)

cat access.log | grep Baiduspider

也可以用下面的命令:

cat access.log | grep Baiduspider | tail -n 10

cat access.log | grep Baiduspider | head -n 10

只看最后10条或最前10条,这用就能知道这个日志文件的开始记录的时间和日期。

3.百度蜘蛛抓取首页的详细记录

cat access.log | grep Baiduspider | grep “GET / HTTP”

百度蜘蛛好像对首页非常热爱每个钟头都来光顾,而谷歌和雅虎蜘蛛更喜欢内页。

4.百度蜘蛛派性记录时间点分布

cat access.log | grep “Baiduspider ” | awk ‘{print $4}’

5.百度蜘蛛爬行页面按次数降序列表

cat access.log | grep “Baiduspider ” | awk ‘{print $7}’ | sort | uniq -c | sort –r

文中的Baiduspider 改成Googlebot都可以查看谷歌的数据,鉴于大陆的特殊性,大家应该对百度的log更为关注。

附:(Mediapartners-Google)Google adsense蜘蛛的详细爬行记录

cat access.log | grep Mediapartners

Mediapartners-Google是什么呢?Google adsense广告之所以能与内容相关,因为每个包含着adsense的广告被访问后,很快就有个Mediapartners-Google蜘蛛来到这个 页面,所以几分钟后再刷新就能显示相关性广告了,真厉害啊!

ITBIJI