GoatCounter 2.7.0 常用 CLI 命令与工具详解
GoatCounter 2.7.0 常用 CLI 命令与工具详解:db/import/dashboard/monitor/serve 等子命令逐条实测回显,含权限位、迁移与排障实录。
GoatCounter 2.7.0 常用 CLI 命令与工具详解
目标:把 GoatCounter v2.7.0 命令行工具的每个子命令(help/version/serve/db/import/dashboard/monitor)讲清并配实测回显,覆盖建站、令牌、迁移、建库、SQL 查询、日志导入、终端看板与可用性巡检的完整运维闭环。文中全部命令与输出均在 Ubuntu 24.04.5 LTS + v2.7.0 环境逐条实测取得,可直接照抄执行。
一、环境信息
- 操作系统:Ubuntu 24.04.5 LTS(x86_64),语言环境默认 C/UTC
- GoatCounter:v2.7.0 官方预编译二进制,
/usr/local/bin/goatcounter;goatcounter version实测:
version=v2.7.0; go=go1.25.5; GOOS=linux; GOARCH=amd64; race=false; cgo=true
- 数据库:SQLite(
/var/lib/goatcounter/db.sqlite3,运行用户goatcounter)为主;另附 PostgreSQL 16.15 实验环境(库名goatcounter,连接串见 5.8 节) - 站点:
stats.example.com(vhost),服务由 systemd 托管、监听:8135(安装与托管见《Ubuntu 24.04 安装 GoatCounter 2.7.0 指南》,参数语义见《GoatCounter 2.7.0 配置参数详解》) - 服务运行中:
systemctl is-active goatcounter实测active
二、工具概览
goatcounter help 实测全文如下——v2.7.0 的 CLI 由 7 个命令与 3 个帮助主题组成:
Usage: goatcounter [command] [flags]
GoatCounter is a web analytics platform. https://github.com/arp242/goatcounter
Use "help <topic>" or "cmd -h" for more details for a command or topic.
Commands:
help Show help; use "help <topic>" or "help all" for more details.
version Show version and build information and exit.
serve Start HTTP server.
import Import pageviews from an export or logfile.
dashboard Show dashboard statistics in the terminal.
db Modify the database and print database info.
monitor Monitor for pageviews.
Extra help topics:
listen Detailed documentation on -listen and -tls flags.
logfile Documentation on importing from logfiles.
debug List of modules accepted by the -debug flag.
要点解读:
- 建站、令牌、迁移、建库、SQL 查询全部收在
db一个命令之下(db create/show/update/delete/newdb/migrate/schema-sqlite/schema-pgsql/test/query)。旧版本的独立create_site、export、query命令在 v2.7.0 中不再是顶层命令:建站用db create site,导出走 Web API(见 5.9 节),通用查询用db query。 help all输出全部帮助(实测 918 行),是离线环境下最完整的操作手册。- 除
serve常驻外,其余命令都是一次性执行;import/dashboard不直连数据库,而是调用 HTTP API(需GOATCOUNTER_API_KEY)。
三、前置条件
- 已安装 v2.7.0 二进制并完成首次建站(本文所有
db示例显式带-db sqlite+/var/lib/goatcounter/db.sqlite3,不依赖工作目录)。 import/dashboard需要一个 API 令牌(5.3 节创建),并以环境变量提供:export GOATCOUNTER_API_KEY=<令牌>。- 直接对生产库做写操作(create/update/delete/query)前建议先备份:
cp /var/lib/goatcounter/db.sqlite3 /var/lib/goatcounter/db.sqlite3.bak(SQLite 文件级备份需在服务停写或使用 sqlite3.backup,见安装篇)。
四、version 与 help
version:显示版本与构建信息;-json 输出 JSON(脚本判断版本用)。实测:
$ goatcounter version
version=v2.7.0; go=go1.25.5; GOOS=linux; GOARCH=amd64; race=false; cgo=true
$ goatcounter version -json
{
"GOARCH": "amd64",
"GOOS": "linux",
"cgo": true,
"go": "go1.25.5",
"race": false,
"version": "v2.7.0"
}
help:goatcounter help(总览,见第二章)、goatcounter help serve|db|import|dashboard|monitor|listen|logfile|debug(分主题)、goatcounter help all(全文)。每个命令也接受 -h,如 goatcounter serve -h 直接列出 serve 全部旗标。
五、各命令详解
5.1 db create site:建站与管理员
新装后第一件事。-vhost 是站点对外域名(仪表盘按它路由),-user.email 是登录账号,-user.password 缺省时交互询问。实测(创建安装篇所用的站点):
goatcounter db create site \
-db sqlite+/var/lib/goatcounter/db.sqlite3 -createdb \
-vhost stats.example.com \
-user.email admin@example.com \
-user.password q1w2e3r4
实测回显:命令成功无输出(echo $? 为 0),同时生成库文件:
$ ls -la /var/lib/goatcounter/
-rw-r--r-- 1 goatcounter goatcounter 507904 Oct 29 14:17 db.sqlite3
验证:db show site(下节)或浏览器访问 http://stats.example.com:8135/,未登录时跳转登录页(实测 303 → /user/new,表单标题实测 "Sign in at stats.example.com")。
-link 多站点:单实例托管第二个站点并复用用户/设置,用 -link 指向已有站点(ID 或 vhost)。实测:
goatcounter db create site \
-db sqlite+/var/lib/goatcounter/db.sqlite3 \
-vhost blog.example.com -link 1
实测创建成功(exit=0),db show site -find blog.example.com 显示 site_id 2、parent 1,且 collect 设置(446)自动继承自主站——省去逐站重配。
5.2 db show / update / delete:查改删行
三个命令作用于三张管理表:site、user、apitoken。-find 支持数字 ID 或友好名(site 用 vhost、user 用邮箱、apitoken 用令牌串);-format 支持 table/vertical(默认)/csv/json/html。实测:
$ goatcounter db show site -db sqlite+/var/lib/goatcounter/db.sqlite3 -find 1
site_id 1
parent NULL
code serve-1cwqr6x8i0d05
cname stats.example.com
cname_setup_at 2026-10-29 14:17:39
settings {"public":"private",...,"collect":190,...}
received_data 0
state a
created_at 2026-10-29 14:17:39
(输出节选:settings/user_defaults 两列为超长 JSON,此处截断)
$ goatcounter db show apitoken -db sqlite+/var/lib/goatcounter/db.sqlite3 -find 1 -format csv
api_token_id,site_id,user_id,name,token,permissions,created_at,last_used_at,sites
1,1,1,cli-demo,1ulw9cuefre8m1pc69y1hkvk4u1fk1lxn4avmqs12mfroy08qftx,62,2026-10-29 14:20:56,2026-10-29 14:21:14,[1]
update 同旗标、多一个 -find 定位(如改站点域名:db update site -find 1 -vhost stats2.example.com,改后需重启服务清缓存——官方帮助注明部分修改因缓存需重启生效)。delete 加 -force 才能删最后一个管理员等受保护对象。
5.3 db create apitoken:创建 API 令牌
import/dashboard 与 REST API 都要用令牌。实测:
goatcounter db create apitoken \
-db sqlite+/var/lib/goatcounter/db.sqlite3 \
-user 1 -name "cli-demo" \
-perm "count,export,site_read,site_create,site_update"
成功无输出;db show apitoken -find 1 可见 48 位令牌串。权限位实测标定(逐项创建后查 permissions 值):
| -perm 值 | 位值 | Web 界面标签 |
|---|---|---|
| count | 2 | Recording pageviews(计点上数) |
| export | 4 | Creating exports |
| site_read | 8 | Read sites |
| site_create | 16 | Create sites |
| site_update | 32 | Update sites |
注意:Web 界面还有第 6 个权限 "Read statistics"(位值 64),-perm 不接受它(实测报 -perm: invalid value "stats_read")。dashboard 命令需要 site_read(8)+64 两个权限,因此纯 CLI 建的令牌跑 dashboard 会报权限不足(实测:goatcounter: API token "cli-demo" is missing the required permissions)。解决办法:Web 界面 → 用户菜单 → API 手工勾选全部权限建一个 127 位掩码令牌(实测建得 full-key,permissions=127,dashboard 随即可用)。用浏览器建令牌时表单字段名为 permissions[],值即上表位值。
5.4 db migrate / newdb / test:建库与迁移
db migrate 管理数据库结构版本。三个特殊位置参数实测:
$ goatcounter db migrate list -db sqlite+/var/lib/goatcounter/db.sqlite3
2021-04-01-1-store-warn
2021-04-07-1-billing-anchor
2021-06-27-1-public
2021-12-02-1-languages
2021-12-02-2-language-enable
(输出节选:共 31 行,已执行的平铺列出)
$ goatcounter db migrate pending -db sqlite+/var/lib/goatcounter/db.sqlite3
no pending migrations
$ echo $?
0
db migrate all 执行全部待执行迁移;升级二进制后跑一次即可,或让 serve -automigrate 代劳(配置篇 5.6 节)。-show 只打印 SQL 不执行,-test 跑完回滚(验证迁移可执行性)。
db newdb 新建空库(含完整 schema),实测:
$ goatcounter db newdb -db sqlite+/tmp/newdb.sqlite3
$ echo $?
0
db test 检查库是否存在可用,实测三种结果:
$ goatcounter db test -db sqlite+/tmp/newdb.sqlite3
DB at "sqlite+/tmp/newdb.sqlite3" seems okay; sqlite3 version 3.50.4
$ echo $?
0
$ GOATCOUNTER_DB="sqlite+/tmp/envtest.sqlite3" goatcounter db test
goatcounter: zdb.Connect: sqlite3 database "/tmp/envtest.sqlite3" doesn't exist (from connection string "sqlite3:file:/tmp/envtest.sqlite3?...")
$ echo $?
1
内置帮助声明"库不存在退出码为 2",实测 v2.7.0 该场景退出码为 1——写自动化脚本时以实测值为准(或直接判断输出文本)。
5.5 db schema-sqlite / schema-pgsql:导出建表 DDL
打印编译在二进制内的完整建表 SQL(v2.7.0 SQLite schema 实测 358 行),用于手工建库、审库或迁移评估。实测查看某张表结构:
$ goatcounter db schema-sqlite -db sqlite+/var/lib/goatcounter/db.sqlite3 | sed -n '/create table hits/,/);/p'
create table hits (
hit_id integer primary key autoincrement,
site_id integer not null,
path_id integer not null,
ref_id integer not null default 1,
session blob default null,
first_visit integer default 0,
browser_id integer not null,
system_id integer not null,
campaign integer default null,
width smallint null,
location varchar not null default '',
language varchar,
created_at timestamp not null check(created_at = strftime('%Y-%m-%d %H:%M:%S', created_at))
);
读库时注意关联键:hits.path_id → paths.path_id、hits.browser_id → browsers.browser_id(表主键带表名前缀,不是 id)。
5.6 db query:直接跑 SQL
无限制直通数据库的 SQL 执行器(官方警示:"this is unrestricted and can modify or delete anything, so use with care"),适合没有 sqlite3/psql 客户端的机器。-format 支持 table/vertical/csv/json/html 与 exec(执行不回显,批量 DDL 用)。实测(统计各路径命中数,注意主键列名带前缀):
$ goatcounter db query -db sqlite+/var/lib/goatcounter/db.sqlite3 \
"select p.path, count(*) as n from hits h join paths p on p.path_id=h.path_id group by p.path order by n desc"
path n
/persist-test 3
/nginx-page 1
/blog/post-1 1
聚合统计表同样可查(仪表盘的数据源):
$ goatcounter db query -db sqlite+/var/lib/goatcounter/db.sqlite3 \
"select path_id, hour, total from hit_counts order by path_id"
path_id hour total
1 2026-10-29 14:00:00 1
2 2026-10-29 14:00:00 1
3 2026-10-29 14:00:00 1
排障实录:内置帮助声明 db query 支持四个特殊值(ua/bots/unknown-ua/screensize,返回 UA 与屏幕尺寸汇总),实测 v2.7.0 这些值被当作 SQL 直接执行并报错:
$ goatcounter db query -db sqlite+/var/lib/goatcounter/db.sqlite3 "ua"
zdb.Query: near "ua": syntax error
即该帮助文本在 v2.7.0 属遗留文档、功能未实现;等价需求可用标准 SQL 联表自行实现(如上文 UA 分布查询)。此差异已实测确认,勿按帮助照抄。
5.7 import:导入历史访问与日志
import 不直写数据库,而是调用站点 HTTP API 上数(与页面埋点同一条链路),因此需要 GOATCOUNTER_API_KEY(需 count 权限)与 -site 指向站点。支持 GoatCounter CSV 导出件回灌与多种 Web 日志格式。实测一:回灌导出 CSV:
$ export GOATCOUNTER_API_KEY=<令牌>
$ goatcounter import -site http://stats.example.com:8135 /tmp/export4.csv.gz
14:29 INFO import: import started
site = 0
replace = false
Imported 1 rows14:29 INFO import: imported 1 rows
site = 0
replace = false
(输出节选:INFO 块为多行结构化日志,Imported N rows 为进度行)
实测二:导入 nginx Combined 格式日志(-format combined;样例日志两条 200 请求):
goatcounter import -site http://stats.example.com:8135 -format combined /tmp/access.log
导入后实测 db query 验证,两条日志已成为命中(/nginx-page、/blog/post-1 各 1 次,Firefox/Safari 正确解析进 browsers 表)。
常用旗标(help import 实测要点):
-format:csv(默认,GoatCounter 导出件)、combined、combined-vhost、common、common-vhost、bunny(Bunny CDN)、caddy(Caddy JSON)、log:[fmt](自定义格式,占位符语法见goatcounter help logfile)。-follow:持续 tail 日志文件(goatcounter import -site=... -follow /var/log/nginx/access.log),只处理新增行。-exclude:默认-exclude static -exclude redirect(静态资源与 3xx 跳转不入库),可用 glob/正则自定义,-exclude=''关闭全部排除。- 大文件导入前按官方建议临时放宽限流:
goatcounter serve -ratelimit api-count:1000/1。
5.8 dashboard:终端版仪表盘
免开浏览器在终端看统计,走 API(需 site_read + Read statistics 权限,见 5.3 节的令牌说明)。实测(最近 7 天):
$ export GOATCOUNTER_API_KEY=<127 位全权限令牌>
$ goatcounter dashboard -site http://stats.example.com:8135 -range 7
1 week ago–Today – 3 of 3 visits shown
┌────────────────────────────────────────────────┬──────────────────────────────┐
│ Pages │ Browsers │
│ 1 /docs/install │ Chrome 100% │
│ Demo │ │
│ 1 /about │ Systems │
│ Demo │ Linux 100% │
│ 1 /hello │ Sizes │
│ Demo │ (unknown) 0% │
│ Toprefs │ (unknown) 0% │
│ (unknown) 100% │ ... │
└────────────────────────────────────────────────┴──────────────────────────────┘
(输出节选:完整框线图含 Locations/Languages/Campaigns 面板)
-range 实测两种写法均可:天数(-range 7)与显式区间(-range "2026-10-01:2026-10-31",实测输出标题 "October – 10 of 10 visits shown")。
5.9 monitor:可用性巡检
按周期检查"最近 N 秒是否有页面访问",没有则报错并给非零退出码——直接可接 cron/systemd timer 做埋点断流告警。实测正例(120 秒窗口内有 3 条命中):
$ goatcounter monitor -db sqlite+/var/lib/goatcounter/db.sqlite3 -once
14:29 INFO monitor: 3 hits in last 120 seconds
module = monitor
location = zgo.at/goatcounter/v2/cmd/goatcounter/monitor.go:85
$ echo $?
0
实测反例(窗口内无访问):
$ goatcounter monitor -db sqlite+/var/lib/goatcounter/db.sqlite3 -once
14:21 ERROR monitor: no hits in last 120 seconds
...(stacktrace 块)
goatcounter: no hits in last 120 seconds
$ echo $?
1
参数:-period(默认 120 秒窗口与循环间隔)、-once(查一次就退)、-site(只看某站点,加速查询)。注意 monitor 查的是已落库的命中,-store-every(默认 10 秒)内的数据尚未入库,巡检窗口不要太小。
5.10 serve 与导出:两点提示
serve是常驻服务命令,旗标全集与生产模板见《GoatCounter 2.7.0 配置参数详解》第五、七章;日常用 systemd 托管(systemctl restart goatcounter)而非裸跑。- v2.7.0 没有顶层
export命令:导出走 Web API(需 export 权限令牌)。实测三步:POST /api/v0/export(返回含id的任务对象,后台生成)→GET /api/v0/export/<id>(num_rows/finished_at就绪后)→GET /api/v0/export/<id>/download下载csv.gz(实测回显含"num_rows": 1与 sha256hash字段)。导出受-ratelimit export:1/3600限流(默认每小时一次)。
六、注意事项
- 聚合与明细是两回事:仪表盘与
hit_counts等聚合表始终写入;hits明细表默认不写(站点collect位不含 256),CSV 导出为空先查这里(实测与处理过程见配置篇第六章)。 - 机器人自动分流:curl 等客户端 UA 会被识别为 bot 进
bots表,不进统计——用 curl 验证埋点时看到"没数据"先换浏览器 UA 复测(实测:同一路径 curl UA 计入 bots、Chrome UA 计入 hits)。 - 落库延迟:
-store-every默认 10 秒批量写,脚本化"发访问→立刻查库"会得到空结果(实测踩点),至少等待一个周期。 db query无权限墙:直通库文件可改删任何数据,生产机避免在共享 shell 历史/脚本中硬编码危险语句;操作前备份。- 令牌是敏感凭据:本文出现的令牌均为演示环境临时生成;真实环境的
GOATCOUNTER_API_KEY建议放 systemdEnvironmentFile=或运维密管,不进命令历史。 - 退出码语义:
monitor0=有访问/1=无访问/2=其他错误;db test实测"库不存在"为 1(帮助写 2,以实测为准);migrate pending有待执行迁移时退出 1。
七、常见问题
Q1:db create site 报 "zdb.Connect: sqlite3 database ... doesn't exist"。
除 serve 外的命令建库都要显式加 -createdb(防误操作新库的官方设计)。加 -createdb 重跑即可(实测通过)。
Q2:dashboard 报 "API token ... is missing the required permissions"。
CLI 建的令牌给不了 "Read statistics"(位 64)权限。按 5.3 节在 Web 界面勾选全部权限重建令牌(实测 127 位掩码后可用)。
Q3:db query "ua" 报 syntax error。
帮助中的特殊值(ua/bots/screensize/unknown-ua)在 v2.7.0 未实现,会被当 SQL 执行(实测复现)。改用标准 SQL 联表查询。
Q4:import 导入的历史日志报 "created_at: in the future."。 日志时间戳晚于服务器当前时间会被整行拒绝(实测:服务器时钟 14:24 时导入 14:30 的行报错、改 14:00 的行成功)。校准日志时间或系统时钟后重导。
Q5:import 回灌导出 CSV 报 "goatcounter: goatcounter.Import: EOF" 或 "could not read as gzip"。
导出文件本身是空的(num_rows=0,明细未开启所致)或下载不完整。先按注意事项 1 开启明细、确认导出任务 finished_at 就绪再下载回灌。
八、参考链接
- v2.7.0 内置帮助:
goatcounter help/help all/help db/help logfile/help debug(本文回显即实测原文) - 官方仓库与 API 文档:https://github.com/arp242/goatcounter、https://www.goatcounter.com/help/api
- 站内相关:《Ubuntu 24.04 安装 GoatCounter 2.7.0 指南》、《GoatCounter 2.7.0 配置参数详解》、《GoatCounter 介绍与选型指南》