Local, self-contained observability demonstration: a small script emits a deterministic GenAI trace and the local .NET Aspire dashboard shows the spans, the OpenTelemetry GenAI attributes, and the correlation trace_id.
Show a concrete, real trace during the observability part of the talk. The audience sees the actual attribute names used by OpenTelemetry, the model, latency, tokens, tool call, and the same trace_id on every span. No customer data, no external service, no cost.
The demo proves:
- GenAI operations can be observed with the OpenTelemetry Development-stage semantic conventions.
- A single
trace_idlinks agent, chat, and tool spans. - The local Aspire dashboard is a working OTLP receiver, so an on-premises inner-loop workflow is possible without a paid observability backend.
| Path | Purpose |
|---|---|
demo/emit_trace.py |
Python script that emits a deterministic trace via OTLP. Uses the current GenAI attribute names (gen_ai.provider.name, gen_ai.request.model, gen_ai.usage.input_tokens, gen_ai.tool.type, gen_ai.tool.call.arguments). |
demo/requirements.txt |
Pinned Python dependencies (opentelemetry-api, opentelemetry-sdk, opentelemetry-exporter-otlp-proto-grpc). |
docker-compose.yml |
Runs the standalone Aspire dashboard image from Microsoft Container Registry and maps OTLP gRPC to localhost:4317 and the dashboard to localhost:18888. |
scripts/run-demo.ps1 |
One-command demo runner: starts the dashboard, prepares the Python environment, and emits a trace. |
scripts/reset-demo.ps1 |
Stops the dashboard container and discards its state. |
PRESENTER-GUIDE.md |
Non-technical step-by-step live-demo guide. |
SECURITY-MODEL.md |
Honest scope of what this lab does and does not prove. |
The script does not call a real language model. This is a deliberate choice: the point of the demo is the trace shape and the correlation, not proving that an LLM produces text. Using deterministic values keeps the on-stage output stable and avoids any dependency on model endpoints or credentials.
- Start Docker Desktop and run
scripts\run-demo.ps1. - Open the Aspire dashboard directly at http://localhost:18888/traces. This demo uses Traces only; ignore Structured logs and Metrics.
- Open the emitted trace and expand its spans.
- Show
gen_ai.provider.name,gen_ai.request.model,gen_ai.usage.input_tokens,gen_ai.tool.type, andgen_ai.tool.call.arguments. - Point out the shared
trace_idand the sequence of agent -> chat -> tool spans. - Run
scripts\reset-demo.ps1when finished.
The complete presenter script is in PRESENTER-GUIDE.md.
- OpenTelemetry GenAI semantic conventions (Development status), spans: https://github.com/open-telemetry/semantic-conventions-genai/blob/main/docs/gen-ai/gen-ai-spans.md
- OpenTelemetry GenAI agent spans: https://github.com/open-telemetry/semantic-conventions-genai/blob/main/docs/gen-ai/gen-ai-agent-spans.md
- OpenTelemetry GenAI attribute registry: https://github.com/open-telemetry/semantic-conventions-genai/blob/main/docs/registry/attributes/gen-ai.md
- .NET Aspire dashboard as a standalone OTLP receiver: https://aspire.dev/dashboard/overview/
- Aspire dashboard container image on Microsoft Container Registry: https://mcr.microsoft.com/en-us/artifact/mar/dotnet/aspire-dashboard
- Microsoft Agent Framework 1.0 (context for GenAI instrumentation in .NET/Python agents): https://learn.microsoft.com/en-us/agent-framework/overview/