Querying¶
Uptrace provides a powerful querying language that supports filters (WHERE
), grouping (GROUP BY
), and aggregates (sum(amount)
).
To write useful and fast queries you have to clean and structure your data. To record contextual information in spans you should use semantic attributes. For logs to achieve the same you should use structured logging.
Filters¶
Filtering allows to filter spans and events by their attributes. The following span attribute types are supported:
Attribute type | Supported comparison operators |
---|---|
string | = , like , contains , exists . |
int64 and float64 | = , < , <= , > , >= , exists . |
array of the types above | contains , exists . |
For example:
Uptrace filter | Note |
---|---|
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.duration > 1ms | Same as span.duration > 1000 . Uptrace supports μs , ms , and s . |
http.request_content_length > 1kb | Same as http.request_content_length > 1024 . Uptrace supports kb , mb , gb , and tb . |
span.event.count > 0 | Filters spans with events. |
span.event.error_count > 0 | Filters spans with error events. |
span.event.log_count > 0 | Filters spans with log events. |
span.event.name exists | Filters 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 grouping | Note |
---|---|
span.group_id | Groups similar spans together. |
span.start_of_minute | Groups spans by the minute they were created. Uptrace also supports grouping by hour, day, and week. |
host.name | Groups 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 function | Note |
---|---|
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 column | Note |
---|---|
span.count | The equivalent of SQL count(*) . |
span.error_count | The number of spans with span.status.code = 'error' . |
span.error_pct | The result of span.error_count / span.count . |
span.rate | The average number of spans per minute. |
Combining all together¶
You can write powerful queries combining filtering, 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