如果你想了解有关你的网站访问情况的详细信息,那么分析你的Web服务器日志是一个不错的选择。在本文中,我们将向你介绍一款强大的命令行工具GoAccess,并演示如何使用它来分析你的Web服务器日志。

什么是GoAccess?

GoAccess是一款开源的实时Web日志分析工具,它可以通过命令行界面展示访问日志的各种统计信息,包括访问量、访问者IP、页面浏览量、流量等等。在实际使用中,可以用于监控网站访问情况、分析用户行为、识别潜在攻击等等。

GoAccess默认支持分析多种日志,如:Apache、Nginx、Amazon S3、 Elastic Load Balancing、 CloudFront等,本文主要是使用GoAccess分析Nginx日志。

项目地址:allinurl/goaccess

GoAccess生成的报告

安装GoAccess

在使用GoAccess之前,你需要先安装它。GoAccess支持在Linux、Unix和macOS等操作系统上运行,可以通过源码安装或者直接从发行包中获取。不过发行包的版本一般比较旧,所以我一般是选择从源码安装。

从源码安装需要先安装一些依赖包,具体可以参考下面:

DistroNCursesGeoIP (可选)GeoIP2 (可选)OpenSSL (可选)
Ubuntu/Debianlibncursesw6-devlibgeoip-devlibmaxminddb-devlibssl-dev
RHEL/CentOSncurses-develgeoip-devellibmaxminddb-developenssl-devel
Archncursesgeoiplibmaxminddbopenssl
Gentoosys-libs/ncursesdev-libs/geoipdev-libs/libmaxminddbdev-libs/openssl
SlackwarencursesGeoIPlibmaxminddbopenssl
  • NCurses:这个是必须安装的。
  • GeoIP:如果编译参数包含了地理位置的支持,并且对应的值是legacy,则需要安装。
  • GeoIP2:如果编译参数包含了地理位置的支持,并且对应的值是mmdb,则需要安装。
  • OpenSSL:如果编译参数包含了支持WebSocket server,则需要安装。

注意:你可能还需要安装像 gccautoconfgettextautopoint 等构建工具。例如 base-devel,,build-essential, "Development Tools".

以下是在Debian系统从源码安装的命令

# 更新软件包
apt-get update
# 安装依赖包
apt-get -y install libncursesw5-dev	libmaxminddb-dev libssl-dev
# 安装构建工具
apt-get -y install build-essential

# 下载GoAccess源码
wget https://tar.goaccess.io/goaccess-1.7.2.tar.gz
tar -xzvf goaccess-1.7.2.tar.gz
cd goaccess-1.7.2/
# 编译
./configure --enable-utf8 --enable-geoip=mmdb -with-openssl
make
make install

编译选项

--enable-debug 开启调试符号并关闭编译器优化。

--enable-utf8 支持宽字符。

--enable-geoip=<legacy|mmdb> 支持地理位置。legacy 将使用原始的GeoIP数据库,mmdb 将使用增强的GeoIP2数据库。点击进入GeoIP2数据库下载地址,需要注册账号,下载GeoLite2-City或者GeoLite2-Country可以。

--with-getline 动态扩展行缓冲区,以解析完整行请求,而不是使用固定大小为4096的缓冲区。

--with-openssl 支持WebSocket server

遇到的问题

1. 无法安装 libncursesw6-dev,提示“Unable to locate package libncursesw6-dev”

改成安装 libncursesw5-dev就可以了。

配置

配置文件路径在 /etc/goaccess/goaccess.conf/usr/local/etc/goaccess/goaccess.conf(前者是发行包安装时的路径,后者是使用源码安装时的配置文件路径)

GoAccess配置的日志格式 log-format 和待解析日志的格式必须是一致,否则无法解析。GoAccess配置文件里已经预定义了格式,可以在配置文件里搜索log-format查看。

下面就以Nignx日志为例

GoAccess配置

# 日志格式
log-format %h - %^ [%d:%t %^] "%r" %^ %s %b %^/%^ "%R" "%u" "%^" %^ %^ %^ %T %v
# 日期格式
date-format %d/%b/%Y
# 时间格式
time-format %H:%M:%S
# GeoIP2数据库路径
geoip-database /path/to/GeoLite2-City.mmdb

我们也可以不修改配置文件,直接在使用的时候指定参数,例如:

goaccess -a -d -f /var/log/nginx/access.log -o /path/to/report.html --log-format='%h - %^ [%d:%t %^] "%r" %^ %s %b %^/%^ "%R" "%u" "%^" %^ %^ %^ %T %v' --date-format=%d/%b/%Y --time-format=%H:%M:%S  --geoip-database=/path/to/GeoLite2-City.mmdb

Nginx配置

http {
        ##
        # Logging Settings
        ##

        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$sent_http_content_type $status $body_bytes_sent '
                  '$ssl_protocol/$ssl_cipher "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for" '
                  '$connection $upstream_addr '
                  '$upstream_response_time $request_time $host';

        access_log /var/log/nginx/access.log main;
        error_log /var/log/nginx/error.log;
}

日志格式说明

GoAccessNginx描述
%h$remote_addr主机(客户端的 IPv4 或 IPv6 地址)
%e$remote_user通过 HTTP 身份认证访问网站的用户标识
%d:%t$time_local访问日期和时间(服务器本地时间)
%r$request客户端的请求路径(location)
$sent_http_content_type请求的资源类型(MIME-type)
%s$status服务器返回客户端的状态代码
%b$body_bytes_sent对象返回客户端的大小
$ssl_protocol建立连接的 TLS 加密协议类型
$ssl_cipher建立连接的 TLS 加密算法类型
%R$http_referer请求标头中的来源(Referer)信息
%u$http_user_agent请求标头中的 user-agent 信息
%C$upstream_cache_status服务器返回对象的缓存状态
$connection连接序号
$upstream_addr转发到那个地址
$upstream_response_time转发响应时间
%T$request_time服务器响应请求的时间(毫秒计量)
%v$host虚拟主机名称
%C$upstream_cache_status服务器返回对象的缓存状态
%^不进行解析

日志格式转换工具

https://github.com/stockrt/nginx2goaccess

nginx2goaccess可以把Nginx的日志格式转换为GoAccess的日志格式,这样可以节省不少时间和精力。

使用方法:

  1. 前往项目地址下载 nginx2goaccess.sh 脚本
  2. 运行sh nginx2goaccess.sh '<nginx_log_format>'
$ sh nginx2goaccess.sh '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'

- Generated goaccess config:

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

分析服务器日志

分析单个日志文件

goaccess -a -d -f /var/log/nginx/access.log -o /path/to/report.html  -p /usr/local/etc/goaccess/goaccess.conf

参数说明

-a 启用user-agent列表

-d 输出HTML或者JSON时开启IP解析

-f <path_to_log> 指定解析的日志文件路径

-o <path_to_ouput> 指定输出的文件路径

-p <path_to_config> 指定配置文件路径

分析多个日志文件

我们平时日志文件都会有切割,那应该怎么对多个日志文件进行分析呢?

  1. 使用通配符
goaccess -a -d -f /var/log/nginx/access.log* -o /path/to/report.html --log-format='%h - %^ [%d:%t %^] "%r" %^ %s %b %^/%^ "%R" "%u" "%^" %^ %^ %^ %T %v' --date-format=%d/%b/%Y --time-format=%H:%M:%S  --geoip-database=/path/to/GeoLite2-City.mmdb
  1. 使用管道

一般我们的历史日志都是压缩保存的,到时候可能会有两种格式txt和gz,这样上面的方法就不适用了。还好GoAccess支持管道,我们可以使用下面的方法进行解析

zcat -f /var/log/nginx/access.log* | goaccess -a -d -o /path/to/report.html --log-format='%h - %^ [%d:%t %^] "%r" %^ %s %b %^/%^ "%R" "%u" "%^" %^ %^ %^ %T %v' --date-format=%d/%b/%Y --time-format=%H:%M:%S  --geoip-database=/path/to/GeoLite2-City.mmdb