traceway-cli
A Go CLI for the Traceway observability platform — exceptions, logs, endpoints, metrics. Designed to be first-class for both LLMs (invoking via shell tools) and humans (with gh-style ergonomics).
Install
Prebuilt binaries are published with every release at
github.com/tracewayapp/traceway/releases
under the matching CLI vX.Y.Z tag — the CLI version tracks the backend release.
Download the archive for your platform (traceway_<version>_<os>_<arch>.tar.gz,
or .zip on Windows), extract it, and put traceway on your PATH.
Or build from source — this repo ships a Nix dev shell with Go 1.26, just, gotestsum, golangci-lint, govulncheck, and gh:
nix develop
just build # produces ./bin/traceway
Or vanilla Go:
go build -o bin/traceway ./cmd/traceway
Check an installed binary with traceway version (or traceway --version). Source builds report dev.
Quick start
# 1. log in (creates ~/.config/traceway/config.json + ~/.local/state/traceway/state.json)
traceway login --url https://cloud.traceway.com
# 2. pick a project (one-time; future calls use it implicitly)
traceway projects list
traceway projects use <project-id>
# 3. ask questions
traceway exceptions list --since 24h
traceway logs query --since 1h --search "OutOfMemory"
traceway endpoints list --since 1h
traceway metrics query --name http.server.duration --aggregation avg --since 1h
Commands
| Command |
Purpose |
traceway login |
Authenticate and store the JWT |
traceway logout |
Forget the stored JWT for a profile |
traceway profiles {list,use} |
Manage multiple Traceway accounts/instances |
traceway projects {list,use} |
List or select the active project |
traceway exceptions list |
Recent grouped exceptions |
traceway exceptions show <hash> |
A single exception group + occurrences |
traceway exceptions occurrence <id> --recorded-at <t> |
A single occurrence by id (+ sessionId and recording) |
traceway exceptions archive <hash>... |
Archive one or more groups (mutating; needs --yes non-interactively) |
traceway exceptions unarchive <hash>... |
Unarchive (mutating; needs --yes non-interactively) |
traceway logs query |
Query logs with severity / service / search filters |
traceway endpoints list |
Per-endpoint p50/p95/p99 stats |
traceway endpoints show <id> --recorded-at <t> |
A single request (transaction) by id: spans + linked errors |
traceway tasks show <id> --recorded-at <t> |
A single background task run by id |
traceway ai-traces show <id> --recorded-at <t> |
A single AI trace by id + its conversation |
traceway sessions show <id> --started-at <t> |
A single session by id + the exceptions that fired in it |
traceway traces show <id> --recorded-at <t> |
A distributed trace: every service node sharing the id |
traceway metrics query |
Time-series metric queries |
Run traceway <command> --help for full per-command flags.
By-id detail lookups are time-bounded
The show / occurrence commands take a UUID plus a required timestamp flag
(--recorded-at, or --started-at for sessions). Telemetry tables are
partitioned by day; the timestamp bounds the query to a window around the record
so the lookup prunes partitions instead of scanning all of them. Get the id and
its timestamp together — from a dashboard URL's ?t= param, a notification's
Occurred at, or a list/exceptions show row's recordedAt. Omitting the flag
exits 2 (usage_error); a non-RFC3339 value exits 2 (invalid_timestamp).
Profiles
Multiple Traceway instances or accounts coexist via profiles. Configuration (URL, username) lives in $XDG_CONFIG_HOME/traceway/config.json so it can be checked in or managed declaratively (e.g. NixOS); credentials and the active project live in $XDG_STATE_HOME/traceway/state.json.
traceway login --url https://traceway.example.com --profile work
traceway profiles list
traceway profiles use work
traceway --profile personal exceptions list # one-off override
The --output flag picks the format. The default is table on a TTY and json otherwise — i.e. piping always gets machine-readable output.
| Format |
Use |
table |
Human-friendly columns (default on TTY) |
json |
Compact JSON, one record per line. Default when stdout isn't a TTY |
yaml |
YAML rendering of the same data |
--fields a,b,c projects list responses to just those keys (the pagination wrapper passes through unchanged):
traceway exceptions list --output json --fields exceptionHash,count,lastSeen
Errors
Every error writes a stable JSON envelope to stderr (in json / yaml modes — prose in table mode) and exits with one of:
| Exit |
Meaning |
| 0 |
Success |
| 1 |
Generic / API error |
| 2 |
Usage error (bad flags, missing confirmation, invalid time range) |
| 3 |
Connection failure |
| 4 |
Auth failure (not_authenticated, token_expired, forbidden) |
| 5 |
Not found |
| 6 |
Rate limited |
| 7 |
Server (5xx) |
Envelope shape:
{"error":"token_expired","message":"session expired or invalid","hint":"traceway login","exit_code":4}
The error field is a stable snake_case identifier. LLMs/scripts can branch on it.
Mutations + confirmation
exceptions archive and exceptions unarchive require explicit consent because they change server state:
- Pass
--yes to skip the prompt.
- Or set
TRACEWAY_ASSUME_YES=1 in the environment.
- Or run interactively and answer the
Continue? [y/N] prompt.
Calling a mutating command from a non-TTY context (script, LLM tool call) without one of the opt-ins fails immediately with usage_error (exit 2) — no hung prompts.
Smoke testing
Unit/CLI tests run by default and never touch a network:
just test
End-to-end tests against a real Traceway instance are gated behind a build tag and read connection info from env vars:
export TRACEWAY_SMOKE_URL=https://traceway.example.com
export TRACEWAY_SMOKE_USERNAME=you@example.com
export TRACEWAY_SMOKE_PASSWORD=...
export TRACEWAY_SMOKE_PROJECT_ID=...
just smoke-test
If any of those vars is missing, the smoke tests skip cleanly rather than fail.
Contributing
just check # lint + test + vulncheck
The library at pkg/client deliberately has zero CLI dependencies — it's importable directly by other Go programs (e.g. a future MCP server).