Skip to main content

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

OperatorMeaningExample
=Equalsspan_status = Error
!=Does not equalresource::env != dev
in (a, b)Any of these valuesresource::env in (prod, staging)
not in (a, b)None of these valuesresource::env not in (dev, test)
=~Matches a regular expressionspan_name =~ "GET /api/.*"
!~Does not match a regular expressionspan_name !~ "^health.*"
> >= < <=Numeric comparisonspan::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:

FormExampleWhat it holds
span::<attribute>span::http.methodA span attribute
resource::<attribute>resource::k8s.cluster.nameA resource attribute
scope::<attribute>scope::nameAn instrumentation scope attribute
Bare columnspan_name, span_statusA 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 nameResolves to
serviceresource::service.name
envresource::env
clusterresource::cluster
operationspan_name
statusspan_status
modelspan::gen_ai.request.model
agentspan::gen_ai.agent.name
userspan::user.id
sessionspan::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

KeyAction
EnterApply the query
Shift + EnterBreak the query onto a new line
EscapePut back the applied query, as you wrote it
SpaceOpen suggestions for whatever comes next
Ctrl + SpaceOpen suggestions at any point
TabAccept 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: