Vibe Coding for Production
Exercises

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 run

The 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:latest

Open 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/orders

The 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/slow endpoint is intentionally slow, so latency percentiles will spread out under load.
  • Error rate or failed requests. The /api/orders/flaky endpoint returns 502 about 25% of the time.
  • A domain metric. The demo emits dashboard_demo.orders_placed when 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.

On this page