Nginx 日志分析工具:GoAccess

是分析访问日志,速度很快;除了输出为html文件,还支持json、csv。

快速生成html文件

Ubuntu 24.04 源是1.8.1版本,官方更新到1.10.2,官方网站文档

wget -O - https://deb.goaccess.io/gnugpg.key | gpg --dearmor | sudo tee /usr/share/keyrings/goaccess.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/goaccess.gpg arch=$(dpkg --print-architecture)] https://deb.goaccess.io/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/goaccess.list
sudo apt-get update
sudo apt-get install goaccess

Nginx的日志文件格式配置:

    log_format main '$remote_addr - $remote_user $time_fmt "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
    # $time_fmt 的格式为[YYYY-MM-DD HH:mi:ss]

Nginx的日志文件内容示例:

59.82.83.23 - - 2026-04-09 19:44:36 "GET /favicon.ico HTTP/1.1" 200 17757 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.6982.167 Safari/537.36"

sudo vim /etc/goaccess/goaccess.conf里面也有很多预置格式,可以看注释文本,找到你自己取消注释行就可以了。

time-format %H:%M:%S
date-format %Y-%m-%d
log-format %h - %e %d %t "%r" %s %b "%R" "%u"

log-format 说明,更多见映射关系章节。

Nginx 变量GoAccess 格式符说明
$remote_addr%h客户端地址
字面量 –原样匹配
$remote_user%e远程用户(可能为 -)
%d %t日期+时间,由 date-format time-format 解析
$request“%r”请求行(引号内)
$status%s状态码
$body_bytes_sent%b响应字节数
$http_referer“%R”Referer(引号内)
$http_user_agent“%u”User-Agent(引号内)

执行后,生成约2.1 MB的HTML报告文件,打开发现是英文的。

goaccess -f /var/log/nginx/access_blog.t725.cn.log -o /data/downloads/report.html

生成中文html文件

先使用locale -a查看有没有zh_CN.UTF-8,如果没有先安装语言包。

sudo apt update
# 安装中文环境支持,因为 zh-CN.UTF-8 在 Ubuntu Server 24.04 mini 默认是不安装的。
sudo apt install language-pack-zh-hans language-pack-zh-hans-base

安装好,不用更换系统默认语言环境,也能生成中文html文件。

(export LANG=zh_CN.UTF-8; goaccess -f /var/log/nginx/access_blogt725.cn.log -o /data/downloads/report.html)

Oracle VPS Ubuntu Server 24.04 mini 上踩过的坑

死活生成出来是英文,后面排查发现:

直接原因是没有/usr/share/locale/zh_CN/LC_MESSAGES/goaccess.mo

根本原因是被Oracle配置了“精简模式”,也就是在安装软件包时会过滤掉所有的本地化翻译文件(locales/languages)和文档。

解决办法

  1. /etc/dpkg/dpkg.cfg.d/excludes文件里,注释下面行,或者直接删除这个文件。
path-exclude=/usr/share/locale/*/LC_MESSAGES/*.mo
  1. 重新安装语言包与GoAccess:
sudo apt reinstall language-pack-zh-hans language-pack-zh-hans-base goaccess
  1. 确认结果
ls -l /usr/share/locale/zh_CN/LC_MESSAGES/goaccess.mo
  1. 恢复GoAcces配置,重新安装会被重置
sudo vim /etc/goaccess/goaccess.conf

地理位置解析

  1. 账号免费注册:https://dev.maxmind.com/geoip/geolite2-free-geolocation-data/
    • 注意:注册为CN账号,是不能下载GeoLite2-City。
  2. 到用户中心创建Key、查看你需要下载ip库URL
  3. 验证下载:
# 验证KEY,每个账户在24小时内最多可进行1,000次直接下载(GeoLite账户限30次)
$ wget -S --method HEAD --user=YOUR_ACCOUNT_ID --password=YOUR_LICENSE_KEY 'https://download.maxmind.com/geoip/databases/GeoLite2-Country/download?suffix=tar.gz'

在输出中看到 HTTP/1.1 200 OKRemote file exists.就是成功。

  1. 成功后,就可以下载,解压后得到类似 GeoLite2-Country.mmdb 文件
wget -O <tar.gz文件存储路径> --user=YOUR_ACCOUNT_ID --password=YOUR_LICENSE_KEY 'https://download.maxmind.com/geoip/databases/GeoLite2-Country/download?suffix=tar.gz'
  1. 配置GoAccess:sudo vim /etc/goaccess/goaccess.conf
geoip-database /opt/GeoIP2/GeoLite2-Country/GeoLite2-Country.mmdb
#geoip-database /opt/GeoIP2/GeoLite2-City/GeoLite2-City.mmdb
geoip-database /opt/GeoIP2/GeoLite2-ASN/GeoLite2-ASN.mmdb
  1. 重新生成报告,就有地理位置信息了。

Nginx 日志变量与 GoAccess 格式符的对照表

以下是 Nginx 日志变量GoAccess 格式符的对照表,26/4/10 基于官方文档整理而成。

Nginx 日志变量GoAccess 格式符说明
客户端信息
$remote_addr%h客户端 IP 地址(支持 IPv4 和 IPv6)
$http_x_forwarded_for~h{, }从 X-Forwarded-For(XFF)请求头中解析客户端真实 IP,大括号内填写 IP 分隔符(常用, )
$remote_user%eHTTP 基本认证提供的用户名
$http_user_agent%u客户端 User-Agent 请求头
请求信息
$request%r完整的请求行(如 GET /index.html HTTP/1.1),需要使用分隔符(如引号)以便解析
$request_method%m请求方法(GET、POST 等)
$uri%U请求的 URL 路径
$query_string / $args%qURL 中的查询字符串参数
$server_protocol%H请求协议(如 HTTP/1.1)
$http_referer%RHTTP Referer 请求头,表示来源页面
响应信息
$status%s服务器返回的 HTTP 状态码
$body_bytes_sent%b返回给客户端的对象大小(响应体字节数,不含响应头)
时间信息
$time_local%d + %t本地时间,GoAccess 需配合 --date-format--time-format 使用。也可使用 %x 配合 --datetime-format
$time_iso8601%xISO 8601 标准格式的本地时间戳,通过%x匹配合并的日期时间字段
其他
$host%v虚拟主机名(服务器名称)
$request_time%T服务请求所花费的时间,单位为秒(含毫秒)
$upstream_cache_status%C缓存状态(如 MISS、BYPASS、EXPIRED、HIT 等)
$sent_http_content_type%M返回资源的 MIME 类型
$ssl_protocol%KSSL/TLS 协议版本(如 TLSv1.2)
$ssl_cipher%kSSL/TLS 加密套件

"$request"只能配置为"%r"

Q:日志变量 "$request" 的内容示例是 "GET /favicon.ico HTTP/1.1" 也就是在 goaccess 里 除了 "%r" 表示,还可以使用 "%m %U %H" 来表示 ?

A:在概念上是正确的,但在 实际使用 GoAccess 解析日志时,两者并不等价,因为它们对应的 日志文件中的字段数量不同。只有当你的 Nginx 日志格式本身定义的是三个独立的字段(例如 $request_method $uri $server_protocol)时,才能使用 %m %U %H

对比项%r%m %U %H
匹配的 Nginx 变量$request$request_method
$uri
$server_protocol
日志字段个数1 个字段3 个字段
日志内容示例"GET /favicon.ico HTTP/1.1"GET /favicon.ico HTTP/1.1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注