使用goaccess分析Nginx日志

首先安装 goaccess:

1
2
brew install goaccess # Mac
yum -y install goaccess # centos

安装完成之后,就可以用 goaccess 为 Nginx 的日志生成 html 版本的报告了,首先我们要获取 Nginx 日志,正好有一个正在运行的 Nginx:alpine 容器,进去看一下:

1
2
3
4
5
6
$ cat /etc/nginx/nginx.conf
error_log /var/log/nginx/error.log warn;

http {
access_log /var/log/nginx/access.log main;
}

发现默认情况下被存储在 /var/log/nginx 目录下:

1
2
3
4
$ ls -l /var/log/nginx/
total 0
lrwxrwxrwx 1 root root access.log -> /dev/stdout
lrwxrwxrwx 1 root root error.log -> /dev/stderr

这两个文件被做成了软链接输出到 console 了,查看一下官方提供的 Dockerfile 果然如此:

1
2
ln -sf /dev/stdout /var/log/nginx/access.log
ln -sf /dev/stderr /var/log/nginx/error.log

这样的话只需要取 docker 的日志即可:

1
2
$ docker inspect --format='{{.LogPath}}' <nginx-containter-id>
/mnt/docker/containers/xxx/xxx-json.log

把这个文件拷贝一份出来,命名为 nginx.log,然后用 goaccesss 分析:

1
2
3
4
5
6
7
8
$ goaccess -f nginx.log -o result.html
Parsing... [0] [0/s]
GoAccess - version 1.3 - Apr 16 2019 15:50:32
Config file: No config file used

Fatal error has occurred
Error occurred at: src/parser.c - parse_log - 2764
未在配置文件中设置时间格式

提示我们要配置日志的时间格式,先找到默认的配置文件:

1
2
/usr/local/Cellar/goaccess/<版本号>/etc/goaccess/goaccess.conf # Mac os 下默认文件在此路径
# 如果不知道的话,可以用 whereis goaccess 查看

打开后开启下面几项:

1
2
3
time-format %H:%M:%S
date-format %d/%b/%Y
log-format %h %^[%d:%t %^] "%r" %s %b "%R" "%u"

再运行 goaccess 就可以了,如果还报错的话,可能是日期格式问题,例如 1.3 版本是重大升级,添加国际化的内容,如果你在命令行运行 date 的时候输出类似下面的结果:

1
20xx年 x月xx日 星期二 14时48分01秒 CST

那么需要用下面的方式来运行:

1
2
3
4
5
6
# 不会报错,但是生成的是英文格式
LANG="en_US.UTF-8" bash -c 'goaccess access.log --log-format=COMBINED'
# 会报错 Token '17/Feb/2017' doesn't match specifier '%d'
LANG="zh_CN.UTF-8" bash -c 'goaccess nginx.log --log-format=COMBINED -o result.html'
# 不会报错,而且生成的HTML是中文歌是
LANG="en_US.UTF-8" LC_TIME="en_US.UTF-8" bash -c 'goaccess nginx.log --log-format=COMBINED -o result.html'

常用参数说明:

  • -f --log-file=<logfile> 指定日志文件
  • -p --config-file=<filename> 指定配置文件
  • --real-time-html 实时更新
  • -a --agent-list 开启 UserAgent 列表。开启后会降低解析速度。
  • -d --with-output-resolver 输出 HTML 或者 JSON 报告时开启 IP 解析。
  • -o --output=<json|csv|html> 将给定文件重定向到标准输出,通过后缀名决定输出格式

下面是启动 goaccess 常用的命令:

1
2
3
4
5
6
# 指定文件和配置文件
goaccess -f nginx.log -p ./goaccess.conf -o result.html
# 指定日志格式
goaccess -f nginx.log --log-format='%^ %^[%h] %^[%d:%t %^] "%r" %s %b "%R" "%u" %^ %T %^' --date-format='%d/%b/%Y' --time-format=%T -o result.html
# 实时更新html
nohup ./goaccess -f access.log -p config/nginxlog.conf -o day-report.html --real-time-html --ws-url=report.xxx.com &

还可以用 docker 来运行,下载官方镜像 allinurl/goaccess,然后启动:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 使用默认的配置
docker run -d \
--name=goaccess \
--restart=always \
-p 7890:7890 \
-v $PWD/data:/srv/data \
-v $PWD/report:/srv/report \
-v $PWD/logs:/srv/logs \
allinurl/goaccess

# 自定义配置
docker run -d \
--name=goaccess \
--restart=always \
-p 7890:7890 \
-v /devops/goaccess:/srv/data \
-v /static/goaccess:/srv/report \
-v /mnt/log/nginx:/srv/logs \
allinurl/goaccess \
goaccess \
--config-file=/srv/data/goaccess.conf \
--log-file=/srv/logs/access.log \
--output=/srv/report/goaccess.html \
--ws-url=ws://xx.xx.xx.xx:7890/

可以看到,需要挂载3个目录:

  • /srv/data 是配置文件目录
  • /srv/report 是输出html的目录
  • /srv/logs 是日志文件目录

为了能访问 goaccess 输出的 html,还需要再启动一个 nginx 容器:

1
2
3
4
5
6
docker run -d \
--name goaccess-dashboard \
--restart=always \
-p 3005:80 \
-v /static/goaccess:/usr/share/nginx/html \
nginx:1-alpine

不过官方默认镜像时区不是中国时区,语言也不是中文,可以在官方镜像的基础上添加时区和语言选项:

1
2
3
4
5
6
7
8
9
FROM allinurl/goaccess:latest

# 设置中文时区
RUN apk add tzdata
ENV TIME_ZONE=Asia/Shanghai
RUN /bin/cp /usr/share/zoneinfo/$TIME_ZONE /etc/localtime && echo $TIME_ZONE > /etc/timezone

# 设置中文语言
ENV LANG zh_CN.UTF-8