bronto-cli

module
v0.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2026 License: MIT

README

bronto-cli

CI Release Go Report Card

A community command-line client for the Bronto observability platform. One scriptable binary wraps Bronto's REST and ingestion APIs: search and tail logs, explore OpenTelemetry traces, send events, and manage every resource from datasets to monitors.

Built for pipelines and agents: JSONL by default when piped, typed errors with machine-readable hints, stable exit codes, and --dry-run plans for every mutating call.

bronto-cli is an official open-source project from Bronto, maintained as a community artifact: free to use, contributions welcome — but not covered by Bronto's product support. Questions, bugs, and feature requests are handled best-effort through GitHub issues, not Bronto's support channels.

Install

Homebrew (coming soon)
brew install bronto-community/tap/bronto

The tap isn't published yet — this will work once homebrew-tap exists and the release workflow's cask upload is flipped from skip_upload to auto. Until then, use one of the options below.

curl install script
curl -fsSL https://raw.githubusercontent.com/bronto-community/bronto-cli/main/scripts/install.sh | sh

Downloads the latest (or a pinned VERSION=) release for your OS/arch from GitHub Releases and verifies its checksum against the release's checksums.txt before installing to /usr/local/bin (override with BINDIR=).

go install
go install github.com/bronto-community/bronto-cli/cmd/bronto@latest
Docker
docker run --rm -e BRONTO_API_KEY -e BRONTO_REGION ghcr.io/bronto-community/bronto-cli:latest search "status >= 500" --since 1h

Two image variants are published on every release: the default (scratch + CA certs) and -distroless (ghcr.io/bronto-community/bronto-cli:latest-distroless), both ENTRYPOINT ["/bronto"]. Neither image has a shell, so pass credentials as environment variables rather than files (see Restricted environments).

Releases

Prebuilt archives (tar.gz for macOS/Linux, zip for Windows) plus .deb/.rpm packages and shell completions are attached to every GitHub release.

Quickstart

bronto auth login                                  # paste an API key, stored in the OS keychain
bronto datasets list                               # see what data you have
bronto search "status >= 500" -d <dataset> --since 1h   # one-shot query
bronto tail "level = 'error'" -d <dataset> --window 5m  # follow new events live

bronto auth login prompts for a key interactively (or --key-stdin to pipe one in) and picks a region (eu/us). Everything after that resolves credentials automatically.

-d takes a dataset name from datasets list (UUIDs work too). A name that exists in several collections is qualified as collection/name — e.g. -d prod/api-logs. You can drop -d entirely once you set a default (bronto config set default_dataset <name>) — or if the account has only one dataset, which is auto-picked.

At a terminal, bronto search "status >= 500" --since 1h renders a table:

@TIME                        @STATUS  @RAW                                       MESSAGE_KVS.STATUS
2026-07-19 09:14:05.312 UTC  error    {"level":"error","status":502,"path":...}  502
2026-07-19 09:13:58.007 UTC  error    {"level":"error","status":500,"path":...}  500

Piped, the same command emits JSONL — one full event per line, 64-bit ids preserved exactly:

{"@time":"2026-07-19 09:14:05.312 UTC","@status":"error","message_kvs.status":502,"metadata.sequence":4367602734065516544,...}

Command tour

Explore — search, tail, and traces:

bronto search "status >= 500" --since 1h
bronto search --select "count()" -g host --since 15m
bronto tail "level = 'error'" --include timeout --exclude healthz
bronto traces show <trace-id>
bronto traces services --since 1h
bronto fields -d <dataset> --since 1h
bronto context --sequence 111721913 -d <dataset> --timestamp 1711535140632

traces also has list, operations, aggregate, and shape subcommands over the .traces logset.

Manage — resources, exports, usage:

bronto datasets list
bronto monitors get <id>
bronto dashboards create -f name=Overview -f description=Prod
bronto parsers update <id> -f name=new-name
bronto api-keys delete <id> --yes
bronto exports create -d <dataset> --since 1h --where "status=500" --wait
bronto usage --since 7d
bronto users list
bronto groups create -f name=oncall
bronto monitors templates list
bronto webhooks create -f name=alerts -f url=https://example.com/hook

Every resource (datasets, monitors — incl. monitors templates and monitors downtimes — dashboards, parsers, exports, api-keys, saved-searches, users, groups, webhooks, slack, limits, encryption-keys, forward-configs, plus read-only collections and log-views) shares the same list | get <id|name> | create | update <id|name> | delete <id|name> --yes pattern (list-only where the API documents no other verbs). Everywhere an id is accepted, a unique name works too (users: email; datasets: collection/name qualifies duplicates) — ambiguous names error with the candidates; create/update take repeated -f key=value or --input file.json/--input -, and delete prompts for confirmation unless --yes is passed.

Pipe — send data in:

bronto send -d app -m 'hello world'
echo '{"message":"m","level":"warn"}' | bronto send -d app

send posts one event with -m/--message, or reads NDJSON/plain-text lines from stdin and batches them (--batch-size, --batch-bytes, --flush-interval) — e.g. tail -f access.log | bronto send -d app --collection prod.

Ops — auth, config, plugins:

bronto auth status
bronto config list
bronto plugins list
bronto ping
bronto version

Anything without a dedicated command is reachable via the escape hatch: bronto api GET /monitors -f limit=10 or bronto api POST /search --input query.json.

Scripting & agents

Output to a non-TTY (piped or redirected) defaults to JSONL, one JSON object per line — no flag needed. Force a format explicitly with -o table|json|jsonl|raw|csv.

bronto search "status >= 500" --since 1h --jq '.message' | wc -l
bronto datasets list --fields log,log_id
bronto datasets list --fields '?'          # list available field names instead of data
  • --dry-run prints any mutating API call as a plan document ({"dry_run":true,"method":"POST","path":"/monitors","body":{…}}) instead of executing it — reads still run, so dataset-name resolution keeps working. Destructive commands skip their confirmation prompt (nothing destructive can happen).
  • --debug traces every API request/response on stderr (method, URL, status, latency, truncated bodies — the API key never appears).
  • --timeout <seconds> and --max-retries <n> tune the HTTP client per invocation (also config keys / BRONTO_TIMEOUT, BRONTO_MAX_RETRIES).
  • --jq '<expr>' runs a gojq expression over json/jsonl output, one result per line. Unlike the jq CLI, a value that errors or halts on the expression is silently skipped — every other row still prints.
  • --fields a,b,c narrows table/json/jsonl/csv output to those columns/keys.
  • Errors go to stderr; in machine mode (non-TTY stderr) they're a stable JSON envelope: {"error":{"code":"...","message":"...","retryable":true|false}}.
  • Exit codes are stable: 0 success, 1 unexpected error, 2 usage/config error, 3 auth error, 4 not found, 5 rate limited or timeout (retryable).

For agents (Claude Code, MCP tool wrappers, etc.), see skill.md for a short orientation doc, or llms.txt for a 20-line summary. bronto --help and bronto <command> --help are always the authoritative reference.

Configuration

Values resolve with this precedence, highest first:

Precedence Source Example
1 Flags --region eu, --api-key ...
2 Environment variables BRONTO_API_KEY, BRONTO_REGION
3 Project file .bronto.toml (walks up from cwd, like .git) region = "eu"
4 User config <config dir>/bronto/config.toml (profile section) [profiles.prod]
5 Built-in defaults region = "eu"

Run bronto config list to see every resolved value and which source it came from; bronto config get <key> for one value; bronto config set <key> <value> to persist to the user config file. api_key is deliberately never read from either TOML file — secrets only come from the OS keychain (bronto auth login) or BRONTO_API_KEY.

Profiles let you keep multiple accounts/regions side by side: bronto auth login --profile prod, then bronto auth switch prod or --profile prod per-invocation.

Environment variables:

Variable Purpose
BRONTO_API_KEY API key (bypasses the keychain)
BRONTO_REGION eu or us
BRONTO_BASE_URL full API base URL (staging, localhost) — overrides the region-derived URL
BRONTO_PROFILE named profile to use
BRONTO_TIMEOUT request timeout override (seconds)
BRONTO_MAX_RETRIES retries for idempotent requests on 429/5xx
BRONTO_INGEST_URL override the ingestion endpoint (bronto send)
BRONTO_CONFIG_DIR override the user config directory (parent of bronto/config.toml)

Config keys (settable via bronto config set, project .bronto.toml, or profile files — flags and env always win):

Key Env Purpose Default
region BRONTO_REGION eu or us eu
base_url BRONTO_BASE_URL full API base URL override (staging/localhost) derived from region
output — default output format table (TTY) / jsonl (piped)
default_dataset — dataset name/UUID or from_expr used when -d is omitted —
timeout BRONTO_TIMEOUT HTTP timeout in seconds 30
max_retries BRONTO_MAX_RETRIES retries for idempotent requests 2
ingest_url BRONTO_INGEST_URL ingestion endpoint for bronto send derived from region
profile BRONTO_PROFILE named profile default

api_key is deliberately not file-settable — keys live in the keychain or BRONTO_API_KEY only.

Troubleshooting

  • auth_invalid_key (exit 3) — the key is wrong or an ingestion key was used where a management key is needed. Run bronto auth login, or check bronto auth status (exits non-zero when the credential is broken, so you can gate scripts on it).
  • No OS keychain (containers, CI) — set BRONTO_API_KEY directly; the keychain is never touched once a key is resolved. bronto auth login falls back to a credentials file with a warning.
  • usage_confirmation_required (exit 2) — a destructive command ran without a TTY; pass --yes (or --dry-run to preview).
  • usage_missing_dataset — the account has several datasets; the error lists them. Pick one with -d <name> or set default_dataset.
  • Wrong region — bronto ping shows the resolved base URL and latency; override with --region / BRONTO_REGION.
  • What is it actually sending? — add --debug for a curl-style trace (API key never printed), or --dry-run to see mutating request bodies without executing.

Staging & local development

Point the CLI at any Bronto-compatible API — a staging environment or a local instance:

export BRONTO_BASE_URL=http://localhost:8080   # or --base-url per invocation
export BRONTO_INGEST_URL=http://localhost:8081 # ingestion host for `bronto send`

Flags beat env, env beats config files, so a one-off --base-url always wins. Keep environments cleanly separated with profiles instead: bronto config set base_url https://api.staging.example --profile staging, then --profile staging (or BRONTO_PROFILE=staging) per invocation. bronto ping and bronto auth status show which base URL actually resolved.

Restricted environments

For containers, CI runners, or sandboxes without a usable OS keychain or writable home directory:

  • Set BRONTO_API_KEY (and BRONTO_REGION) directly — no keychain access is attempted once a key is already resolved.
  • Set BRONTO_CONFIG_DIR to a writable path if you need bronto config set or profile files to work somewhere other than the default user config directory.

The published scratch-based image (ghcr.io/bronto-community/bronto-cli:latest) has no shell, package manager, or keychain daemon by design — pass credentials as environment variables when running it.

Plugins

Any executable named bronto-<name> on PATH is invoked when <name> is the first argument that doesn't match a built-in command — e.g. bronto deploy invokes a bronto-deploy executable found on PATH. Built-in commands always take precedence, so a plugin can't shadow search, auth, etc. Discover installed plugins with bronto plugins list.

Plugins do not inherit keychain-stored credentials — only environment variables are passed through. A plugin needing API access should call bronto auth token itself (prints the resolved key for scripting) or require the caller to set BRONTO_API_KEY directly.

Development

git clone https://github.com/bronto-community/bronto-cli
cd bronto-cli
make build   # -> ./bronto
make test    # go test ./...
make lint    # golangci-lint run

No code generation is required for day-to-day development — the vendored API client is already checked in. See CONTRIBUTING.md for the architecture map, TDD/lint expectations, and how to add a new resource command.

No telemetry

bronto-cli sends no telemetry, analytics, or usage data anywhere. The only network calls it makes are the ones you ask for: requests to the Bronto API and ingestion endpoints you've configured.

License

MIT — see LICENSE.

Directories

Path Synopsis
cmd
bronto command
Package integration black-box tests the built bronto binary via os/exec: real process, real exit codes, real signal handling — named coverage gaps like tail's SIGINT path (tail_sigint_test.go) and main()'s own exit mapping (cmd/bronto/main.go's exitStatus) live only there and can't be reached by in-process unit tests.
Package integration black-box tests the built bronto binary via os/exec: real process, real exit codes, real signal handling — named coverage gaps like tail's SIGINT path (tail_sigint_test.go) and main()'s own exit mapping (cmd/bronto/main.go's exitStatus) live only there and can't be reached by in-process unit tests.
internal
api
Package api holds the hand-written HTTP layer for the Bronto management API: the retrying auth Transport, the --debug tracing transport, and the status-to-typed-error mapping (ErrorFromStatus).
Package api holds the hand-written HTTP layer for the Bronto management API: the retrying auth Transport, the --debug tracing transport, and the status-to-typed-error mapping (ErrorFromStatus).
bronto
Package bronto is the service layer: request/response models and cross-endpoint workflows over the Bronto REST API (spec §4).
Package bronto is the service layer: request/response models and cross-endpoint workflows over the Bronto REST API (spec §4).
cli
Package cli contains the Cobra command tree.
Package cli contains the Cobra command tree.
clierr
Package clierr defines the CLI's typed errors: stable machine codes, human hints, and the exit-code contract (spec §5).
Package clierr defines the CLI's typed errors: stable machine codes, human hints, and the exit-code contract (spec §5).
config
Package config resolves CLI configuration with the precedence flags > env > project .bronto.toml > user config > defaults (spec §6), tracking the source of every value.
Package config resolves CLI configuration with the precedence flags > env > project .bronto.toml > user config > defaults (spec §6), tracking the source of every value.
ingest
Package ingest sends events to Bronto's ingestion host (a separate host from the REST API): NDJSON bodies, routing headers, optional gzip.
Package ingest sends events to Bronto's ingestion host (a separate host from the REST API): NDJSON bodies, routing headers, optional gzip.
output
Package output is the single output engine used by every command (spec §5).
Package output is the single output engine used by every command (spec §5).
secrets
Package secrets stores API keys in the OS keychain (macOS Keychain, Linux Secret Service, Windows Credential Manager) with a 0600 credentials-file fallback for headless environments (spec §6).
Package secrets stores API keys in the OS keychain (macOS Keychain, Linux Secret Service, Windows Credential Manager) with a 0600 credentials-file fallback for headless environments (spec §6).
timerange
Package timerange converts CLI time flags (--since / --from / --to) into the Bronto search API's time parameters: a relative time_range string ("Last 15 minutes") or absolute from_ts/to_ts unix-millisecond bounds.
Package timerange converts CLI time flags (--since / --from / --to) into the Bronto search API's time parameters: a relative time_range string ("Last 15 minutes") or absolute from_ts/to_ts unix-millisecond bounds.
tools/endpointmap command
Command endpointmap prints the CLI's management-API endpoint inventory (see cli.EndpointInventory) as JSON.
Command endpointmap prints the CLI's management-API endpoint inventory (see cli.EndpointInventory) as JSON.
traces
Package traces implements the trace explorer: span model, aggregations, and the waterfall/shape algorithms over Bronto's .traces logset.
Package traces implements the trace explorer: span model, aggregations, and the waterfall/shape algorithms over Bronto's .traces logset.
version
Package version holds build metadata injected via -ldflags.
Package version holds build metadata injected via -ldflags.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL