Skip to content
How-to

Configure telemetry for an integration

Wire an integration host up to OpenTelemetry with the Intropy.Telemetry package, so every run exports its traces, metrics, and logs over OTLP.

  • Read The Intropy model and The Intropy Framework — the framework emits pipeline and step spans on its own; this guide is about getting them out of the process
  • Have an integration project that builds and runs on .NET 10.0 or later
  • Have Docker available — the Verify section runs a local telemetry backend in a container

1. Install the package that matches your host

Section titled “1. Install the package that matches your host”

Two NuGet packages expose the same configuration surface; pick by how the Component is hosted.

Components that run to completion or drain a queue next to a Dapr sidecar — scaffolded extractors and transactional integrations are the typical cases.

Terminal window
dotnet add package Intropy.Telemetry.ConsoleApp

A single AddOpenTelemetry call replaces the usual page of provider boilerplate. ServiceName and Environment are required. The service name becomes the service.name resource attribute on every signal — give each integration its own, and keep it stable, because it’s what you’ll filter by in every backend.

using Intropy.Telemetry.ConsoleApp;
var services = new ServiceCollection();
services.AddOpenTelemetry(config =>
{
config.ServiceName = "customer-golden-record";
config.ServiceNamespace = "fluxia"; // your organization
config.Environment = "Production";
});
var serviceProvider = services.BuildServiceProvider();
using var telemetryScope = new OpenTelemetryScope(serviceProvider);

The OpenTelemetryScope owns the provider lifetime: keep it alive for the whole run, and let its disposal flush any remaining telemetry before the host exits.

That one call configures all three signals:

  • Traces — subscribes activity sources matching Intropy.* (which covers the framework’s Intropy.Framework.Core, .Blocks, .Adapters, and .Hosting sources) plus your ServiceName, and instruments outbound HTTP, SQL Client, and gRPC calls. The framework’s Pipeline.<name>, Step.<StepName>, and Finalizer.<FinalizerName> spans are collected with no further registration.
  • Metrics — HTTP client metrics, plus ASP.NET Core request metrics on that host type.
  • Logs — structured ILogger output exported alongside the traces, correlated with the active span.

All three signals export over OTLP, configured through the standard OpenTelemetry environment variables:

Terminal window
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317

Locally, that’s wherever the collector you test against listens — the Verify section below runs one. In a deployed environment the endpoint is environment configuration, not code — set it per environment alongside the rest of the Component’s deployment config. Because the export is standard OTLP, you can point it at whatever OpenTelemetry-compatible backend you already operate.

To check the signals locally, run Grafana’s otel-lgtm image — an OTLP collector with Tempo for traces, Prometheus for metrics, Loki for logs, and Grafana on top.

Terminal window
docker run --rm -ti -p 3000:3000 -p 4317:4317 -p 4318:4318 grafana/otel-lgtm

Ports 4317 and 4318 receive OTLP over gRPC and HTTP; 3000 serves the Grafana UI (default credentials admin / admin).

With the container running and OTEL_EXPORTER_OTLP_ENDPOINT pointed at it, run the integration once with a message flowing through it, then open Grafana at http://localhost:3000 and use Explore with the Tempo data source:

  • A trace appears under your ServiceName, with a Pipeline.<name> root and Step.<StepName> children
  • Log lines from the run carry the trace’s trace_id
  • Outbound HTTP or SQL calls made by your steps show up as child spans

If nothing arrives at all, the endpoint is wrong or unreachable — check OTEL_EXPORTER_OTLP_ENDPOINT from inside the host’s environment, not just your shell. If signals arrive under the wrong service name, two hosts share a ServiceName — go back to Step 2.