Add usage telemetry to clickhousectl
Default-on telemetry with first-run notice and easy opt-out, to measure local/offline adoption. Consent model follows Homebrew: nothing is ever sent before the notice has been shown.
Consent & state
- State lives in
telemetry.json in the existing config dir, single key: {"disabled": false}. The file doubles as the first-run marker.
- First run (file absent): print notice, write file, send nothing, continue as normal.
- Subsequent runs:
disabled: false → send; disabled: true → fully silent.
DO_NOT_TRACK env var (donottrack.sh spec) is checked first and overrides everything: no notice, no file write, no send. If later unset and no file exists, the first-run flow applies then.
- Config dir unwritable → fail open to disabled: no send, no error, no repeated notice. We only send if we successfully recorded that the notice was shown.
- Notice prints to stderr (stdout stays machine-parseable), regardless of TTY — otherwise agent/non-interactive usage never triggers the notice and is never measured.
clickhousectl telemetry disable|enable|status subcommand toggles the file; this is what the notice references.
Notice content
Four things only: what's collected (command + flag names, never values), why, both off switches (clickhousectl telemetry disable, DO_NOT_TRACK=1), docs URL.
Payload
- Command path (e.g.
local start)
- Flag names only — never flag values, never positional args. Build payload from clap definitions, not
env::args(), so leaking values is structurally impossible. Document this.
- Exit success/failure
- Agent detection via existing
is-ai-agent
- CI boolean (
CI env var) so pipelines can be filtered from adoption numbers
- chctl version
- os/arch
No install ID, no device ID, no fingerprinting, etc.
Transport
- Detached child process: parent exits immediately; child fires one POST with 1–2s timeout, all stdio nulled, dies silently on any failure. Zero latency impact, zero disk writes.
- Telemetry is forwarded to a clickhouse.com address served via Cloudflare.
Transparency
CHCTL_TELEMETRY_DEBUG=1 → print exact payload to stderr, send nothing.
- Public docs page: what's collected, why, retention, all opt-out methods. Publish before release; announce in changelog.
- Build-time cargo feature flag to compile telemetry out entirely (for distro packagers).
Acceptance criteria
Add usage telemetry to clickhousectl
Default-on telemetry with first-run notice and easy opt-out, to measure local/offline adoption. Consent model follows Homebrew: nothing is ever sent before the notice has been shown.
Consent & state
telemetry.jsonin the existing config dir, single key:{"disabled": false}. The file doubles as the first-run marker.disabled: false→ send;disabled: true→ fully silent.DO_NOT_TRACKenv var (donottrack.sh spec) is checked first and overrides everything: no notice, no file write, no send. If later unset and no file exists, the first-run flow applies then.clickhousectl telemetry disable|enable|statussubcommand toggles the file; this is what the notice references.Notice content
Four things only: what's collected (command + flag names, never values), why, both off switches (
clickhousectl telemetry disable,DO_NOT_TRACK=1), docs URL.Payload
local start)env::args(), so leaking values is structurally impossible. Document this.is-ai-agentCIenv var) so pipelines can be filtered from adoption numbersNo install ID, no device ID, no fingerprinting, etc.
Transport
Transparency
CHCTL_TELEMETRY_DEBUG=1→ print exact payload to stderr, send nothing.Acceptance criteria
telemetry.jsonDO_NOT_TRACK=1→ fully silent, nothing written or senttelemetry disable/enable/statusworks and persists