Documentation menu
Source pipelines
Select multiple measurements with aliases and units, enrich dimensions, and rank entities.
Source pipeline syntax
from SOURCE
[ | where DIM OP VALUE [and DIM OP VALUE ...] ]
| summarize AGG(FIELD) as ALIAS [, AGG(FIELD) as ALIAS ...]
[by DIM [, DIM ...]]
[ | join left|inner (SOURCE_QUERY) as NAME on (DIM [, DIM ...]) ... ]
[ | extend ALIAS = EXPRESSION [, ALIAS = EXPRESSION ...] ... ]
[ | order by ALIAS_OR_GROUP_DIMENSION [asc|desc] [ | limit INTEGER ] ]
Square brackets above describe optional syntax; do not type them. For an alert,
finish with | pick ALIAS instead of ordering or limiting. A joined query may
use extend, but cannot contain joins, ordering, limits, or pick.
The order of stages matters: filter before summarizing, join before calculating,
and calculate before ranking. Use unique aliases. by (agent_id, test_id) and
by agent_id, test_id are both accepted in source queries. The available
sources include tests, host_resources, containers, kubernetes, custom,
traces, and otel_logs; use the
source’s field suggestions for exact supported names.
See OpenTelemetry queries for imported metric selectors, received trace/log aggregation and profile detail access.
Filters use =, !=, =~, !~, in, or not in. Separate source filters
with and, and selector filters with commas inside {...}. Source filter
values are quoted strings, with bare true and false also accepted.
Aggregations are avg, min, max, sum, count, p50, p90, p95, p99,
rate, and increase.
Query test measurements
from tests accepts the same full metric names as single-metric selectors,
including built-in checks, typed host/container/Kubernetes metrics, and custom
script metrics. Each selected metric reads its registered storage source.
from tests
| where test.name =~ "API.*" and agent.name = "East office"
| summarize p95(http_check_total_ms) as latency,
avg(http_check_passed) as pass_rate
by test_type, test_id, test.name, agent_id, agent.name
| order by agent.name asc
Use test_id or test.id for an exact test definition, test.name for its
current name, and test_type for the check type recorded on each observation.
For example, where test_type in ("http_check", "dns_check") selects those
check types. A test with multiple checks has a separate test ID for each check.
test.group_id selects the containing test group.
Autocomplete shows agent and test names alongside their IDs. Selecting a name in an ID filter inserts the ID; selecting one in a name filter inserts the quoted name. At the start of a filter, an entity suggestion inserts a complete ID filter. Duplicate names remain distinguishable by ID.
This source queries measurements, not a test inventory: absent samples remain
absent, and count(metric) counts observed metric samples, not configured tests.
Use full metric names here; source-local fields such as cpu_percent still
belong to their specific source. Every selected metric must support the requested
filters and grouping dimensions. Different outputs keep their own units and
measurement provenance; selecting them together does not imply a shared execution.
Multiple measurements from one source
Use a source query to select several measurements, each with its own aggregation, alias, and unit:
from host_resources
| where resource_kind = "process" and monitored = true
| summarize avg(cpu_percent) as cpu,
max(rss_bytes) as memory,
max(threads) as threads
by agent_id, process_name
| order by cpu desc
| limit 20
The editor completes source names, available fields, units, and grouping
dimensions. tests accepts full metric names across sources. The specific sources
host_resources, containers, kubernetes, and custom accept their registered metric names and the local field names
listed by the editor. custom also accepts exact names emitted by your scripts.
Each alias produces a separate series; memory stays in bytes while CPU stays in
percent. Missing CPU does not discard an available memory reading. For host
resources, filter resource_kind to process, service, or interface when
using local fields so process samples and service totals are not combined.
order by ranks entities within each time bucket, and all selected
measurements follow that ranking. It can name a selected output or a grouping
dimension, such as agent.name, agent_id, or test_type. Dimension ordering
is lexicographic; empty metadata sorts last in either direction. An output alias
takes precedence if it shares a dimension’s name. Missing ordering values sort last; ties break
by grouping values. limit requires an order and accepts 1–200 entities per
bucket. Winners may change over time. Queries accept up to 16 measurements;
the overall series limits still apply across all measurements and buckets.
Filters use and with the existing matcher operators. Quote values, except
that true and false are accepted for dimensions such as monitored.
Agent and test relationships
Both source queries and existing metric selectors can filter and group by
agent.name, agent.site, test.name, and test.group_id:
from tests
| where agent.site = "east"
| summarize p95(http_check_total_ms) as latency,
avg(http_check_passed) as pass_rate
by agent_id, agent.name, test_id, test.name
The relationship follows the agent and test IDs stored on each observation.
Changing a test’s assignment does not change those historical IDs. Names, sites,
and group membership are current metadata: renaming an agent changes its
display name on the next query, including historical results. agent.site reads
the agent’s site agent tag. agent.id and test.id are also accepted as
aliases for the observation IDs.
Group by IDs as well as names to keep similarly named entities distinct. Unresolved or deleted metadata produces an empty dimension value. Enrichment never multiplies measurements. Agent names include public workers, so you can find their IDs and filter their results by name. Measurements still belong to your tenant’s tests; a public agent name does not grant access to other tenants’ results, provider site labels, or host telemetry. Other metadata remains owned by your tenant. Learned baselines and baseline bands require stable IDs instead of these current-metadata fields.
Selecting an output for an alert
An alert condition must choose one output with pick:
from host_resources
| where resource_kind = "service" and process_name = "postgres"
| summarize avg(cpu_percent) as cpu, max(rss_bytes) as memory
by agent_id
| pick cpu
Set the CPU threshold using the condition editor. A second condition can select
memory; the rule’s all/any mode combines the conditions. The grouping must
match the rule’s scope. A picked query rejects ordering and limits so every
scoped entity can be evaluated. An unpicked source query is rejected as an alert
condition, even if it currently selects just one measurement.
For learned-baseline conditions, pick can select one measured output using
avg, min, max, or a percentile. Use stable IDs and recorded labels. Source
identity and local fields are retained when learning history. Joins, calculated
outputs, totals, counts, counter conversions, reductions, and rankings require
their own output history and cannot use this sample-based baseline. Choose
Against the baseline in the condition editor; a source pipeline cannot append
a baseline(...) or deviation(...) stage in its query text.
See Advanced health-rule recipes for conditions
scoped by test and agent, monitored-service absence, and agent probe budgets.