Dashboard YAML Templates

Uptrace dashboards can be defined as YAML templates. Templates are used for built-in dashboards that ship with Uptrace and for importing/exporting user-created dashboards.

When Uptrace receives new metrics, it checks available templates and automatically creates matching dashboards.

Template structure

Every template starts with a schema: v2 header followed by metadata, then the layout of the dashboard and optional metric_monitors.

yaml
schema: v2
name: 'Hostmetrics: Overview'
description: Tracks host CPU, memory, and system load.
tags: [otel, infra]
version: v26.11.05
setup_link: https://example.com/setup
doc_link: https://example.com/docs

# Optional: minimum query interval
min_interval: 1m

# Optional: shift the query time window
time_offset: 5m

# Optional: only apply when these metrics exist
metrics_match:
  present:
    - metric: system_cpu_utilization
    - library: io.opentelemetry.instrumentation.system
      metric: system_cpu_time

layout:
  items: [] # the widgets or the groups of the dashboard

metric_monitors: [] # bundled alert monitors

Top-level fields

FieldTypeRequiredDescription
schemastringyesMust be "v2"
namestringyesHuman-readable dashboard title
descriptionstringnoSummary of the dashboard's purpose, shown in the template list
tagslistyesCategorization labels (see Tags)
versionstringyesRevision in vYY.MM.DD format (e.g., v26.11.05)
setup_linkstringnoURL to instrumentation/setup instructions
doc_linkstringnoURL to documentation
min_intervaldurationnoMinimum query interval (e.g., 1m, 5m)
time_offsetdurationnoShifts query time window (e.g., 5m)
default_time_perioddurationnoTime period the dashboard shows when it opens without a stated range (e.g., 1h)
tooltips_connectedboolnoWhether a hover on one chart marks the same time on every chart. Defaults to true
max_widthstringnoPage width: none (default), small, medium, large, or extra_large
variableslistnoAttribute names the filter bar of the dashboard offers as variables
metrics_matchobjectnoMetrics that must, or must not, exist before the template is applied (see Metric requirements)
layoutobjectnoThe root of the layout (see Layout)
metric_monitorslistnoMetric monitors bundled with the template (see Metric monitors)

Metrics and queries

Metrics and queries appear throughout the template (tables, grid items, monitors). They follow the same pattern everywhere.

Metrics

The metrics field declares metric aliases using MQL syntax:

yaml
metrics:
  - system_cpu_utilization as $cpu_util
  - system_memory_usage as $mem_usage

Each entry takes the form metric_name as $alias. The alias (prefixed with $) is used in queries.

Query

The query field is a list of MQL clauses. Splitting across lines improves readability -- clauses are joined into a single query during processing.

yaml
query:
  - group by host_name
  - avg($cpu_util) as cpu_avg
  - sum($mem_usage{state="used"}) as mem_used
  - where device !~ "loop"

Common clause patterns:

  • Aggregations: avg($x), sum($x), max($x), min($x), p50($x), p75($x), p90($x), p99($x)
  • Rate functions: perMin(sum($x)), perSec(sum($x))
  • Counting: histogram_count($x), uniq($x, attr_name)
  • Grouping: group by attr_name, group by attr1, attr2
  • Filtering: where attr = "value", where attr !~ "pattern"
  • Aliasing: sum($x) as my_alias
  • Inline grouping: avg($x) as y group by state
  • Attribute filtering: $metric{state="used"}, $metric{direction=read}
  • Arithmetic: sum($a) / sum($b) as ratio

Layout

The layout key holds the root of the dashboard. The root and each group are a body: a list of items with the fields that arrange them. An item is a widget or a group, and its type selects which: omit it or state chart for a chart, a widget type for a widget of that type, or group for a group. A body holds widgets or groups, never both.

yaml
layout:
  mode: tabs
  items:
    - type: group
      title: CPU
      items:
        - title: CPU utilization
          metrics:
            - system_cpu_utilization as $cpu_util
          query:
            - avg($cpu_util)

    - type: group
      title: Memory
      items:
        - title: Memory utilization
          metrics:
            - system_memory_utilization as $mem_util
          query:
            - avg($mem_util)

Modes

The mode of a body states how it arranges its items:

ModeHoldsDescription
autowidgetsA grid of columns. Each widget takes one cell, or the full width with full_width: true. All grid rows have one height
customwidgetsEach widget in the cell its grid_pos states, on a grid of 24 columns
rowsgroupsGroups one under another, each with a header that collapses it
tabsgroupsGroups as tabs. The dashboard shows one group at a time

Without mode, a body that holds groups is rows, a body whose widgets state grid_pos is custom, and any other body is auto. When a body that states no mode lists widgets beside groups, Uptrace puts each run of widgets in a group with no header. A rows or tabs body holds groups only, and Uptrace refuses a widget in it.

Body fields

FieldTypeDescription
modestringauto, custom, rows, or tabs (see Modes)
itemslistThe widgets or the groups of the body, in the order the body shows them
columnsintColumns of an auto body, 1 to 12
column_width_modestringNarrowest column of an auto body: narrow, standard, wide, auto, or custom
column_widthintNarrowest column in pixels when column_width_mode is custom
row_height_modestringHeight of the grid rows of an auto body: short, standard, tall, or custom
row_heightintGrid row height in pixels when row_height_mode is custom
fit_contentboolWhether a widget that can fit its content grows or shrinks to it
fit_min_height_modestringLeast height of a widget that fits its content: none, short, standard, tall, or custom
fit_min_heightintLeast height in pixels when fit_min_height_mode is custom
fit_max_height_modestringMost height of a widget that fits its content: short, standard, tall, or custom
fit_max_heightintMost height in pixels when fit_max_height_mode is custom
match_tallestboolWhether all widgets of a grid row take the height of the tallest one when fit_content is on

Groups, rows and tabs

A group is an item with type: group. It is a body too, so it takes all the body fields, and it holds widgets or other groups. A group in a rows body is a row with a header, and a group in a tabs body is a tab.

yaml
- type: group
  title: Gauges
  columns: 6
  column_width_mode: narrow
  items:
    - title: Availability
      type: stat
      metrics:
        - httpcheck_status as $status
      query:
        - sum($status{http_status_class="2xx"}) / sum($status) as availability
      columns:
        availability: { unit: utilization }
FieldTypeRequiredDescription
typestringyesAlways group
titlestringnoHeading above the widgets. Omit it for a group with no heading
descriptionstringnoExplanation shown below the heading
collapsedboolnoShow the group closed when the dashboard loads. Only a group with a header can close
hide_headerboolnoShow no header. The group then only arranges its widgets
itemslistyesThe widgets or the groups of the group

Table widgets and linked grids

A table widget in the root can link a grid: a layout of its own that a row of the table opens, filtered to the group by values of that row. The grid key of the table widget holds it. It is a body, so it takes the same fields as layout.

yaml
layout:
  items:
    - type: table
      title: Hosts
      metrics:
        - system_cpu_utilization as $cpu_util
        - system_memory_usage as $mem_usage
      query:
        - group by host_name
        - avg($cpu_util) as cpu_util
        - sum($mem_usage{state="used"}) as mem_used
      columns:
        cpu_util: { unit: utilization }
        mem_used: { unit: bytes }
      grid_variables: [deployment_environment, service_name]
      grid:
        items:
          - type: group
            title: General
            items:
              - title: CPU utilization
                metrics:
                  - system_cpu_utilization as $cpu_util
                query:
                  - avg($cpu_util)

Only a table widget in the root links a grid. The grid keys of a table widget:

FieldTypeDescription
gridobjectThe linked grid. An empty mapping (grid: {}) links an empty grid
grid_querystringA where clause that each widget of the grid starts from, joined with the row a reader opened
grid_variableslistAttribute names the filter bar of the grid offers, beside the grouping attributes of the table
grid_includelistOther templates whose root items are appended to the grid (see Composition)

See Table for the other fields of a table widget.

Widgets beside the table

The root can hold other widgets beside the table, for example a summary above it. They are ordinary widgets of the root:

yaml
layout:
  items:
    - title: Number of hosts
      type: text
      metrics:
        - system_memory_usage as $mem_usage
      query:
        - uniq($mem_usage, host_name) as num_host
      text: ${num_host} hosts

    - type: table
      title: Hosts
      metrics:
        - system_memory_usage as $mem_usage
      query:
        - group by host_name
        - sum($mem_usage{state="used"}) as mem_used

Widget types

The type field of an item selects the widget. When type is omitted, the widget is a chart.

Common fields

All widget types share these fields:

FieldTypeRequiredDescription
titlestringyesDisplay heading. An empty title (title: "") shows the widget with none
descriptionstringnoExplanation shown below the title
typestringnoOne of: chart (default), table, stat, gauge, pie, heatmap, text
full_widthboolnoIn an auto body, take the full width (true) or one cell (false). A table defaults to true, other types to false
grid_posobjectnoIn a custom body, the cell on one line: {w: 12, h: 20, x: 0, y: 0}. A widget states grid_pos or full_width, not both
heightstringnoIn a custom body, content (fit the content) or fixed (the rows grid_pos states)

Chart

Charts are the default grid item type. They render time-series data as line, bar, or scatter plots.

yaml
- title: CPU time
  # type: chart (default, can be omitted)
  metrics:
    - system_cpu_time as $cpu_time
  query:
    - perMin(sum($cpu_time)) as cpu_time group by state
  fill_opacity: 0.1

Chart-specific fields

FieldTypeDescription
metricslistMQL metric expressions
querylistMQL query clauses
chartstringChart type: line (default), bar, scatter
tooltipobject{mode, sort_order}: what the tooltip shows, and in which order
sort_bylistColumns the legend table sorts the series by
max_data_pointsintMost datapoints the chart reads
min_intervaldurationLower bound for the grouping step
fill_opacityfloatArea fill opacity, 0 to 1
stackstringStacking mode: "" (none) or "all"
columnsmapPer-metric display settings with unit and color
legendobjectLegend configuration (see below)
propertieslistVisual properties (see Visual properties)
overrideslistPer-timeseries overrides (see Timeseries overrides)

Legend configuration

yaml
legend:
  type: table     # "none", "list", or "table"
  placement: bottom # "bottom" or "right"
  values: [avg, min, max, last]
  items_per_page: 10

Table

Table widgets show query results in rows with sortable columns.

yaml
- title: Slowest groups
  type: table
  metrics:
    - uptrace_tracing_spans as $spans
  query:
    - group by _group_id
    - group by _system
    - p50($spans)

Table-specific fields

FieldTypeDescription
metricslistMQL metric expressions
querylistMQL query clauses
columnsmapPer-column display settings (see Column settings)
overrideslistPer-column visual property overrides (see Column overrides)
items_per_pageintRows on one page of the table. Defaults to 5
compact_tableboolShow the rows with less padding. Defaults to true
lines_per_rowintLines of text one row shows. Defaults to 1
nulls_modestringHow a cell with no value shows: keep, replace, or connect
sort_bylistColumns the table sorts its rows by
grid, grid_query, grid_variables, grid_includeThe linked grid (see Table widgets and linked grids)

Column settings (shorthand)

The columns map provides a compact syntax for column formatting:

yaml
columns:
  cpu_util: { unit: utilization }
  mem_used: { unit: bytes, color: red }
  availability: { unit: utilization, agg_func: avg }
  max_latency: { unit: milliseconds, agg_func: max, display: bar }

Available column properties:

PropertyDescription
unitDisplay unit (e.g., bytes, utilization, seconds, nanoseconds, milliseconds, 1, or custom like span/min)
colorDisplay color
agg_funcAggregation function (e.g., sum, avg, max, last)
displayColumn display mode: value (default), sparkline, or bar. Can also be a map: {mode: bar, min: 0, max: 1}

Column overrides (structured)

The overrides format provides more control:

yaml
overrides:
  - column: cpu_util
    properties:
      - name: unit
        value: utilization
      - name: color
        value: red

Stat

Stat widgets show a single aggregated value as text, optionally with value mappings for status labels.

yaml
- title: Status
  type: stat
  metrics:
    - httpcheck_status as $status
  query:
    - sum($status{http_status_class="2xx"})
  value_mappings:
    - op: any
      text: UNKNOWN
      color: gray
    - op: eq
      value: 0
      text: DOWN
      color: red
    - op: gte
      value: 1
      text: UP
      color: green

Stat-specific fields

FieldTypeDescription
metricslistMQL metric expressions
querylistMQL query clauses
columnsmapPer-column settings with unit and agg_func
overrideslistPer-column visual property overrides
value_mappingslistMaps values to labels and colors

Value mappings

Value mappings are evaluated in order, and the last matching rule wins, so a lower rule overrides the rules above it. Put the catch-all (any) first, and the more specific rules below it.

FieldTypeDescription
opstringComparison operator: any, eq, lt, lte, gt, gte
valuenumberThreshold value (not required for any)
textstringDisplay label. An empty label keeps the number
colorstringDisplay color

Gauge

Gauges draw a single value on a dial, against the scale they state.

yaml
- title: CPU utilization
  type: gauge
  metrics:
    - system_cpu_utilization as $cpu
  query:
    - avg($cpu) as cpu
  columns:
    cpu: { unit: utilization }
  scale_min: 0
  scale_max: 1

Gauge-specific fields

FieldTypeDescription
metricslistMQL metric expressions
querylistMQL query clauses
columnsmapPer-column settings with unit and agg_func
overrideslistPer-column visual property overrides
value_mappingslistMaps values to labels and colors (see Value mappings)
scale_minnumberValue the dial starts at. Defaults to 0
scale_maxnumberValue the dial ends at. Must be greater than scale_min
shapestringarc (default) or circle
bar_capstringflat (default) or rounded
bar_width_factornumberBar thickness as a fraction of the radius. Defaults to 0.3
sparklineboolShow a small trend chart beside the value

Pie

Pie widgets show the share of each group, or of each column when the query has no grouping.

yaml
- title: Memory by state
  type: pie
  metrics:
    - system_memory_usage as $mem
  query:
    - avg($mem) as mem
    - group by state
  columns:
    mem: { unit: bytes }

Pie-specific fields

FieldTypeDescription
metricslistMQL metric expressions
querylistMQL query clauses. With a grouping, state one value column
columnsmapPer-column settings with unit and agg_func
overrideslistPer-column visual property overrides
shapestringdonut (default) or pie
slice_stylestringflat (default) or rounded
slice_gapboolPart the slices with a small gap. Defaults to true
color_schemestringdefault, carbon, sequential-reds, sequential-greens, or sequential-blues
max_slicesintMost slices the pie shows. Defaults to 8
other_sliceboolSum the smallest slices above max_slices into one slice named Other. Defaults to true
legendobjectLegend configuration
labelsobjectSlice label configuration

Heatmap

Heatmaps visualize the distribution of a single histogram metric over time.

yaml
- title: Span duration heatmap
  type: heatmap
  metric: uptrace_tracing_spans
  unit: milliseconds

Heatmap-specific fields

FieldTypeDescription
metricstringSingle metric name (not an alias)
unitstringDisplay unit
querylistOptional MQL query clauses for filtering

Text

Text widgets render a Go template string with metric data, useful for summary counts and labels.

yaml
- title: Host count
  type: text
  metrics:
    - process_runtime_go_goroutines as $goroutines
  query:
    - uniq($goroutines, host_name) as num_host
  text: ${num_host} hosts

Text-specific fields

FieldTypeDescription
metricslistMQL metric expressions
querylistMQL query clauses
textstringTemplate string using ${column_name} placeholders
columnsmapPer-column settings with unit and agg_func
overrideslistPer-column visual property overrides

Visual properties

Visual properties control chart appearance. They can be set via shorthand fields (chart, fill_opacity, stack) or the properties list.

yaml
properties:
  - name: chartType
    value: bar
  - name: fillOpacity
    value: 0.3
  - name: stack
    value: all
PropertyTypeValues
chartTypestringline, bar, scatter
stackstring"" (off), all
nullsModestringHow a time bucket with no value is drawn: keep (a gap), replace (a zero), connect (a line across the gap)
showPointsstringWhen a line chart marks its points: auto, always, never
lineWidthnumberLine thickness in pixels, 1 to 10
fillOpacitynumber0 to 1
symbolSizenumberPoint marker size in pixels, 1 to 20
symbolstringMarker name, such as circle or triangle
colorstringA CSS color
colorSchemestringColor scheme name
colorModestringWhich part of a stat is colored: none, value, backgroundGradient, backgroundSolid
textSizenumberStat value size in pixels, 1 to 200
unitstringDisplay unit
aggFuncstringAggregation function
columnDisplayobject{mode: value | sparkline | bar, min?, max?}

nullsMode replaces the older boolean connectNulls.

Timeseries overrides

Chart widgets support per-timeseries overrides that apply visual properties to specific series:

yaml
overrides:
  - matchers:
      - target: metric   # "metric" or "timeseries"
        value: cpu_idle
    properties:
      - name: unit
        value: utilization
      - name: color
        value: blue

The target field specifies what to match:

  • metric -- matches by metric/column name
  • timeseries -- matches by timeseries label

Metric monitors

The metric_monitors section bundles alert monitors with the dashboard. Each entry uses the same format as a metric monitor and adds a key:

yaml
metric_monitors:
  - key: cpu_usage
    name: CPU usage
    type: threshold
    metrics:
      - system_cpu_load_average_15m as $load_avg_15m
      - system_cpu_time as $cpu_time
    query:
      - avg($load_avg_15m) / uniq($cpu_time, cpu) as cpu_util
      - group by host_name
    column:
      unit: utilization
    max_value: 3
    num_eval_points: 10
    trend_agg_func: last

Monitor fields

FieldTypeRequiredDescription
keystringyesUnique monitor identifier within the template
namestringnoHuman-readable title. Defaults to a name made from key
typestringyesDetector: threshold, anomaly, outlier, or forecast
metricslistyesMQL metric expressions
querylistyesMQL query clauses
statusstringnoactive (default) or paused
columnstring/objectnoColumn to evaluate: a name, or {name: "col", unit: "ms"}
resolutiondurationnoData point interval
num_eval_pointsintnoNumber of recent data points to evaluate, 1 to 15
window_rulestringnoat_all_times, at_least, on_average, or in_total (the last two for threshold only)
min_breach_pointsintnoNumber of points that must breach, for at_least
absent_pointsstringnoMissing data handling: zero, ignore, or alert
time_offsetdurationnoShifts the evaluation window, for late data
trend_agg_funcstringnoAggregation function for trend detection: sum, avg, median, last
trend_sensitivitystringnoSensitivity of trend detection
repeat_intervalobjectnoNotification repeat interval configuration

The detector settings sit at the top level beside type. A setting of another type is accepted and ignored.

TypeSettings
thresholdmin_value, max_value (at least one), recovery: {min_value, max_value}
anomalysensitivity, direction, seasonality, min_change, min_volume, preset
outliersensitivity, direction, min_peers, min_change, keep_firing_for
forecastmin_value, max_value (at least one), horizon, seasonality

See Alerting for the meaning of each setting.

yaml
# Threshold with a recovery band inside the range
type: threshold
min_value: 100
max_value: 1000
recovery:
  min_value: 110
  max_value: 900
yaml
# Anomaly detection
type: anomaly
sensitivity: medium     # very_low, low, medium, high, very_high
direction: both         # both, above, below
min_change: 10          # optional: smallest move, in metric units

Older templates use a nested detector block (type: manual or type: auto). Uptrace still reads it and rewrites it to the current shape, but new templates should use the top-level type.

Template composition

A table widget can append the root items of other templates to its grid with grid_include. This enables modular dashboard composition:

yaml
# Parent: uptrace.dotnet.10.all.yml
schema: v2
name: '.NET: All'
tags: [otel, app]
version: v26.11.05

layout:
  items:
    - type: table
      title: Services
      metrics:
        - process_runtime_dotnet_gc_heap_size as $heap_size
      query:
        - group by service_name
        - sum($heap_size) as heap_size
      grid_include:
        - uptrace.dotnet.20.gc
        - uptrace.dotnet.30.runtime
        - uptrace.dotnet.40.thread_pool

Each entry references another template by filename (without .yml).

Metric requirements

The metrics_match field controls when a template is activated. It appears at the top level of the template:

yaml
metrics_match:
  present:
    - metric: system_cpu_utilization
    - library: io.opentelemetry.instrumentation.system
      metric: system_cpu_time
      attrs: [cpu]
  missing:
    - metric: system_cpu_logical_count

present lists metrics the project must emit, and every entry must match. missing lists metrics the project must not emit. Each entry has these fields:

FieldTypeDescription
metricstring or listMetric name. A list matches any one of the names, for example after a rename
librarystringInstrumentation library name (optional)
attrslistAttribute keys the metric must carry (optional)

A file can hold several YAML documents separated by ---. They are variants of the same dashboard for different metric sets, and Uptrace applies the first one whose metrics_match passes. Only the first document states the metadata (schema, name, tags, version, and so on). A variant without metrics_match matches every project, so it must be the last one. Older templates use require_metrics, which Uptrace still reads and rewrites to metrics_match.

Tags

Tags categorize dashboards for filtering. Use one data source tag and 1-3 category tags.

Data source tags

  • otel -- OpenTelemetry metrics
  • prom -- Prometheus metrics

Category tags

  • infra -- System resources (CPU, RAM, disk, network)
  • network -- Network-specific metrics
  • db -- Database systems (PostgreSQL, MySQL, Redis)
  • app -- Application runtimes (Go, .NET, Java, JVM)
  • k8s -- Kubernetes resources
  • tracing -- Distributed tracing and spans
  • logs -- Log aggregation
  • messaging -- Message queues (Kafka)
  • self_monitoring -- Uptrace internal metrics (no data source tag needed)
yaml
tags: [otel, infra]         # Host metrics
tags: [otel, app, db]       # Go SQL client
tags: [otel, k8s, infra]    # Kubernetes infrastructure
tags: [self_monitoring]      # Uptrace self-monitoring

Template ID and filename

The template ID is derived from the filename:

  • uptrace.hostmetrics.10.overview.yml becomes ID uptrace.hostmetrics.overview
  • The numeric suffix (e.g., 10) is stripped from the ID and used as a display priority

Validation

Templates are validated in two ways:

  1. YAML parsing with DisallowUnknownField catches typos and unknown keys.
  2. JSON Schema validation against schema.json ensures structural correctness.

To validate templates:

bash
go run -tags=cloud ./cmd/cloud dashboard validate_templates

Earlier template formats

Templates written for earlier releases still import. Uptrace rewrites each earlier spelling to the current one, and an export always writes the current format:

Earlier spellingCurrent spelling
table at the top levelA table widget at the end of layout.items
grid_sections (or grid_rows)Groups in rows mode: in the grid of that table widget, or in the root when there is no table
table_grid_itemsWidgets in layout.items, before the table widget
include_grid_sections, grid_query, grid_variables at the top levelgrid_include, grid_query, grid_variables on the table widget
type: gauge with no gauge fieldtype: stat
require_metricsmetrics_match

Older monitors with a nested detector block are rewritten too (see Metric monitors).

Full example

yaml
schema: v2
name: 'HTTP Check: Endpoints'
description: Monitors HTTP endpoint availability and response times.
tags: [otel, infra]
version: v26.11.05
setup_link: https://example.com/setup

layout:
  fit_content: true
  items:
    - title: Successful checks
      type: text
      text: ${num_up} out of ${num_all}
      metrics:
        - httpcheck_status as $status
      query:
        - uniq($status{http_status_class="2xx"}) as num_all
        - uniq($status{http_status_class="2xx"}) == 1 as num_up

    - type: table
      title: ""
      metrics:
        - httpcheck_status as $status
        - httpcheck_duration as $duration
      query:
        - group by http_url
        - group by host_name
        - sum($status{http_status_class="2xx"}) / sum($status) as availability
        - avg($duration)
      columns:
        availability: { unit: utilization }
      grid:
        items:
          - type: group
            title: Gauges
            columns: 6
            column_width_mode: narrow
            items:
              - title: Status
                type: stat
                metrics:
                  - httpcheck_status as $status
                query:
                  - sum($status{http_status_class="2xx"})
                value_mappings:
                  - op: any
                    text: UNKNOWN
                    color: gray
                  - op: eq
                    value: 0
                    text: DOWN
                    color: red
                  - op: gte
                    value: 1
                    text: UP
                    color: green

          - type: group
            title: General
            items:
              - title: HTTP check result
                metrics:
                  - httpcheck_status as $status
                query:
                  - $status group by http_status_code

              - title: HTTP check duration
                metrics:
                  - httpcheck_duration as $duration
                query:
                  - avg($duration)

metric_monitors:
  - key: http_check_is_down
    name: HTTP check is down
    metrics:
      - httpcheck_status as $status
    query:
      - sum($status{http_status_class="2xx"}) as status_2xx
      - group by http_url
      - group by host_name
    type: threshold
    min_value: 1
    max_value: 1
    num_eval_points: 1
    absent_points: alert
    trend_agg_func: last