# Querying data

# Introduction

Uptrace provides a powerful querying language that supports filters (where span.status.code = "error), grouping (group by span.group_id), and aggregates (p50(span.duration)).

filters

To write useful and performant queries, you need to pre-process raw data so it has a well-defined structure. You can achieve that by recording contextual information in span attributes and events. For logs you can use structured logging.

# Filters

Uptrace allows to filter spans and events by their attributes. Filters starts with the keyword where, for example, where span.name contains 'hello'.

Uptrace supports the following span attribute types:

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

You need to separate search terms in filters with a space, for example, span.status.code = "error" , but not span.status.code="error".

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 contains "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 units.
http.request_content_length > 1kbSame as http.request_content_length > 1024. Uptrace supports kb, mb, gb, and tb units.
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 expressions starts with groups by and works like the corresponding SQL clause, but in addition it also selects the grouping expression. For example, group by host.name groups spans by the attribute host.name and at the same time selects the attribute.

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 a host name.

# Aggregates

Aggregate functions perform a calculation on a set of values, and return a single value. They are often used together with grouping. Aggregates don't have a prefix.

Aggregate functionExampleNote
anyany(span.name)Any (random) span name.
avgavg(span.duration)The average span duration.
min, maxmax(span.duration)The maximum span duration.
p50, p75, p90, p99p50(span.duration)The span duration percentile.
sumsum(http.request_content_length)The total number of processed bytes.
top3, top10top3(code.function)The top 3 most popular function names.
uniquniq(http.client_ip)The number of unique IP addresses.

There is also a number of common pre-aggregated 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 for each day excluding bots:

where http.user_agent.bot not exists | uniq(http.client_ip) | group by span.start_of_day

querying