Every command reads the same config, takes the same global flags and prints something a pipe can consume. Where a command names a next step, that step is a command too.
sgl login
Signing in happens in the terminal. The browser step issues a device code and the token lands in your system keychain. CI reads its own token from the environment and never opens a browser.
sgl login
# opens signal.sh/device · code SGL-4H2K
# token stored in the login keychain
sgl whoami
# nadia@kesteven.health · org kesteven · 3 services- --token <value>
- for CI, where there is no browser
- --org <name>
- pick one when you belong to several
sgl watch
The default view: every service in an environment with its p95, its error rate, and any regression the timeline can attribute to a deploy. Ends by printing the command that investigates what it found.
sgl watch --env prod --since 15m
sgl watch --service payments-worker --follow
sgl watch --env prod --json | jq '.regressions'- --since <window>
- default 15m
- --follow
- redraw every 5s
- --json
- machine output; exits 1 when a regression is attributed
sgl query
One query language in the CLI, the dashboard and the API: by, where, since, compare. A table by default, JSON when you ask.
$ sgl query 'p95(latency) by route' \
--service checkout --since 24h
route p95 n 24h
/checkout/submit 412ms 18.2k +38%
/checkout/quote 121ms 44.9k -2%
/checkout/receipt 88ms 12.1k +1%- --compare <window>
- adds a delta column
- --format table|json|csv
- table by default
- --limit <n>
- default 20 rows
sgl trace
The slowest traces in a window, or every trace inside one release. This is the command sgl watch hands you when it attributes a regression.
sgl trace payments-worker --deploy 8f21c4e
sgl trace checkout --slowest 20 --since 1h
sgl trace --id 4b21f0c9 --format json- --deploy <sha>
- scope to one release window
- --slowest <n>
- default 10
- --id <trace>
- one trace, span by span
sgl diff
Compare two windows, or two deploys, across latency, error rate and throughput, per route. Added in 2.1.0 for the question you ask once and never build a dashboard for.
sgl diff 8f21c4e^ 8f21c4e --service payments-worker
sgl diff --since 24h --compare 7d --format json- --by route|service
- grouping, route by default
- --format json
- for pasting into an incident note
sgl cost
What the next invoice will say, before it says it. Billing is per ingested gigabyte after sampling, so the estimate moves when your sample rates do. The rate and the free-tier line are on pricing.
$ sgl cost --estimate --since 30d
service ingest est.
payments-worker 41.2 GB $17.30
checkout 33.8 GB $14.20
api-gateway 32.1 GB $13.48
total 107.1 GB $44.98 at $0.42/GB- --estimate
- project the window forward a month
- --by service|env
- service by default
- --since <window>
- default 30d
sgl collector
Run the ingest path inside your own network. The collector is one static binary, and verify checks disk headroom, clock skew and OTLP reachability before you cut over.
sgl collector verify --endpoint https://otel.internal:4317
# disk headroom 412 GB ok
# clock skew 14 ms ok
# otlp reachable yes ok
sgl collector start --config signal.config.ts- --endpoint <url>
- where the SDK will send spans
- --dry-run
- check, change nothing
- --config <file>
- default signal.config.ts
Exit codes
- 0
- the command answered
- 1
- a regression was attributed (--json only)
- 2
- bad usage, or an unknown flag
- 7
- no ingest key in the environment