# Search logs, traces, and metrics

> Use raw telemetry when a customer story or Issue requires a deeper service-level investigation.

Canonical page: https://anectico.com/docs/investigate/search-telemetry/


Raw signal views are the deeper layer beneath customer and Issue workflows. Use them when the problem
has no customer, when correlation is incomplete, or when you need service-wide context.

## Logs

Open **Signals → Logs** to search structured fields or use live tail. Begin with a short time range
and a service, trace ID, customer ID, or error level.

Use live tail for active reproduction, not for historical analysis. **Pause** keeps the displayed
window and its opaque server cursor; starting **Live** again resumes from that cursor and backfills
logs that arrived during the pause. Changing project, environment, query, service, or severity
starts a new scoped window; a typed query is applied once you stop typing, so a filter you are
part-way through does not keep restarting the window. The dashboard discloses when the bounded
live window drops older rows.

From the CLI:

```bash
anectico logs query --service orders-api --since 30m
anectico logs query --since 2026-08-02T21:58:18Z --until 2026-08-02T22:07:15Z
anectico logs tail --service orders-api --level error
anectico logs tail --distinct-id buyer@acme.example
```

`logs query` accepts positive lookback durations or exact RFC 3339 bounds.
Exact bounds are normalized to UTC; include `Z` or an explicit numeric offset
and make `--until` later than `--since`.

Bounded search filters include service, level, full-text query, environment, customer ID, project,
and exact structured field values discovered from the selected project and time window. Structured
field filters do not apply to live tail; clear them before starting the stream. Log results support
newest-first or oldest-first timestamp ordering; relevance ordering is not available. The CLI
reconnects from the last processed opaque cursor when a stream drops, including logs durably
received during the interruption. It uses bounded exponential backoff and suppresses repeated
stable log IDs with a 10,000-entry per-run cache; `Ctrl-C` stops it. The dashboard's **Live** button
starts the same resumable stream with supported current filters; **Pause** returns to bounded search
without discarding the live cursor or buffer.

**Refresh** resolves a relative preset such as **Last 24 hours** against the current clock, then
reloads the log rows, structured-field choices, and patterns for that same window. An explicit
start/end window is queried again without moving either bound.

Search counts are exact for the complete selected project, time window, and filter set, regardless
of the current page. Matched text is highlighted as escaped literal text by the dashboard; the API
does not claim or return server-computed highlight ranges. Field discovery is deliberately bounded:
`values_truncated` and `fields_truncated` disclose when more values or structured keys exist.

Expand a row to inspect the complete multiline message, host, pod, logger, source, resource fields,
log attributes, trace/customer links, and surrounding context. **Copy log link** preserves the
durable log ID, search/filter/time state, and whether context is open. Reloading that URL fetches the
exact entry even if it is outside the current result page, or reports honestly when retention has
removed it. The **Patterns** panel summarizes repeated templates in the current project and window.

A template may also carry a small **category** chip — `database`, `auth`, `external_call` and nine
others — and a **Needs attention** marker when it reads as a degraded or failing situation rather
than ordinary traffic. Both are hints, and neither ever hides, filters or reorders anything: the
panel always lists every cluster that met the threshold, largest first, labeled or not.

Labels are worked out after a read, so a template you are seeing for the first time carries none and
picks one up the next time you open the panel. A template showing neither a chip nor a marker means
one of exactly two things: nothing has labeled it yet, or labeling was unavailable — and when the
reason is known the panel says so in a muted line, for example when your plan's daily
decision-scoring cap has been reached (see [plans and limits](/docs/reference/limits)). There is no
"routine" or "low severity" badge anywhere in the panel. "Not flagged" and "not looked at yet" are
indistinguishable from the marker alone, and showing one as the other would be a judgment the
labeling is not accurate enough to make. A category is shown only when it is confident enough to be
worth having; below that the template is left honestly uncategorized rather than probably wrong.

For a custom SSE consumer:

```bash
curl -N \
  -H "X-Anectico-API-Key: $ANECTICO_API_KEY" \
  "https://app.anectico.com/api/v1/stream/logs?project_id=$ANECTICO_PROJECT&level=error"
```

Send `Accept: text/event-stream` in production clients. Each `data:` frame contains one JSON log
with a stable `log_id`, the same source/runtime/resource fields as historical search, and an opaque
`resume_cursor`; the SSE `id` is that same cursor. Save it only
after processing the frame, then reconnect with `Last-Event-ID` and bounded backoff. `since` is only
an explicit initial time and is ignored once a cursor exists. Treat cursors as opaque and keep the
same project and filters. Cursors are unsigned encoded positions, not credentials; authenticated
scope remains authoritative. Unauthorized or server-disabled streams require credentials or server
configuration to change before retrying.

**A live tail keeps re-checking the credential it opened with**, roughly every 30 seconds, so
revoking the key, freezing it, or narrowing its scopes ends the stream rather than letting it run on.
The last thing you receive is an `error` frame carrying a reason and a `terminal` flag: `unauthorized`
or `forbidden` marked terminal means reconnecting cannot repair it and your client should stop, while
a frame that is *not* marked terminal means the credential simply needs re-establishing — reconnect
with backoff from your saved cursor. A signed-in browser session ends this way when its authorization
expires (see [Revoke agent access](/docs/agents/revoke-agent-access)); the dashboard re-establishes
and resumes on its own.

## Traces

Open **Signals → Traces** to inspect requests and spans. Filter by service, duration, status, or
customer identity. In a trace, start with the critical path and error spans, then open correlated
logs.

Drag the separator beside **Operation** to widen or narrow the span-name column. The separator also
supports the arrow keys, **Home**, and **End** when focused. If a wide operation column no longer
fits in the card, scroll the timeline horizontally; Anectico preserves the requested width instead of
clipping long operation names.

Use the **Status** selector for **All statuses**, **Successful**, or **Errors**. Anectico applies this
trace-level filter before pagination, so an empty page means no matching trace exists in the selected
project, environment, and time range. The selection is preserved in the URL (`status=ok` or
`status=error`) for reliable sharing and browser navigation. A submitted trace, service, operation,
or customer search is also preserved as `query=...`. When you open a trace from filtered results,
**Back to traces** restores that exact status and search context so you can inspect multiple samples
without rebuilding the investigation.

Use **Attributes** to add an exact, case-sensitive span attribute filter such as
`cache.result=hit` or `http.route=/checkout/{id}`. Multiple attribute filters require every
key/value pair to occur in the trace, though the pairs may occur on different spans. Each active
filter appears as a removable chip. Attribute filters are also preserved in the URL using readable
parameters such as `attribute.cache.result=hit`, and remain active when you open a trace and return
to the results.

The **LLM Costs** tab is a trace-backed view of model calls and token cost.

## Metrics and services

Use **Metrics**, **Services**, and **Service Map** for symptoms that affect a broad service or have no
customer identity, such as queue backlog or infrastructure saturation.

On **Metrics**, select the metric, inspect its unit and available label values, optionally group by
one label, then choose the aggregation, bucket interval, and time range. Use a dashboard when you
need label filters, two grouping dimensions, multiple targets, formulas, or a native histogram.
Metrics identify when and where behavior changed; use the matching time window in traces and logs to
explain why.

See [Explore and compare metrics](/docs/investigate/metrics) for aggregation semantics, dashboard
queries, forecasts, CLI examples, and common misleading results.

## Save repeatable work

Save a search when the same filter is useful during future incidents. Create a dashboard only for a
question the team expects to revisit; avoid dashboards that duplicate an existing customer, Issue,
or service view.

## Keep the investigation connected

Whenever a raw signal contains a customer, Issue, trace, release, or replay link, follow it instead of
copying identifiers between tabs. The value of Anectico is the connected path, not the number of query
builders available.

## When live tail is empty

The stream carries newly ingested logs and bounded resumable catch-up. Run
`anectico logs query --since 5m`, remove filters, and confirm the active project before investigating
the streaming connection. Proxies that buffer or time out SSE can repeatedly end a healthy stream;
the dashboard and CLI resume automatically, but custom clients must retain the last SSE id.

- [Understand a customer's complete story](/docs/investigate/customer-story)
- [Explore and compare metrics](/docs/investigate/metrics)
- [Save searches and export data](/docs/manage/save-and-export-data)
