Custom Dashboards
Build your own dashboards of OpenTelemetry metric widgets, with queries, grouping, filters and six visualizations.
Custom dashboards put the metrics you care about on one page: checkout latency next to queue depth next to heap usage. Each widget charts one or more OpenTelemetry metrics your services report. Use them for the views no built-in page gives you, such as a team's own health board.
Open Dashboards in the sidebar, at /o/:org/projects/:project/dashboards. A dashboard lives at /o/:org/projects/:project/dashboards/:dashboard.
Where the data comes from
Widgets read the same gauges, sums and histograms as Metrics: runtime and host metrics from the AdonisJS agent, and any metric you record with the OpenTelemetry API. A widget can only use a metric this project has reported, and saving checks that every metric name exists.
Dashboards
The Dashboards page lists every dashboard of the project by name, with a miniature of its layout, its description, its widget count and who created it. New dashboard asks for a name, up to 80 characters, and an optional description, up to 280. The row menu offers Rename (name, description and an icon), Duplicate, which copies the dashboard and its widgets as "name copy" and opens the copy, and Delete, which removes the dashboard and its widgets but never the metrics. The confirmation toast after Delete has an Undo button that brings the dashboard back with its widgets.
Who can change a dashboard
Every dashboard is visible to everyone who can view its project. Only its creator and org admins can rename it, change its layout, add or edit widgets, or delete it. Everyone else sees it read-only, marked "View only", with Duplicate to make their own editable copy. Dashboards created before creators were recorded, or whose creator left, are managed by org admins.
Sharing
Copy link in the dashboard header copies its address with the current time range, environment, services and variable values, so the person you send it to sees the same view. A relative range such as the last hour ends at the time the link is opened. To share the window you are looking at, pick Copy link to this exact window from the menu next to it. Anyone who can view the project can open the link, read-only unless they created the dashboard or are an org admin.
Layout
Widgets sit on a 12-column grid. A dashboard holds up to 60 widgets, and a widget is at most 12 rows tall.
Edit layout switches to edit mode. Drag a widget by its title bar, resize it from its corner, or use Duplicate and Remove in its header. From the keyboard, focus a widget's move handle and use the arrow keys to move it, or Shift and the arrow keys to resize it; the resize corner takes the arrow keys too. Each step announces the new position to screen readers. Save stores every change at once and Cancel discards them. Leaving the page with unsaved layout changes asks "Discard layout changes?" first. Duplicate and Remove on a widget outside edit mode also enter edit mode, so they wait for Save too.
Every widget follows the time range, interval, environment and services in the top bar. See scope controls.
Variables
Variables filter every widget on the dashboard at once. A new dashboard starts with four: $service (service.name), $env (deployment.environment.name), $version (service.version) and $route (http.route). Each one shows as a chip above the widgets with the values reported in the current range. Pick one or more values to filter every widget whose metric carries that attribute, unless the widget already filters on it. Nothing selected means no filter. Selections live in the URL as var.<name>, as in ?var.service=api.
People who can change the dashboard add and remove variables from Variables, up to 8. A variable has a name of lowercase letters, digits and _ that starts with a letter, up to 20 characters, and one attribute. A widget filter can also use $name as a value, which stands for the current selection and drops out when nothing is selected.
Widgets
Add widget opens the editor, with a live preview that uses the current scope. Without a title of your own, the widget is named after its first metric. Apply is disabled until every query has a metric, and the line under the header lists what is still missing.
| Visualization | Shows | Default size |
|---|---|---|
| Time series | Values over time | 6 by 5 |
| Stat | Latest value | 3 by 3 |
| Sparkline | Latest value and trend | 3 by 3 |
| Bars | Compare groups | 4 by 5 |
| Pie | Share of each group | 4 by 4 |
| Table | Values per bucket | 6 by 5 |
Bars and Pie compare several series, so they need a group by or a second query. Otherwise the widget says so instead of drawing one bar.
Queries
A widget has up to 6 queries, lettered A to F. Each one sets:
- Metric, searched among the metrics reported in the current range.
- Aggregation, limited to what the metric type supports:
| Type | Aggregations | Default |
|---|---|---|
| Gauge | Avg, Sum, Min, Max, Count, P50, P95, P99 | Avg |
| Counter (sum) | Avg, Sum, Min, Max, Count, Rate /s | Rate /s |
| Histogram | Avg, Sum, Min, Max, Count, Rate /s, P50, P95, P99 | P95 |
- Group by, any data-point or resource attribute, plus
service.nameandservice.instance.id. Each query draws its 10 largest groups and notes how many it hid. - Filters, up to 10, each keeping one or more values of an attribute, up to 50 values per filter.
- Legend label, up to 60 characters, which replaces the metric name in the legend.
Clicking a query's letter pins its color, and clicking again cycles it.
Formulas combine queries into one series, such as A / B for a ratio or A * 100 for a percentage. A widget has up to 4 formulas, each with its own legend. A formula uses the query letters, numbers, +, -, *, / and parentheses.
For a cumulative sum, Sum is the increase within each bucket for each series, so a counter's running total does not swamp the chart. Rate /s divides that increase by the bucket length.
Options
- Description, up to 280 characters, shown under the title.
- Values formats numbers: Auto follows the metric's unit, or pick Number, Duration (ms), Percentage (0-1) or Bytes.
- Unit label, up to 20 characters.
- Style (Line, Area or Bars) and Stack series apply to Time series only.
The Table visualization has one row per time bucket and one column per series.
When a widget fails
A widget that cannot load shows the reason in its body instead of an empty chart: a metric name this project never reported, an aggregation the metric type does not support, a Bars or Pie widget with a single series, or a query error from storage. When telemetry storage is unavailable, the dashboard and its widgets still open, and each widget offers Retry.
Managing dashboards from an assistant
The MCP server exposes list_dashboards, get_dashboard, create_dashboard, update_dashboard, delete_dashboard, add_widget, update_widget and remove_widget. See MCP server.
Answering "is checkout healthy after today's release?"
- Create a dashboard called Checkout.
- Add a Time series widget on
shop.checkout.durationwith P95, grouped bypayment.method. - Add a Stat widget on
shop.orders.placedwith Rate /s. - Add a Time series on
nodejs.eventloop.delay.p99filtered toservice.nameof the API. - Set the range to 24h and compare each widget before and after the deployment.
From a metric in Metrics, Add to dashboard turns the current aggregation, grouping and filters into a widget on an existing dashboard or a new one. Not available yet: opening a widget's query in Metrics.