Documentation
¶
Overview ¶
Package telemetry sends strictly opt-in, allowlisted usage events to PostHog. It is off by default, DO_NOT_TRACK always wins, and sending never blocks the CLI for more than a short bounded flush or changes its output.
The official posthog-go client is intentionally not used: it starts background goroutines with retry/backoff and batching we do not need for one event per process. A single bounded HTTPS POST is simpler to reason about for the never-block rule and adds no dependencies.
Index ¶
- Constants
- Variables
- func Build(props map[string]any) map[string]any
- func Categories(counts map[string]int) string
- func Endpoint(getenv func(string) string) (host, key string)
- func EnsureInstallID(stateDir string) (string, error)
- func InstallID(stateDir string) string
- func RemoveInstallID(stateDir string) error
- func Send(ctx context.Context, host, key, distinctID, event string, props map[string]any, ...) error
- type Reason
Constants ¶
const ( DefaultKey = "phc_X9QM3tEAsU8bp71rq0wlODLXWnrX0AiRM9zHzklbiEp" DefaultHost = "https://piaget.icarus.tools" // FlushTimeout bounds the single send at process exit. FlushTimeout = 2 * time.Second EventCommand = "cli_command" Source = "oku-cli" )
Public, write-only project key and first-party ingestion proxy (same project as the Oku web app).
Variables ¶
var AllowedProperties = map[string]string{
"$lib": "always \"oku-cli\"",
"source": "always \"oku-cli\"",
"command": "command path, e.g. \"swap prepare\"",
"success": "true or false",
"error_code": "structured error code, e.g. REJECTED (failures only)",
"retryable": "whether the error is marked retryable (failures only)",
"duration_ms": "command wall time in milliseconds",
"cli_version": "oku version",
"cli_commit": "oku build commit",
"os": "GOOS, e.g. linux",
"arch": "GOARCH, e.g. amd64",
"json": "whether --json was used",
"invoked_by": "mcp, tty or non_tty",
"api_env": "prod, staging, local or custom (never the URL)",
"chain_id": "funds commands: source chain id",
"destination_chain": "funds commands: destination chain id",
"route": "funds commands: route/bridge the CLI selected, else the --route value",
"route_forced": "funds commands: whether --route forced the route",
"intent": "funds commands: whether intent routes were allowed",
"amount_source": "funds commands: max or exact (never the amount)",
"from_kind": "funds commands: native or erc20 (never the address)",
"to_kind": "funds commands: native or erc20 (never the address)",
"routes_considered": "funds REJECTED failures: number of routes considered",
"routes_rejected": "funds REJECTED failures: number of routes rejected",
"route_attempts": "funds REJECTED failures: number of quote attempts",
"route_rejections": "funds REJECTED failures: rejection category counts only (known categories, else other), e.g. amount_mismatch:2,not_answered:1",
"$process_person_profile": "always false (no person profiles)",
}
AllowedProperties is the exhaustive set of property keys that may be sent. Anything else is dropped by Build. Keep docs/telemetry.md in sync.
var UserAgent = "oku-cli"
Send posts one event with a hard timeout. All errors are returned for tests but callers must ignore them. UserAgent identifies the CLI to the ingestion proxy. Cloudflare in front of the proxy blocks Go's default "Go-http-client" agent with a 403.
Functions ¶
func Build ¶
Build filters props to the allowlist and drops any value that is not a bool, int, or short safe token string. Strings that look like addresses or decimal amounts are dropped as a belt-and-braces guard.
func Categories ¶
Categories formats rejection category counts as "a:2,b:1", keeping only snake_case category names.
func EnsureInstallID ¶
EnsureInstallID returns the install ID, creating a random UUIDv4 if absent.
func RemoveInstallID ¶
RemoveInstallID deletes the install ID so a later enable starts fresh.