Sazabi
Investigate

Log search

Ask questions about your logs in plain language, get an answer with the query behind it, then rerun, page through, and list those queries from the CLI, a thread, MCP, or the API.

Log search answers questions about the logs stored in your project. Ask in plain language, such as "how many errors did checkout log yesterday?", and you get a short answer, the results it was written from, the time window it covered, and a query ID. The query ID reruns the same query later, over the same window or a new one, without asking the question again.

You can search from the CLI, from a thread with the Sazabi agent, from your own AI agents over MCP, and from the API. Every surface reads the same logs and the same saved queries.

Ask your first question

Install the CLI, sign in, and choose a project; see CLI reference. Then ask a question about the active project's logs:

sazabi logs ask "errors per service in the last 6 hours"
In the last 6 hours (2026-10-12 03:30–09:30 America/Los_Angeles), 1,482 error-level lines came from 6 services. Top: checkout 912; api 341; payments-worker 155; auth 48; web 19; notifications 7.

Results (top 50):
  Service          Count
  checkout           912
  api                341
  payments-worker    155
  auth                48
  web                 19
  notifications        7

Window: 2026-10-12 03:30–09:30 America/Los_Angeles
Query ID: 8f0c2a4e-5b1d-4c7e-9a3f-2d6b8e1f4c90
Question: errors per service in the last 6 hours

To ask about another project, add --project-id your-project-id.

What you get back

Every answer has the same layout:

  • The answer, in the language you asked in. Its counts cover everything that matched, not only the rows shown.
  • Results, the table the answer was written from, with up to 50 rows. Its shape follows the question:
    • one number, under Results (1):, for "how many" and "how many distinct" questions;
    • one row per group, such as per service, endpoint, message, or user, with a column for each figure;
    • matching log lines as Time, Service, Severity, and Message, for "show me" questions.
  • Window: the time range the results cover, on your clock.
  • Query ID: the ID that reruns this query.
  • Question: your question as you typed it.

When more than 50 lines matched, the output ends with the command for getting the rest:

To fetch more query results, run: sazabi logs query execute your-query-id

That command reruns the query and shows the same first page; raise --limit to see up to 5,000 lines at once, or follow its Next: line page by page. See Page through matching lines.

When nothing matched, the table reads no matching log lines and a Read as: line shows how your question was understood. Rephrase the question, or rerun its query over a wider window.

Ask about a time

Name the period in your question: "in the last 6 hours", "since 9am", "yesterday", "last Tuesday", "between 18:00 and 19:00", or "this hour against the previous hour". If the question names no period, the last hour is searched.

Times are read in your computer's time zone, and the output shows them in it too:

sazabi logs ask "how many errors did checkout log yesterday?"
checkout logged 2,317 errors yesterday (2026-10-11, 00:00–24:00 America/Los_Angeles).

Results (1):
  2,317

Window: 2026-10-11 00:00–2026-10-12 00:00 America/Los_Angeles
Query ID: 3b7e9d12-6a4f-4f0b-8c2e-71d5a9e0b6f3
Question: how many errors did checkout log yesterday?

To use another time zone, name it in the question ("since midnight UTC") or set TZ for the command (TZ=UTC sazabi logs ask "errors since midnight").

To set the window yourself, pass --since with whole minutes, hours, or days (--since 30m, --since 7d), or --from and --to as ISO-8601 times. A flag replaces the period your question names, and the answer says so.

Use the output in scripts

--json prints the whole response: answer, queryId, window (in UTC), and results.

sazabi logs ask "errors per service in the last 6 hours" --json | jq -r .queryId

Rerun a query

sazabi logs query execute runs a saved query again by its query ID. It does not ask the question again or write a new answer, so it returns faster, with results in the same table shapes. If the answer was an overview of what's in your logs, its query ID returns the newest log lines of the kinds the overview showed instead of the overview table.

# The same times the original answer covered
sazabi logs query execute 8f0c2a4e-5b1d-4c7e-9a3f-2d6b8e1f4c90

# The same question over the last 24 hours, ending now, top 5
sazabi logs query execute 8f0c2a4e-5b1d-4c7e-9a3f-2d6b8e1f4c90 --since 24h --limit 5

# A window you choose
sazabi logs query execute 8f0c2a4e-5b1d-4c7e-9a3f-2d6b8e1f4c90 --from 2026-10-12T09:00:00-07:00 --to 2026-10-12T12:00:00-07:00
Results (top 5):
  Service          Count
  checkout         3,804
  api              1,297
  payments-worker    611
  auth               173
  web                 66

Window: 2026-10-11 09:31–2026-10-12 09:31 America/Los_Angeles
Query ID: 8f0c2a4e-5b1d-4c7e-9a3f-2d6b8e1f4c90

Without a window flag, a rerun covers the same times as the original answer, however long ago that was. It searches your logs again rather than returning a saved copy, so the results can differ if logs for that window arrived late or have since aged out.

--limit sets how many rows to show, from 1 to 5,000 (50 by default).

Page through matching lines

When a query returns log lines and more matched than one page holds, the output ends with a Next: line:

sazabi logs query execute c41a7f08-2e9b-4d63-b5a1-9f3e6c2d8b17 --limit 3
Results (top 3):
  Time                     Service   Severity  Message
  2026-10-12 09:30:58.114  checkout  ERROR     payment authorization failed: card_declined order=84213
  2026-10-12 09:30:41.902  checkout  ERROR     payment authorization failed: timeout after 10000ms order=84207
  2026-10-12 09:29:17.356  checkout  ERROR     inventory reservation failed: sku=TS-2041 out of stock

Window: 2026-10-12 08:31–09:31 America/Los_Angeles
Query ID: c41a7f08-2e9b-4d63-b5a1-9f3e6c2d8b17

Next: --cursor eyJ2IjoyLCJxIjoiYzQxYTdmMDgtMmU5Yi00ZDYzLWI1YTEtOWYzZTZjMmQ4YjE3IiwiZiI6IjIwMjYtMTAtMTJUMTU6MzE6MDAuMDAwWiIsInQiOiIyMDI2LTEwLTEyVDE2OjMxOjAwLjAwMFoiLCJhIjpbIjIwMjYtMTAtMTIgMTY6Mjk6MTcuMzU2MDAwMDAwIiwiMDFhMTNjNTItN2Q0ZS03YjE5LWEzZjYtNWMwZThkMmI5YTQxIl19

Pass the token as --cursor for the next page. The cursor keeps the window of the first page, so don't add --since, --from, or --to to it. Each page continues after the last line of the page before, so no line appears twice. A line that arrives late for a part of the window you already paged through doesn't appear; run the query again from the first page to include it.

sazabi logs query execute c41a7f08-2e9b-4d63-b5a1-9f3e6c2d8b17 --limit 3 --cursor your-cursor-token

Grouped results and single numbers don't page: --limit caps how many groups are shown. With --json, the token is nextCursor.

Change a query yourself

sazabi logs query execute also runs a query you edit. Save a query's definition with sazabi logs query get your-query-id --json | jq .spec > query.json, change it, and run it with sazabi logs query execute @query.json --since 6h. sazabi logs query schema prints the format.

To see when the matching lines began and ended, add "times": true to a query. Each group, each point of a series, or the single value then also shows the first and last matching line's time (firstSeen and lastSeen in JSON, First seen and Last seen in the CLI). For a percentage, they are the times of the lines it counts as its part, such as the first and last error in an error rate. These times are read from the log lines themselves.

List your queries

sazabi logs query list shows the project's queries, newest first: every question asked and every query you ran from your own definition, with the time on your clock. Reruns by query ID aren't listed.

sazabi logs query list --limit 3
Log queries
  Query ID                              Created at (America/Los_Angeles)  Question
  c41a7f08-2e9b-4d63-b5a1-9f3e6c2d8b17  2026-10-12 09:31                  show me the newest errors from checkout
  3b7e9d12-6a4f-4f0b-8c2e-71d5a9e0b6f3  2026-10-12 09:30                  how many errors did checkout log yesterday?
  8f0c2a4e-5b1d-4c7e-9a3f-2d6b8e1f4c90  2026-10-12 09:30                  errors per service in the last 6 hours

Next: --cursor 8f0c2a4e-5b1d-4c7e-9a3f-2d6b8e1f4c90

It lists 20 queries by default and up to 100 with --limit. Pass the Next: token as --cursor to see older ones.

Ask the agent in a thread

Ask about your logs in any thread and the Sazabi agent searches them for you. It shows each search as a tool call, and it can show what it found as a table of log lines, a chart over time, or the full detail of a single line. In a log table you can filter by Severity and Services and expand a row to see its JSON body. The agent also combines log search with its other tools: your code, issues, and connected services. See Agent tools.

The web app has no separate log search page; in the web app, you search by asking the agent in a thread.

Use log search from AI agents and the API

Coding agents in a terminal can run sazabi logs ask and sazabi logs query execute directly once the CLI is signed in.

MCP clients reach log search through the Sazabi MCP server; see Connect your coding agent to set one up. The agent finds these operations with the server's search tool and runs them with execute:

  • sazabi/logs.ask asks a question.
  • sazabi/logs.executeQuery reruns a query ID, with an optional window, limit, cursor, and group.
  • sazabi/logs.queries.list lists the project's queries.

The API offers the same operations with a secret key:

  • POST /v1/logs/ask asks a question. See Ask about logs.
  • POST /v1/logs/queries/execute reruns a query ID and pages with cursor and nextCursor. For a grouped result, set group to one row's values, one per column, to get the log lines behind that row. See Run a log query.
  • GET /v1/logs/queries lists queries. See List log queries.
curl https://api.sazabi.com/v1/logs/ask \
  -H "Authorization: Bearer $SAZABI_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"question": "errors per service in the last 6 hours", "timeZone": "America/Los_Angeles", "results": true}'

Two differences from the CLI: set "results": true to get the result rows with the answer, and pass timeZone so periods such as "yesterday" use your clock (without it they're read in UTC). Pass projectId unless your secret key is scoped to one project. The TypeScript SDK has the same calls as sazabi.logs.ask and sazabi.logs.executeQuery; see TypeScript SDK.

Questions that work well

To find outAsk
Errors by service"errors per service in the last 6 hours"
A count over a day"how many errors did checkout log yesterday?"
Latency percentiles"p95 latency per endpoint in the last hour"
A user's activity"requests from user 4182 since 9am"
Distinct counts"how many distinct users called the api in the last 24 hours?"
The most common errors"top error messages from payments-worker since 9am"
A change over time"did api log more errors this hour than the previous hour?"
Recent lines"show me the newest errors from checkout"

Tips:

  • Name the service, severity, and period when you know them. "errors from checkout in the last hour" is answered more precisely than "what's wrong?".
  • Use the words in your logs. Field names and values from your log lines, such as a user ID, an order number, or http.method, help the question find the right lines.
  • Ask one thing at a time. A focused question gets a focused table, and its query ID reruns that one question.
  • Rerun instead of asking again. To watch a number over time, rerun its query ID with --since; the results come back faster and stay comparable.

Stream logs live

sazabi logs tail streams new logs from the active project as they arrive. Narrow the stream with --severities (ERROR, WARN, INFO, DEBUG, or TRACE), --services, --environments, --search, --trace-id, or --attribute key=value, and stop after a set number of seconds with --duration.

sazabi logs tail --services api --severities ERROR,WARN

Time range and retention

--since reaches back at most 90 days, and you can search only the logs your project still keeps. How long logs are kept depends on your plan; see Log storage & retention.

When the results cover a different time range than the window you asked about, the output adds a Coverage: line with the range that was covered. That happens when your logs don't reach back to the start of the window, when the window is too large to search in full (then the most recent part is covered), or when the window starts or ends partway through a minute and the whole minutes around it are counted. Narrow the window or the question to cover all of it.

Limits and answers to common questions

  • How long does a question take? A question is answered, or reported as taking too long, within about a minute. The CLI waits up to 2 minutes, then stops waiting and says so. Reruns are faster.
  • How long can a question be? Up to 2,000 characters.
  • Is there a rate limit? Asking questions and running queries from the CLI, API, SDK, or MCP count toward your organization's API rate limits. When you reach one, you get a 429; retry after a short wait. See Limits.
  • What if my question isn't about logs? A question that isn't about this project's logs is refused without searching anything, and sazabi logs ask exits with a non-zero exit code.
  • Can log search change or delete logs? No. Logs are read-only: a request to delete or change logs is answered as a question about the lines it names.
  • Do saved queries expire? No. A query ID keeps working, and reruns read whatever logs your project still keeps for the window.

Anyone who can open a project can search its logs, including people with read-only access. In a restricted project, that is its project members, plus organization owners and admins.

Further reading