Filter Query Language
The filter bar above the trace list has two modes, and both edit the same filters:
- Builder picks a label, an operator, and values from dropdowns.
- Code writes the same filter as text, with autocomplete over the labels and values your traces actually carry.
Switch with the Builder / Code control on the right of the bar. Whatever is applied in one mode appears in the other, so you can start in the Builder and switch to Code to refine, or the other way round.
The same bar and the same language apply on the Trace Explorer and on Agent Observability.
How filters combine
Every filter has to match. Filters are joined with AND:
resource::service.name = checkout AND span_status = Error
A space between two filters means AND as well, so this is the same
query:
resource::service.name = checkout span_status = Error
Use OR when either filter will do:
span_status = Error OR span::http.status_code_int >= 500
AND binds tighter than OR, as it does elsewhere, so this:
resource::env = prod AND span_status = Error OR resource::env = staging
reads as (prod AND Error) OR staging.
In the Builder, every row after the first has an AND / OR control
in front of it. The two modes describe the same chain.
Parentheses override that order, and nest:
(resource::env = prod OR resource::env = staging) AND span_status = Error
Without them, prod OR staging AND Error would read as
prod OR (staging AND Error), which is a different question.
Parentheses that change no reading are not stored, since AND already
binds tightest: (a AND b) OR c and a AND b OR c are one filter.
The text you typed stays as you typed it, and Apply appears only when
the query says something other than what is applied.
A long query can be laid out over several lines with Shift + Enter.
A line break reads as an ordinary space, and it is kept as written.
A query with a group is edited in Code mode only. There is no builder row that draws a group, so the Builder side is disabled while one is in the query rather than flattening it into something that means something else. Remove the parentheses and the Builder comes back.
For several values of one label, prefer a list. It is shorter than
an OR chain and cheaper to run:
resource::env in (prod, staging)
resource::env = (prod or staging) means the same thing. To match none
of them, use not in:
resource::env not in (dev, test)
The Builder has the same two operators, listed straight after = and
!=: picking several values under in matches any of them, and under
not in matches none of them. Adding a second value to an = or !=
row moves it to in or not in on its own, so the row always says
what it does.
Operators
| Operator | Meaning | Example |
|---|---|---|
= | Equals | span_status = Error |
!= | Does not equal | resource::env != dev |
in (a, b) | Any of these values | resource::env in (prod, staging) |
not in (a, b) | None of these values | resource::env not in (dev, test) |
=~ | Matches a regular expression | span_name =~ "GET /api/.*" |
!~ | Does not match a regular expression | span_name !~ "^health.*" |
> >= < <= | Numeric comparison | span::http.status_code_int >= 500 |
Comparisons apply to numeric labels only. Oodle marks those with an
_int or _float suffix, and the bar offers > >= < <= only
for them.
Label names
A label is the storage column the trace API filters on:
| Form | Example | What it holds |
|---|---|---|
span::<attribute> | span::http.method | A span attribute |
resource::<attribute> | resource::k8s.cluster.name | A resource attribute |
scope::<attribute> | scope::name | An instrumentation scope attribute |
| Bare column | span_name, span_status | A trace storage column |
Autocomplete lists the labels present in the time range you are looking at, so start typing and pick from the list rather than guessing. A label the current time range has not seen is still accepted, with a note: widen the time range if you expected it.
Short names
A few common labels have a short name you can type instead. They resolve to the storage label, which is what the bar then shows:
| Short name | Resolves to |
|---|---|
service | resource::service.name |
env | resource::env |
cluster | resource::cluster |
operation | span_name |
status | span_status |
model | span::gen_ai.request.model |
agent | span::gen_ai.agent.name |
user | span::user.id |
session | span::session.id |
The dotted form of a scope prefix works too: span.http.method is read
as span::http.method.
Values
Write a value plainly when it has no spaces or punctuation:
span::http.method = GET
Quote it when it does:
span::gen_ai.agent.name = "trip planner"
Quote a value that would otherwise read as syntax, such as and, or,
in, or not:
span_name = "or"
Quotes hold whatever is inside them: commas, parentheses, a trailing
space, or a quote of its own written as \". Single quotes work too
and come back as double ones.
A value with a space and no quotes reads as a value followed by something else, so the bar says which quotes to add rather than guessing.
Keys
| Key | Action |
|---|---|
Enter | Apply the query |
Shift + Enter | Break the query onto a new line |
Escape | Put back the applied query, as you wrote it |
Space | Open suggestions for whatever comes next |
Ctrl + Space | Open suggestions at any point |
Tab | Accept the highlighted suggestion |
Suggestions never take Enter from you: nothing is preselected, so
pressing it applies the query unless you first chose an entry with the
arrow keys or Tab.
Examples
Failed checkout requests:
resource::service.name = checkout AND span_status = Error
Server errors on one endpoint:
span_name =~ "POST /api/orders.*" AND span::http.status_code_int >= 500
Production and staging, excluding health checks:
resource::env in (prod, staging) AND span_name !~ "^health.*"
One agent's calls to a specific model:
span::gen_ai.agent.name = "trip planner" AND span::gen_ai.request.model = gpt-4o
Everything a single end user did:
span::user.id = u_1042
Suggestions
Click into an empty query box and the list opens on the queries you ran most recently, ahead of the usual label suggestions. Picking one puts it back in full. When you have run none yet, the list offers examples built from labels and values your own traces carry, so a suggestion always returns something.
Suggestions open when you press space, which is where one part of a
filter ends and the next begins: pick a label, then an operator, then
a value. Choosing in (a, b) opens its parentheses and leaves the
cursor inside them, and each value you pick is followed by a comma
ready for the next one. Ctrl + Space opens the list anywhere.
Ask AI
Click Ask AI in the filter bar to describe the filter you want in plain language. The assistant opens with your request ready to send, reads the labels and values your traces carry, and writes the query into the bar. The query it writes goes through the same check a typed one does, so an attribute your traces do not have comes back as a correction rather than a filter that matches nothing.
Ask AI can also refine what is already applied. With filters in the bar, ask for a change ("only the ones over two seconds") and it updates the query in place.
Sharing a filter
The applied filters live in the page URL, so a link carries them. Copy the address bar to send a colleague the exact view you are looking at, including the time range.
Support
If you need assistance or have any questions, please reach out to us through:
- Email at [email protected]