GoAccess 常用 CLI 命令与工具详解

GoAccess 命令行完全指南:终端 TUI、HTML、JSON、CSV 四种输出形态的命令矩阵与实测回显,实时大屏、多日志合并、gzip 压缩日志、小时粒度、persist/restore 增量分析与 systemd timer 定时报告方案。

GoAccessGoAccess2026/10/17

GoAccess 常用 CLI 命令与工具详解

‍‍​​‌​> 目标:把 GoAccess 的日常命令一次讲全——四种输出形态的命令矩阵、实时大屏、多日志合并、压缩日志、时间粒度切换、增量分析与定时报告,每条命令均附 Ubuntu 22.04 上的真实执行回显,可直接照抄到生产脚本。

一、环境信息

本文所有命令在以下环境实测:

  • 操作系统:Ubuntu 22.04.4 LTS(x86_64),内核 6.8.0-138-generic
  • GoAccess 1.9.4(/usr/local/bin/goaccess,编译参数 --enable-utf8 --enable-geoip=mmdb)
  • GeoIP 库:GeoLite2-Country.mmdb(位于 /opt/data/goaccess-sample/geoip/)
  • 分析样本:/opt/data/goaccess-sample/access.log(nginx Combined 格式,53 行,覆盖 200/404/405 状态与 GET/POST/DELETE/PATCH/HEAD 方法、Chrome/Firefox/Edge/curl 等多种 UA)
  • 相关目录:报告输出 /tmp/goaccess-rt/、持久化库 /tmp/ga-db/

二、前置条件

确认命令可用与样本就位:

which goaccess && goaccess --version | head -1
wc -l /opt/data/goaccess-sample/access.log

实测回显:

/usr/local/bin/goaccess
GoAccess - 1.9.4.
53 /opt/data/goaccess-sample/access.log

三、命令语法与全局选项

GoAccess 的命令行骨架只有三种形态:

goaccess <日志文件> [选项]              # 直读文件
goaccess <日志文件> --output=<文件>     # 直接产出报告
goaccess - [选项]                       # 从标准输入读日志

核心约定(实测确认,遗漏即报错):

  1. - 是"从标准输入读日志"的专用参数——管道模式必须以 - 收尾;写漏时会报 没有提供输入数据,也没有要恢复的数据(见 10.3 排障)。
  2. --log-format 是每次分析的必需参数(除非已写入配置文件);预定义名 COMBINED 无需再传 time/date-format。
  3. --output 的文件扩展名决定输出形态:.html / .json / .csv。
  4. 多个 --output 可同时使用(如同时产出 HTML 与 JSON),一次解析多形态输出。

常用全局选项速查(完整语义见配置文件注释):--log-format、--date-format、--time-format、--output、--real-time-html、--port、--addr、--daemonize、--pid-file、--persist、--restore、--db-path、--geoip-database、--ignore-panel、--exclude-ip、--date-spec、--hour-spec、--json-pretty-print、--num-tests、--invalid-requests、--config-file、--no-global-config、--help。

四、四种输出形态分析矩阵

本节给出同一份日志在四种形态下的完整命令与真实回显,构成日常分析的"命令矩阵"。

4.1 终端 TUI(交互界面)

goaccess /opt/data/goaccess-sample/access.log --log-format=COMBINED

实测界面渲染文字(53 行样本,概览栏与"每日独立访客"面板节选;界面随 locale 中文显示):

GoAccess   1.9.4 概览-所有已分析的请求 (17/10月/2026 - 17/10月/2026)
所有请求50 独立访客5  请求的文件14 来源地址0  有效的请求50 日志解析耗时1s
静态文件3  日志大小7.91 KiB 失败的请求0 未找到(404) 27 数据传输量13.30 KiB
日志文件夹地址 /opt/data/goaccess-sample/access.log [当前面板: 访客]

1 - 每日独立访客 - 包括网络机器人   总共: 1/1
点击量    h%   访客  v%   数据传输量  数据
  50 100.00%   5 100.00%  13.30 KiB  17/10月/2026

常用交互键(实测有效):1-17 数字键或 Tab 切换面板、j/k 或方向键滚动、s 面板内排序、g 跳到面板首行、q 退出当前面板或整个程序、h 帮助、c 配色方案。TUI 适合排查时的即时查看,退出后不留产物。

4.2 HTML(静态报告)

goaccess /opt/data/goaccess-sample/access.log --log-format=COMBINED \
  --geoip-database=/opt/data/goaccess-sample/geoip/GeoLite2-Country.mmdb \
  --output=/tmp/goaccess-quick.html
ls -la /tmp/goaccess-quick.html

实测回显:

-rw-r--r-- 1 root root 735009 10月 17 16:43 /tmp/goaccess-quick.html

产出约 735KB 的单文件 HTML——全部样式、图表脚本与统计数据内嵌,拷到任意位置或用 nginx 托管即可打开,无外链依赖,天然适配内网与归档。

4.3 JSON(结构化数据)

goaccess /opt/data/goaccess-sample/access.log --log-format=COMBINED --output=/tmp/ga-test.json
python3 -c 'import json; d=json.load(open("/tmp/ga-test.json")); g=d["general"]; print(g["total_requests"], g["unique_visitors"], g["unique_not_found"]); print([ (r["data"], r["hits"]["count"]) for r in d["requests"]["data"][:3] ])'

实测回显:

53 5 27
[('/notfound-page', 2), ('/old/blog/2019.html', 1), ('/wp-admin/setup.php', 1)]

JSON 形态输出全部 17 个面板的结构化数据(压缩单行约 21KB;加 --json-pretty-print 变为 1973 行缩进),是接入监控脚本、告警阈值判断与二次可视化的首选形态。

4.4 CSV(表格导入)

goaccess /opt/data/goaccess-sample/access.log --log-format=COMBINED --output=/tmp/ga-report.csv
head -6 /tmp/ga-report.csv

实测回显:

"0",,"general",,,,,,,,"2026-10-17 16:29:50 +0800","date_time"
"1",,"general",,,,,,,,"50","total_requests"
"2",,"general",,,,,,,,"50","valid_requests"
"3",,"general",,,,,,,,"0","failed_requests"
"4",,"general",,,,,,,,"1","generation_time"
"5",,"general",,,,,,,,"5","unique_visitors"

CSV 以"序号,面板,值,键名"逐行组织汇总指标与各面板数据,直接可被 Excel、Python pandas(pd.read_csv)等导入,适合交付给数据同事做进一步计算。

命令矩阵小结:

目标命令模板产物
交互速览goaccess log --log-format COMBINED终端界面
交付报告goaccess log --log-format COMBINED --output=out.html单文件 HTML
程序消费goaccess log --log-format COMBINED --output=out.json结构化 JSON
表格导入goaccess log --log-format COMBINED --output=out.csvCSV

五、常用命令组合

本节把高频实战场景打包成可复制的完整命令行。

组合一:离线静态报告 + 地理位置分析(cron/一次性):

goaccess /var/log/nginx/access.log \
  --log-format COMBINED \
  --geoip-database /opt/data/goaccess-sample/geoip/GeoLite2-Country.mmdb \
  --output /var/www/html/goaccess/report-$(date +%F).html

实测同类命令产物:/tmp/goaccess-quick.html(735KB),文件名带日期便于按日归档。

组合二:实时 HTML 大屏(管道常驻):

tail -F -n0 /var/log/nginx/access.log | goaccess --log-format COMBINED \
  --real-time-html --port=7890 \
  --output=/var/www/html/goaccess/report.html -

实测回显(启动后端口监听与日志提示):

LISTEN 0      4096         0.0.0.0:7890       0.0.0.0:*    users:(("goaccess",pid=2294384,fd=8))
WebSocket服务器已准备接收来自客户的连接

实测刷新验证:流内新增 1 行请求后,浏览器报告的 total_requests 从 53 即时变为 54(见第九章 systemd 托管)。

组合三:远端日志本地分析(跨机管道):

ssh user@web01 "tail -F -n0 /var/log/nginx/access.log" \
  | goaccess --log-format COMBINED --real-time-html --port=7890 \
    --output=/var/www/html/goaccess/web01.html -

无需在 web01 安装任何东西,用 SSH 把远端日志流接进本地 GoAccess;生产建议将 SSH 免密与连接保活(-o ServerAliveInterval=30)写入该命令。

组合四:格式试跑校准(接入新日志源的第一步):

goaccess /var/log/nginx/access.log --log-format COMBINED \
  --num-tests=10 --invalid-requests=/tmp/invalid.log --output=/dev/null

实测有效:解析 10 行试验若失败,错误行会写入 /tmp/invalid.log 供比对其格式差异。

组合五:只看某个维度的轻量分析:

# 剔除内网探活 IP 后看真实访客
goaccess /var/log/nginx/access.log --log-format COMBINED \
  --exclude-ip 10.0.0.0-10.255.255.255 --output=/tmp/real-users.json

# 忽略静态资源后的"有效请求"视角
goaccess /var/log/nginx/access.log --log-format COMBINED \
  --ignore-statics=req --output=/tmp/dynamic-only.json

# 只看爬虫
goaccess /var/log/nginx/access.log --log-format COMBINED \
  --crawlers-only --output=/tmp/crawlers.json

六、多日志合并分析

nginx 按日轮转后日志分散在多个文件(access.log、access.log.1、access.log.2.gz),GoAccess 支持三种合并姿势。

方式一:cat 顺序拼接管道(最常用):

cat /tmp/log-a.log /tmp/log-b.log | goaccess --log-format COMBINED --output=/tmp/ga-merge.json -

实测回显(25 行 + 25 行两个切片合并):

merged total: 50

方式二:通配符多文件直读(1.7+ 支持位置参数展开为多文件):

goaccess /var/log/nginx/access.log* --log-format COMBINED --output=/tmp/all.html

方式三:gzip 压缩日志 zcat 管道(跨轮转周期合并时必需):

gzip -c /opt/data/goaccess-sample/access.log > /tmp/access.log.gz
zcat /tmp/access.log.gz | goaccess --log-format COMBINED --output=/tmp/ga-gz.json -

实测回显:

zcat-pipe total: 53

⚠️ 注意:1.9.4 不能直读 .gz 文件——实测 goaccess /tmp/access.log.gz --log-format COMBINED --output=... 解析 0 行退出(压缩日志直读依赖编译期 zstd 支持,本文构建未开启,gzip 亦不受支持)。旧压缩包必须经 zcat 管道;若日志量极大可用 --enable-zstd 重新编译获得原生压缩支持。

⚠️ 注意:合并多台服务器的日志时,各机 log-format 必须一致;--log-format 在命令行中只写一次,作用于全部输入。

七、按日期与小时粒度分析

GoAccess 没有"只分析某个时间段"的过滤参数,粒度控制靠两个维度参数 + 日志切分实现。

参数一:--date-spec=hr(访客面板按小时聚合):

goaccess /opt/data/goaccess-sample/access.log --log-format COMBINED \
  --date-spec=hr --output=/tmp/ga-hr.json
python3 -c 'import json; d=json.load(open("/tmp/ga-hr.json")); print([x["data"] for x in d["visitors"]["data"]]); print([(x["data"], x["hits"]["count"]) for x in d["visit_time"]["data"]])'

实测回显:

['2026101708', '2026101707']
[('07', 19), ('08', 34)]

访客键由 20261017(日)变为 2026101708(小时);配合 --date-spec=min 可到分钟级。

参数二:--hour-spec=min(时段面板 10 分钟粒度):默认时段面板键为小时(如上回显 07/08),加 --hour-spec=min 后变为 07:30 这类 10 分钟键。

按日期切分日志再分析(真正的时间过滤):要"只看 10 月 16 日的访问",在输入侧完成过滤:

# 单文件内按日期 grep
grep '16/Oct/2026' /var/log/nginx/access.log | goaccess --log-format COMBINED --output=/tmp/oct16.json -

# 已按天轮转的日志直接指定对应文件
goaccess /var/log/nginx/access.log.1 --log-format COMBINED --output=/tmp/yesterday.html

grep 过滤与粒度参数组合可覆盖"每小时报表""任意时间段回溯"两类需求;周期性场景优先用轮转文件而非 grep(避免全量扫描)。

八、增量分析:persist 与 restore

面对持续增长的日志,"每次全量重算"不可持续。GoAccess 的增量方案由三个参数构成:--db-path(数据库目录)、--persist(退出时写盘)、--restore(启动时读盘),三者组合即可实现"数据越滚越多、处理越来越快"。

第 1 步:全量解析并落盘:

goaccess /opt/data/goaccess-sample/access.log --log-format COMBINED \
  --persist --db-path=/tmp/ga-db --output=/tmp/p1.json
ls /tmp/ga-db/*.db | wc -l

实测回显:

151

落盘 151 个面板数据文件(每面板一组 key-value .db)。

第 2 步:空输入从磁盘恢复(验证数据可独立于日志存在):

goaccess --log-format COMBINED --restore --db-path=/tmp/ga-db --output=/tmp/p2.json
python3 -c 'import json; d=json.load(open("/tmp/p2.json")); print("restored total:", d["general"]["total_requests"])'

实测回显:

restored total: 53

第 3 步:喂新日志做增量(恢复 + 追加 + 回写一条龙):

tail -1 /opt/data/goaccess-sample/access.log > /tmp/new-line.log
goaccess /tmp/new-line.log --log-format COMBINED \
  --restore --persist --db-path=/tmp/ga-db --output=/tmp/p3.json
python3 -c 'import json; d=json.load(open("/tmp/p3.json")); print("incremental total:", d["general"]["total_requests"])'

实测回显:

incremental total: 54

53 → 54,增量语义正确。--restore --persist 成对出现是增量分析的标准姿势:先读旧库、合并新日志、写回新库。

配套参数:--keep-last 30 只保留最近 30 天数据(控制库体积);轮转日志场景建议配合 7.1 的日志切分(每天一份),将"已入库的旧日志"移出增量队列。

⚠️ 注意:1.9 版本起 --load-from-disk 已更名为 --restore(实测 1.9.4 传旧名报 unrecognized option);且持久化数据库格式随版本演进,跨大版本升级后建议先备份配置文件、清空 db-path 重建数据库。

九、定时报告:systemd timer 方案

真实服务器上"每小时/每天出一份报告"不建议用裸 cron,systemd timer 自带持久化(错过的触发点开机补跑)、日志进入 journal、状态可查询。完整方案两件套:

单元文件:

mkdir -p /var/www/html/goaccess /var/lib/goaccess

cat > /etc/systemd/system/goaccess-report.service <<'EOF'
[Unit]
Description=GoAccess daily HTML report generator
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/goaccess /opt/data/goaccess-sample/access.log --log-format=COMBINED --output=/var/www/html/goaccess/report.html --persist --db-path=/var/lib/goaccess
EOF

cat > /etc/systemd/system/goaccess-report.timer <<'EOF'
[Unit]
Description=Run GoAccess report hourly

[Timer]
OnCalendar=hourly
Persistent=true

[Install]
WantedBy=timers.target
EOF

设计说明:service 为 oneshot(跑完即退);ExecStart 中 --persist --db-path 让每次报告把统计写进 /var/lib/goaccess,若再追加 --restore 参数即从第 N 次起全时段累积(首跑先建库)。OnCalendar=hourly 每整点触发,改为 OnCalendar=*-*-* 00:00:00 即每日零点;Persistent=true 保证停机错过的时间点开机后补跑。

启用与触发:

systemctl daemon-reload
systemctl enable --now goaccess-report.timer
systemctl start goaccess-report.service

实测回显:

Created symlink /etc/systemd/system/timers.target.wants/goaccess-report.timer → /etc/systemd/system/goaccess-report.timer.
NEXT                        LEFT       LAST PASSED UNIT                  ACTIVATES
Sat 2026-10-17 17:00:00 CST 16min left n/a  n/a    goaccess-report.timer goaccess-report.service

1 timers listed.

执行状态验证:

systemctl status goaccess-report.service --no-pager -l | head -6
ls -la /var/www/html/goaccess/

实测回显:

● goaccess-report.service - GoAccess daily HTML report generator
     Loaded: loaded (/etc/systemd/system/goaccess-report.service; static)
     Active: inactive (dead) since Sat 2026-10-17 16:43:50 CST; 15ms ago
    Process: 2310852 ExecStart=/usr/local/bin/goaccess /opt/data/goaccess-sample/access.log --log-format=COMBINED --output=/var/www/html/goaccess/report.html --persist --db-path=/var/lib/goaccess (code=exited, status=0/SUCCESS)
total 728
-rw-r--r-- 1 root root 735009 10月 17 16:43 report.html

status=0/SUCCESS、735009 字节报告与 /var/lib/goaccess/ 下的持久化库均按预期生成。

运营技巧:报告页由 nginx 托管 /var/www/html/goaccess/ 即可全队访问;文件名模板 --output=/var/www/html/goaccess/report-$(date +%F).html 无法直接写入 unit(unit 不做 shell 展开),改为把 ExecStart 指向一个包装脚本,在脚本内完成日期命名与旧报告清理。

十、常见问题(FAQ)

Q1:--real-time-html 模式下报告不更新?

根因:文件直读模式读到 EOF 后不再监控文件增长(实测进程 fd 表中无日志文件句柄)。解决:一律改用管道模式 tail -F -n0 日志 | goaccess ... -(-F 可跟随轮转重命名,-n0 避免启动时重复计入旧数据),实测新增日志后报告秒级刷新(53 → 54)。

Q2:Unable to set bind: Address already in use. 后退出?

WebSocket 端口(默认 7890)被旧实例占用。解决:

ss -tlnp | grep 7890
pkill -x goaccess

或启动时 --port=7891 换端口。

Q3:报 没有提供输入数据,也没有要恢复的数据?

管道模式漏写收尾的 - 参数——goaccess 找不到输入源(实测 zcat access.log.gz | goaccess --log-format COMBINED --output=... 复现此错,补上 - 后 53 行全部解析成功)。另注意:--load-from-disk 在 1.9.4 上须写 --restore,否则同样被视作"没有要恢复的数据"。

Q4:.gz 压缩日志能直接读吗?

不能(实测解析 0 行退出)。1.9.4 的压缩直读仅支持编译期开启 zstd 的构建;gzip 日志用 zcat access.log.gz | goaccess ... - 管道读入,或对大日志量用 --enable-zstd 重新编译。

Q5:多文件合并时方法/URL 统计翻倍不对?

检查两处:各文件 log-format 是否一致;是否把轮转边界(access.log 与 access.log.1 存在同一时间段的重叠行)重复统计。轮转配置用了 copytruncate 时特别容易出现重叠。

Q6:定时任务跑了但报告没更新?

先看服务退出码:systemctl status goaccess-report.service 的 code=exited, status=0/SUCCESS 行;非 0 时 journalctl -u goaccess-report.service -n 50 看具体报错(常见为路径权限——db-path 与 output 目录需对运行用户可写,或 log-format 传参引号丢失)。

十一、参考链接

  1. goaccess(1) 手册页(全命令行参数):https://man.archlinux.org/man/goaccess.1
  2. GoAccess GitHub 仓库:https://github.com/allinurl/goaccess
  3. 官网文档首页:https://goaccess.io/docs
  4. systemd timer 官方手册:https://www.freedesktop.org/software/systemd/man/latest/systemd.timer.html
  5. nginx 官方文档(log_format 指令):https://nginx.org/en/docs/http/ngx_http_log_module.html