> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bronto.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Searching logs

> Run one-shot queries with bronto search, build filters with flags, aggregate, summarize, and explore interactively.

`bronto search` runs one query and exits. The query is a Bronto WHERE expression, the
same language the web app's search bar uses. The
[search syntax page](https://docs.bronto.io/query-syntax/search-syntax) on docs.bronto.io
documents it in full. Under the hood, `bronto search` calls the
[search API](https://docs.bronto.io/api-reference/search/execute-a-query).

<Frame caption="Narrowing 502s in checkout-service">
  <video src="https://mintcdn.com/bronto/KAWScdJxL520s-EQ/cli/tapes/search.webm?fit=max&auto=format&n=KAWScdJxL520s-EQ&q=85&s=19305f4353042a1d2c548a02034fa4bf" poster="/cli/tapes/search.png" aria-label="Narrowing 502s in checkout-service" autoPlay muted loop playsInline controls data-path="cli/tapes/search.webm" />
</Frame>

## The basics

```console theme={"dark"}
$ bronto search "status >= 500" -d prod/checkout-service --since 1h
@TIME                        @STATUS  MESSAGE_KVS.TRACE_ID              MESSAGE_KVS.DURATION_MS  MESSAGE_KVS.HOST  MESSAGE_KVS.MESSAGE                               MESSAGE_KVS.PATH  MESSAGE_KVS.SERVICE
2026-07-19 09:24:49.632 UTC  error    f7df498a556927026404a9f1e89c38e2  30042                    web-3             payment failed: payments-api timed out after 30s  /api/checkout     checkout-service
2026-07-19 09:24:33.007 UTC  error    168a296e219517ed2119957be0ed85c1  30034                    web-3             payment failed: payments-api timed out after 30s  /api/checkout     checkout-service
...
```

* **Dataset.** `-d`/`--dataset` takes a dataset name or UUID and can be repeated to search
  several at once. Qualify a name that exists in more than one collection as
  `collection/name`. Without `-d`, the CLI uses `default_dataset` from your config, or the
  only dataset if the account has just one. Otherwise it fails with
  `usage_missing_dataset` and lists the datasets it found. `--from-expr` takes a dataset
  selector expression instead, for example `--from-expr "log_id = '<uuid>'"`.
* **Time range.** `--since` takes a relative lookback such as `30s`, `15m`, `1h`, `2d`,
  `1w`, or `1h30m`. For a fixed window, pass RFC 3339 timestamps with `--from` and
  `--to`. With no time flag, the search covers the last 15 minutes.
* **Size and order.** `-n`/`--limit` caps the number of events (1 to 10000, default 100).
  Results come newest first. `--oldest-first` flips that, and `--order-by` takes an
  SQL-style order such as `'duration_ms DESC'`.
* **Stdin.** Pass `-` as the query to read it from stdin, which helps with long queries
  and quoting.

At a terminal, the result is a table. The CLI ranks parsed fields by how often they hold
a value and how much they vary, and turns the best ones into columns. Once it has three
useful columns it drops the raw JSON. A footer on stderr points to `bronto fields`,
`--select`, and `-x`.

## Filter flags instead of WHERE

The filter flags build the WHERE expression for you:

| Flag | Keeps events where the field... |
| - | - |
| `--eq field=value` | equals the value |
| `--ne field=value` | does not equal the value |
| `--gt`, `--ge`, `--lt`, `--le` | is greater than, greater or equal, less than, less or equal |
| `--match field=regex` | matches the regex |
| `--nmatch field=regex` | does not match the regex |

```console theme={"dark"}
$ bronto search -d prod/checkout-service --ge status=500 --gt duration_ms=1000 --since 1h
@TIME                        @STATUS  MESSAGE_KVS.TRACE_ID              MESSAGE_KVS.DURATION_MS  MESSAGE_KVS.HOST  MESSAGE_KVS.MESSAGE                               MESSAGE_KVS.PATH  MESSAGE_KVS.SERVICE
2026-07-19 09:24:49.632 UTC  error    f7df498a556927026404a9f1e89c38e2  30042                    web-3             payment failed: payments-api timed out after 30s  /api/checkout     checkout-service
2026-07-19 09:24:33.007 UTC  error    168a296e219517ed2119957be0ed85c1  30034                    web-3             payment failed: payments-api timed out after 30s  /api/checkout     checkout-service
...
```

Each flag can be repeated. The CLI ANDs them together, and with the positional query if
you pass one. The CLI looks up each field name in the dataset's field index, so
`model` finds `$model` and matching is case-insensitive. It quotes the value based on its
shape: numbers and booleans stay bare, strings get single quotes. The compiled filter is
echoed to stderr.

* `--show-query` prints the compiled WHERE and exits without searching.
* `--exact` turns off the fuzzy name lookup and uses field names as written. Use it in
  scripts.
* An unknown or ambiguous field name is an error (exit code 2) that lists candidates.

```console theme={"dark"}
$ bronto search -d prod/checkout-service --ge status=500 --eq service=checkout-service --show-query
status >= 500 AND service = 'checkout-service'
```

## Look closer at events

`-x`/`--expand` is the "click on a row" view. It prints every field of every event, one
per line and untruncated, including the `metadata.*` fields the table hides.

```console theme={"dark"}
$ bronto search "status >= 500" -d prod/checkout-service --since 1h -n 2 -x
─ event 1 ──────────────────────────────
@time                    2026-07-19 09:24:49.632 UTC
@status                  error
@raw                     {"level":"error","service":"checkout-service","host":"web-3","message":"payment failed: payments-api timed out after 30s","path":"/api/checkout","status":502,"duration_ms":30042,"trace_id":"f7df498a556927026404a9f1e89c38e2"}
message_kvs.duration_ms  30042
message_kvs.host         web-3
message_kvs.message      payment failed: payments-api timed out after 30s
message_kvs.path         /api/checkout
message_kvs.service      checkout-service
message_kvs.status       502
message_kvs.trace_id     f7df498a556927026404a9f1e89c38e2
metadata.logId           0b7c6f2e-1d4a-4c8e-9a51-3f2d8e6b7a10
metadata.origin          web-3
metadata.sequence        48211195
metadata.timestamp       1784453089632
─ event 2 ──────────────────────────────
...
```

`-x` only works with table output. When piped, add `-o table`. The JSON formats already
carry every field.

To see what happened around one event, use `bronto context`. It needs the event's
`metadata.sequence` value and its timestamp in Unix milliseconds, both visible in the
`-x` view:

```sh theme={"dark"}
bronto context --sequence <sequence> --timestamp <unix-ms> -d prod/checkout-service
bronto context --sequence <sequence> --timestamp <unix-ms> -d prod/checkout-service --direction before -n 20
```

`--direction` is `before`, `after`, or `both` (the default), and `-n` sets how many
events to fetch in each direction.

## Find the right field names

`bronto fields` lists the fields seen in a dataset, each with a sample of values, so you
can spell a query correctly the first time. Add a positional filter to keep only fields
whose name contains it:

```console theme={"dark"}
$ bronto fields -d prod/checkout-service --since 1h
KEY          COUNT  TYPE    SOURCE   VALUES
duration_ms  76     number  message  123, 124, 148, 158, 32, …
host         76     string  message  web-1, web-2, web-3
...
$ bronto fields -d prod/checkout-service status
KEY     COUNT  TYPE    SOURCE   VALUES
status  76     number  message  200, 502
```

Leave out `-d` to scan all datasets. `--since` (default `1h`) sets how far back to look
and `-n` caps the number of fields.

`bronto query check` validates an expression locally, without calling the API, and points
a caret at the problem:

```console theme={"dark"}
$ bronto query check "status >= 500 AND service = 'checkout-service'"
✓ valid — fields: service, status
```

With `-d <dataset>` it also warns about fields that haven't appeared in that dataset
recently and suggests close matches. `--strict` turns those warnings into a failure
for use in CI.

## Aggregate

`--select` picks columns or aggregate functions, and `-g`/`--group-by` groups by one or
more keys. Both are repeatable.

```console theme={"dark"}
$ bronto search --select "count()" -g host -d prod/checkout-service --since 30m
COUNT  GROUP  STAT     VALUE
28     web-2  count()  28
26     web-1  count()  26
22     web-3  count()  22
```

For timeseries aggregates, `--slices` sets the number of time buckets.

## Summaries

Two flags summarize a result instead of listing events.

`--histogram` shows when matching events happened, which answers "when did this start and
how big is it?":

```console theme={"dark"}
$ bronto search "status >= 500" -d prod/checkout-service --since 1h --histogram
09:00   0
...
09:20   0
09:21  ████████████████████████ 3
09:22  ████████████████████████████████████████ 5
09:23  ████████████████████████████████████████ 5
09:25   0
...
total: 13 events (bucket: 1m15s)
```

All 13 errors land in the few buckets after 09:21. Empty buckets print `0`, so a quiet
period before a spike is easy to see.

`--patterns` clusters events into message templates with counts, which shows what a noisy
dataset is mostly made of (learn more about
[patterns](https://docs.bronto.io/core-features/patterns)):

```console theme={"dark"}
$ bronto search "" -d prod/checkout-service --since 1h --patterns
COUNT  PATTERN
58     <*> <*>
13     <*> failed: payments-api timed out after <*>
3      <*> slow to respond <*>
2      {"level":"info","service":"checkout-service","host":"web-2","message":"checkout <*>
```

## Saved searches and the web UI

`--saved <name>` runs a [saved search](https://docs.bronto.io/Search-and-Visualize/Saved-Searches)
by name or id. Query, dataset, and time flags you pass on the command line override what's
stored.

```sh theme={"dark"}
bronto saved-searches list
bronto search --saved <saved-search-name> --since 30m
```

Saved searches are a regular [resource](/cli/guides/resources), so
`bronto saved-searches create`, `update`, and `delete` manage them.

`--url` prints a link to the same query in the Bronto web app, and `--open` opens it in
your browser. Neither runs the query. The link targets your active org. If the CLI can't
work out the org, set it with `bronto config set org_id <uuid>`.

`--explain-only` returns the query plan and cost estimate instead of results.

## Search local files

`--local <file>` evaluates the query on your machine over an NDJSON or plain-text file.
Nothing is sent to Bronto and no API key is needed, so it works on downloaded
[exports](/cli/guides/exports) or a `kubectl logs` dump. Pass `-` to read stdin.

```sh theme={"dark"}
kubectl logs deploy/checkout | bronto search --local - "status >= 500"
bronto search --local export.ndjson "path = '/api/checkout'" -o jsonl --fields @time,path
```

JSON lines are queryable by their keys (nested keys in dotted form). Plain-text lines are
matched with `@raw ~ 'regex'`. `-o`, `--fields`, `--jq`, and `-n` work. Dataset, time
range, select, and group-by flags don't apply and are rejected.

## The REPL

For a longer investigation, `bronto repl` opens a psql-style prompt. Type a WHERE
expression to run it, then edit it and run it again.

```sh theme={"dark"}
bronto repl -d prod/checkout-service --since 1h
```

| Meta-command | What it does |
| - | - |
| `\since <duration>` | change the time window |
| `\d <dataset>` | switch dataset |
| `\limit <n>` | change the result limit |
| `\more` | fetch the next page |
| `\fields` | list field names |
| `\tail` | follow live until Ctrl-C |
| `\help` | list meta-commands |
| `\q` | quit |

History is saved in your config directory between sessions. The REPL needs a terminal.
Piped, it exits with code 2.

To go from a question in plain English to a query, see [Ask](/cli/guides/ask).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.