Filters

Filter an alert to a slice of your traffic — one agent, one tool, one model, one customer — with rules on run and span fields, metadata and attributes.

Without a filter, an alert watches every run or span in your team. A filter narrows it to the slice you actually care about, and it is what turns "latency is up" into "latency on charge_card is up".

Filters decide which rows are counted, not what is measured. The measure and aggregation still do their job; they just do it on fewer rows.

Rules and groups

A rule is field · operator · value — for example span.tool_name is charge_card.

Rules sit in groups. Inside a group you choose AND (every rule must match) or OR (any rule). Add more groups to build something like "this agent, and either of these two tools".

Two rules on the same field with is are usually a mistake — status is ok AND status is error matches nothing. Use is with a list of values instead, which matches any of them.

Fields you can filter on

Run fields

FieldType
Agentstring
Statusstring
Duration (ms)number
Costnumber
Tokens in / Tokens outnumber
Tool callsnumber
Spansnumber
Errorsnumber
Error typestring
Error messagestring
Levelstring
Userstring
Conversationstring
Parent runstring
Feedback ratingnumber
Satisfactionnumber
Ragenumber

Span fields

FieldType
Agentstring
Kindstring
Namestring
Statusstring
Toolstring
Modelstring
Providerstring
Duration (ms)number
Costnumber
Tokens in / Tokens outnumber
Error typestring
Error messagestring
Userstring
Conversationstring

Your own metadata and attributes

Anything you attach to a run as metadata, or to a span as attributes, is filterable too. Trodo discovers the keys your team actually sends and offers them in the field picker alongside the built-in ones, so a tenant, a plan or a release you record shows up without any configuration.

This is the mechanism for per-customer alerting. Send metadata: { tenant: "acme" } on your runs and you can build an alert that watches only Acme's error rate — with its own threshold, separate from everyone else's.

A span alert can also filter on run fields. "Slow tool calls, but only inside runs of the checkout-assistant agent" is one alert, not two.

Operators

OperatorApplies toNotes
is / is notstring, numberAccepts a list — status is [error, timeout] matches either.
contains / does not containstringSubstring, case-insensitive.
starts with / ends withstring
is above / is at or abovenumber
is below / is at or belownumber
is set / is not setstring, numberWhether the field has a value at all. No value to type.

For error messages, prefer contains over is. An exact message picks up an id or a duration in the next release and the alert goes silent without telling you. error_message contains "rate limit" keeps working.

Two rules worth knowing

A missing value matches no comparison. A run with no recorded duration does not match duration is below 1000 — it is not treated as zero. This is what the table shows you and what SQL answers, and it stops "below" filters from silently sweeping up every incomplete row.

To catch rows that have no value, ask for that directly with is not set.

There are no time filters. The alert's window is the time filter. A second, disagreeing time rule inside it would be a trap — a 15-minute window with a "last 24 hours" rule inside it means nothing coherent — so the option isn't offered.

Examples

One agent's latency

run.agent_name  is  checkout-assistant

A specific tool, only when it errors

span.tool_name   is      charge_card
AND span.status  is      error

One model across every agent

span.model  is  gpt-4o-mini

One customer, from your own metadata

run.metadata.tenant  is  acme

Everything except your own test traffic

run.metadata.environment  is not  staging

Slow tool calls, but only inside one agent's runs

span.kind             is        tool
AND run.agent_name    is        checkout-assistant
AND span.duration_ms  is above  2000

Next

On this page