Dashboard (OpenTelemetry analytics)
Build a dashboard that surfaces telemetry from a small instrumented API.
Goal
Build a small dashboard that helps you see what an application is doing: latency, errors, and at least one domain metric you care about. The point is to practice driving a real data path from instrumentation to UI with an agent. It is not to ship a perfect product on the first day.
Getting started
The repository ships a starter API that emits OpenTelemetry traces and metrics over OTLP.
dotnet runThe starter API targets .NET 10 (net10.0) and listens on
http://localhost:5080. To actually see the telemetry, run an OTLP backend on
port 4317. The simplest is the Aspire dashboard in Docker:
docker run --rm -it \
-p 18888:18888 \
-p 4317:18889 \
-p 4318:18890 \
--name aspire-dashboard \
-e DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS=true \
mcr.microsoft.com/dotnet/aspire-dashboard:latestOpen http://localhost:18888, then send some traffic:
curl http://localhost:5080/api/orders
curl http://localhost:5080/api/orders/slow
curl http://localhost:5080/api/orders/flaky
curl -X POST http://localhost:5080/api/ordersThe demo exports traces and metrics over OTLP/gRPC to
http://localhost:4317 by default. Metrics are exported periodically, so leave
the app running for a few seconds after sending traffic before checking the
Metrics tab. If another tool, such as an IDE, sets generic OTEL_*
environment variables, the demo still uses its own DashboardDemo__OtlpEndpoint
setting so telemetry goes to the local Aspire dashboard unless you explicitly
override it.
Prefer Node? See the alternative in demos/dashboard/README.md in the workshop
repository you were given. The exercise stays the same.
The Aspire dashboard verifies that telemetry is flowing and provides its own viewer. It does not expose a Prometheus query API for a separate custom UI.
What you build
Configure a queryable metrics backend such as Prometheus (usually through an OpenTelemetry Collector), then build a small UI against that backend's documented API. Document the collector/backend and the exact query API or dashboard data source. Show three things from the demo's telemetry:
- Request rate and latency for the API. The
/api/orders/slowendpoint is intentionally slow, so latency percentiles will spread out under load. - Error rate or failed requests. The
/api/orders/flakyendpoint returns 502 about 25% of the time. - A domain metric. The demo emits
dashboard_demo.orders_placedwhen you POST to/api/orders. Put that on a panel.
If you build a custom frontend, use whatever stack you are comfortable with. Blazor, Razor Pages, or a static page can work once a queryable backend is configured. Keep it small. One screen with three panels is plenty.
Constraints (keep it teachable)
- Do not paste production API keys into chat. Use local env vars or throwaway keys.
- Pick one runtime and one telemetry backend in v1. Avoid boiling the ocean.
- If the model invents metric names, verify they exist in the exporter or dashboard config.
Done when
You can demo the dashboard, explain where each panel's data comes from, and name one follow-up you would add next (an SLO, an alert, a drill-down view).
Optional stretch
- Add an SLO or error budget panel if your stack supports it.
- Wire up a second instance of the demo so you have one healthy and one flaky service in the same dashboard.