Logstreem
Aggregations

Aggregations

The functions that live inside summarize.

Aggregations collapse many rows into one value. They only appear inside summarize.

FunctionReturnsNote
count()Row countTakes no argument
countif(predicate)Rows matching the predicateThe clean way to get an error rate
dcount(field)Approximate distinct countHyperLogLog, ~1% error above 10k
dcountif(field, predicate)Conditional distinct count
sum(field) / sumif(field, p)Sum
avg(field)MeanNulls excluded from both sum and count
min(field) / max(field)ExtremesWorks on datetimes
percentile(field, p)One percentilepercentile(latency, 95)
percentiles(field, p1, p2, …)Several at onceCheaper than repeating percentile
stdev(field) / variance(field)Spread
make_list(field) / make_set(field)Array of values / distinct valuesCapped at 1,048,576 elements
arg_max(byField, …) / arg_min(…)The whole row at the extreme"The slowest request, with all its context"

The error-rate pattern

countif in the same summarize as count is how you get a rate without a self-join.

LSQL
read top to bottom
1['api-gateway-prod']
2| summarize requests = count(), errors = countif(status >= 500) by service
3| extend error_rate = round(100.0 * errors / requests, 2)
4| where requests > 100
5| order by error_rate desc

arg_max: the row, not the number

max(latency) tells you the worst latency. arg_max(latency, *) tells you *which request* it was, with every field attached — usually the thing you actually wanted.

LSQL
read top to bottom
1['api-gateway-prod']
2| where status >= 500
3| summarize arg_max(latency, *) by service
4| project service, latency, route, region, message

dcount is approximate on purpose

Exact distinct counts over billions of rows need memory proportional to cardinality. dcount uses HyperLogLog: ~1% error, constant memory. When you need exactness on a small set, summarize by field | count is exact.