Every observability example used an in-process exporter, which proves the adapter's semantics but never serializes a span or opens a socket. Nothing in the repository showed the path an OpenTelemetry user actually takes, so the exporter choice, Resource, auth headers, and shutdown order were left for each reader to reconstruct. `otlp-backend.ts` runs OTel SDK to OTLP/HTTP exporter to HTTP to a backend, and prints what crossed the wire. The backend is a loopback listener the example starts itself, so it still needs no API key, no external collector, and no internet access; `OTLP_URL` and `OTLP_HEADERS` redirect the same payload to a hosted vendor. It also demonstrates two things that are easy to get wrong. `service.name` belongs to the provider's Resource, and a provider built without one files every span under `unknown_service:node`. Tool input and output require both halves of the capture opt-in, so the example sets the core policy and the adapter mode together and states what the run exports without them. `runToolDemo` joins the shared demo runtime so the example can show a real `execute_tool` span; the existing `runDemo` export is unchanged. The example is registered in the catalog and in the smoke script, which now runs eight examples.
Observability v2 examples
These examples exercise the real public package/subpath APIs with a
deterministic local adapter. They need no model API key, global OpenTelemetry
provider, or external collector. Only otlp-backend.ts opens a socket, and it
binds a loopback listener of its own rather than reaching the internet. Build
the workspaces first, then run any file with npx tsx.
| Example | Ownership and lifecycle |
|---|---|
batching-exporter.ts |
application-owned custom exporter and batching sink |
in-memory-store.ts |
non-durable in-memory store; application shuts down the sink |
file-trace-store.ts |
drain sink, fsync store, shut down sink, close store |
otel-provider.ts |
official in-memory exporter; OMA sink drains before application provider shutdown |
otlp-backend.ts |
real OTLP/HTTP exporter posting to a loopback listener the example starts itself |
cli-lifecycle.ts |
short-lived natural exit with explicit flush/shutdown/close |
server-lifecycle.ts |
application registers SIGTERM, stops intake, drains telemetry |
serverless-lifecycle.ts |
short per-invocation flush; warm singleton is not shut down |
run-viewer.ts |
persists fictional deterministic records to FileTraceStore, then exports one historical run to oma-dashboards/run-viewer-demo.html |
public-snippets.ts is compile-only. It mirrors the
copyable migration guide API combinations and is included in the automated
TypeScript check.
The separate trace-observability.ts intentionally
remains the legacy onTrace example.
Generate the offline Run Viewer demo from the repository root:
npx tsx packages/core/examples/integrations/observability-v2/run-viewer.ts
The command needs no API key or network access. Its trace represents fictional, deterministic demo data rather than a live provider run. The explicit output path is non-overwriting; move the existing HTML before generating it again.