# Querying data

# Introduction

Uptrace provides a powerful querying language that supports filters (WHERE), grouping (GROUP BY), and aggregates (sum(amount)).


To write useful and performant queries make sure your data is well-structured. It can be achieved by recording contextual information in spans using semantic attributes. For logs you should use structured logging.

# Filters

Filtering allows to filter spans and events by their attributes. The following span attribute types are supported:

Attribute typeSupported comparison operators
string=, like, contains, exists, ~.
int64 and float64=, <, <=, >, >=, exists.
array of the types abovecontains, exists.

You must separate search terms with a space. For example, span.status.code = "error" works, but span.status.code="error" doesn't.

Uptrace filterNote
span.status.code = "error"Filters spans with error status code. Case-sensitive.
span.name like "hello%"Filters span names that start with "hello". Case-insensitive.
span.name like "%hello"Filters span names that end with "hello". Case-insensitive.
span.name contains "hello"Filters span names that contain "hello". Case-insensitive.
span.name ~ "foo|bar"Same as span.name contains "foo" OR span.name contains "bar".
span.duration > 1msSame as span.duration > 1000. Uptrace supports μs, ms, and s.
http.request_content_length > 1kbSame as http.request_content_length > 1024. Uptrace supports kb, mb, gb, and tb.
span.event.count > 0Filters spans with events.
span.event.error_count > 0Filters spans with error events.
span.event.log_count > 0Filters spans with log events.
span.event.name existsFilters span events (spans that have span.event.name attribute).

# Grouping

Grouping works like SQL GROUP BY, but in addition it also selects the grouping expression.

Uptrace groupingNote
span.group_idGroups similar spans together.
span.start_of_minuteGroups spans by the minute they were created. Uptrace also supports grouping by hour, day, and week.
host.nameGroups spans by the hostname.
lower(host.name)Groups spans by the lower-cased hostname.

# Aggregates

Aggregate functions perform a calculation on a set of values, and return a single value. You often use them together with grouping.

Aggregate functionNote
any(span.name)Any (random) span name.
avg(span.duration)The average span duration.
max(span.duration)The maximum span duration.
min(span.duration)The minimum span duration.
p50(span.duration)The span duration percentile.
sum(http.request_content_length)The total number of processed bytes.
top3(code.function)The top 3 most popular function names.
uniq(http.client_ip)The number of unique IP addresses.

There is also a number of common pre-calculated columns:

Virtual columnNote
span.countThe equivalent of SQL count(*).
span.error_countThe number of spans with span.status.code = 'error'.
span.error_pctThe result of span.error_count / span.count.
span.rateThe average number of spans per minute.

# Combining all together

You can write powerful queries combining filters, grouping, and aggregates together. For example, to select the number of unique visitors (excluding bots) for each day:

filters:    http.user_agent.bot not exists
aggregates: uniq(http.client_ip)
grouping:   span.start_of_day