前言

使用Nginx的网站可能会遇到访问流量异常、被友情检测、程序出现Bug等各种突然情况,这时大家的反应想必都是第一时间分析日志,然后发现日志有几十GB之多,又需要按照时间、错误类型或者关键字段检索信息时会不会有种醍醐灌顶、菊花一紧的错觉。文中介绍的方法不管是GoAccess还是sed/awk虽然可以解决一时的问题但未必能够治本,也许ELK(Logstash+ElasticSearch+Kibana)对我们大多数人来说是更合理的集中化日志管理解决方案。

日志固然重要,但努力建设适合业务发展的集中化日志管理平台才是基础核心


更新历史

2015年08月31日 - 增加Nginx日志按时间分割
2015年07月16日 - 初稿

阅读原文 - https://wsgzao.github.io/post/goaccess/

扩展阅读

GoAccess - http://goaccess.io/
用GoAccess分析Nginx的日志 - http://www.fancycoding.com/log-analyse-using-goaccess/
sed 简明教程 - http://coolshell.cn/articles/9104.html
AWK 简明教程 - http://coolshell.cn/articles/9070.html
LTMP索引 - https://wsgzao.github.io/index/#LTMP


安装GoAccess

各平台都有灰常简单的部署方案 - http://goaccess.io/download

1
2
3
4
5
6
wget http://tar.goaccess.io/goaccess-0.9.2.tar.gz
tar -xzvf goaccess-0.9.2.tar.gz
cd goaccess-0.9.2/
./configure --enable-utf8
make
make install

使用方式

更多常见问题请参考官方FAQ - http://goaccess.io/faq

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

#直接打开
goaccess -f access.log

#选择日志格式
NCSA Combined Log Format

#剩下的操作都蛮简单的,参考扩展阅读和官方文档吧

#导出HTML报告会遇到的问题
goaccess -f time_access.log -a > report.html

GoAccess - version 0.9.2 - Jul 15 2015 16:23:20
Config file: /usr/local/etc/goaccess.conf

Fatal error has occurred
Error occured at: src/parser.c - verify_formats - 1691
No time format was found on your conf file.

#添加配置文件
vi ~/.goaccessrc

time-format %T
date-format %d/%b/%Y
log-format %h %^[%d:%t %^] "%r" %s %b "%R" "%u"

#重新指定配置文件后执行
goaccess -f time_access.log -p ~/.goaccessrc -a > report.html

使用bash/sed/awk手动查找Nginx日志

更多技巧可以参考扩展阅读,Python的处理效率或者更优

1
2
3
4
5
6
7
8
9
#按日期查找时间段
sed -n "/30\/Aug\/2015:00:00:01/,/30\/Aug\/2015:23:59:59/"p access.log > time_access.log

#查找504错误的页面和数量
awk '($9 ~ /504/)' time_access.log | awk '{print $7}' | sort | uniq -c | sort -rn > 504.log

#查找访问最多的20个IP及访问次数
awk '{print $1}' time_access.log | sort | uniq -c | sort -n -k 1 -r | head -n 20 > top.log

Nginx日志按时间分割

这个脚本可以作为通用模板,其它业务需求也可以参照

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

#增加自定义脚本
vi nginx_log.sh

#!/bin/bash
#设置crontab -e为每日凌晨3点
#0 3 * * * /root/OMCS/script/nginx_log.sh

for ngix_i in `ls /app/local`
do
#设置临时变量
nginx_dir=`basename ${ngix_i}`
if ( echo "$nginx_dir"|grep "nginx" > /dev/null ); then
# echo $nginx_dir
#设置日志文件存放目录
logs_path="/app/local/$nginx_dir/logs/"
#设置备份日志存放目录
logs_bak="/app/local/$nginx_dir/logs/bak/"
#设置pid文件
pid_path="/app/local/$nginx_dir/logs/nginx.pid"

#判断目录是否存在
if [ ! -d "$logs_path" ]; then
continue
fi
#判断文件是否存在
if [ ! -e "$pid_path" ]; then
continue
fi

#判断目录是否存在
if [ ! -d "$logs_bak" ]; then
mkdir -p "$logs_bak"
fi

cd ${logs_path}
logfiles=(`ls *.log`)

array_i=0
#迁移日志循环模块
for i in ${logfiles[@]};
do
#设置临时变量
j=`basename ${i}`
#重命名并迁移日志文件
baklogname=${j}_$(date -d "yesterday" +"%Y%m%d%H%M%S")
baklognames[$array_i]=$baklogname
mv ${i} ${logs_bak}${baklogname}
array_i=`expr $array_i + 1`
done

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

cd ${logs_bak}
#压缩日志循环模块
for i in ${baklognames[@]};
do
#压缩并删除原日志
tar -zcvf ${i}.tar.gz ${i} --remove-files > /dev/null 2>&1
done

#清理7天前的日志
find ${logs_bak} -name '*' -mtime +90 | xargs rm -rf {}

fi

done

#增加执行权限
chmod u+x nginx_log.sh

#设置crontab -e为每日凌晨3点
crontab -e

0 3 * * * /root/OMCS/script/nginx_log.sh

文章目录
  1. 1. 前言
  2. 2. 更新历史
  3. 3. 安装GoAccess
  4. 4. 使用方式
  5. 5. 使用bash/sed/awk手动查找Nginx日志
  6. 6. Nginx日志按时间分割