GoatCounter 2.7.0 常用 CLI 命令与工具详解

GoatCounter 2.7.0 常用 CLI 命令与工具详解:db/import/dashboard/monitor/serve 等子命令逐条实测回显,含权限位、迁移与排障实录。

GoatCounter自托管GoSQLite监控LinuxGoatCounter2026/10/30

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

二、工具概览

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 界面标签
count2Recording pageviews(计点上数)
export4Creating exports
site_read8Read sites
site_create16Create sites
site_update32Update 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 与 sha256 hash 字段)。导出受 -ratelimit export:1/3600 限流(默认每小时一次)。

六、注意事项

  1. 聚合与明细是两回事:仪表盘与 hit_counts 等聚合表始终写入;hits 明细表默认不写(站点 collect 位不含 256),CSV 导出为空先查这里(实测与处理过程见配置篇第六章)。
  2. 机器人自动分流:curl 等客户端 UA 会被识别为 bot 进 bots 表,不进统计——用 curl 验证埋点时看到"没数据"先换浏览器 UA 复测(实测:同一路径 curl UA 计入 bots、Chrome UA 计入 hits)。
  3. 落库延迟:-store-every 默认 10 秒批量写,脚本化"发访问→立刻查库"会得到空结果(实测踩点),至少等待一个周期。
  4. db query 无权限墙:直通库文件可改删任何数据,生产机避免在共享 shell 历史/脚本中硬编码危险语句;操作前备份。
  5. 令牌是敏感凭据:本文出现的令牌均为演示环境临时生成;真实环境的 GOATCOUNTER_API_KEY 建议放 systemd EnvironmentFile= 或运维密管,不进命令历史。
  6. 退出码语义:monitor 0=有访问/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 就绪再下载回灌。

八、参考链接