---
title: Configure OpenTelemetry
summary: Composes opt-in OpenTelemetry logging, metrics, and tracing.
status: draft
owner: Framework.NCore maintainers
last_reviewed: 2026-10-02
library: SAIF.NetCore.ServiceExtensions
reference_type: package
operation_id: OP-19
trigger: A consuming application calls ConfigureOpenTelemetry() on an IHostBuilder or IHostApplicationBuilder.
---

# Configure OpenTelemetry

This operation composes OpenTelemetry logging, metrics, and tracing for an application, including resource attributes, universal meter/source collection, always-on sampling, and an optional OTLP exporter. OpenTelemetry is a third-party observability framework (not a SAIF package documented by this run); its own instrumentation packages are called directly and are not cross-linked to dependency operation pages.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-19 |
| **Trigger** | A consuming application calls `ConfigureOpenTelemetry()` on its `IHostBuilder` or `IHostApplicationBuilder`. |
| **Inputs** | An optional `Action<OpenTelemetryOptions>` callback (`Owner` defaults to `"Unknown"` when not set by the callback); environment variables, including `OTEL_EXPORTER_OTLP_ENDPOINT` and `APP_POOL_ID`. |
| **Outputs** | Logging providers cleared and replaced with OTel logging; metrics/tracing providers registered; an OTLP exporter if an endpoint is configured. |
| **Primary components** | `OpenTelemetryExtensions.ConfigureOpenTelemetry` |
| **Entry point** | `src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/OpenTelemetryExtensions.cs` (L36–160) |

## Steps

1. Construct a new `OpenTelemetryOptions` internally and invoke the caller's optional `configureOptions` callback against it (`Owner` defaults to `"Unknown"` if the callback does not set it); add relevant environment variables to the configuration.
2. `Logging.ClearProviders()`, then add OpenTelemetry logging with formatted messages and scopes enabled ([BR-SE-22](../business-rules.md#br-se-22-enabling-opentelemetry-replaces-existing-logging-providers))
   - Removes any previously configured console or other logging provider (see [Register logging and error handler](register-logging-and-error-handler.md)).
3. Build the OTel resource: service name = `environment.ApplicationName` via `AddService`; attributes include `hosting.environment.name`/`hosting.environment.path`, `deployment.environment.name`, `host.name`, `process.runtime.version`, `owner` (lower-cased), `saif.sdk.name`/`saif.sdk.version`/`saif.sdk.language=dotnet`, `iis.app_pool.name` (from `APP_POOL_ID`), `host.ip` (a `string[]` of every distinct, operational, non-loopback, non-tunnel IPv4 address across all network interfaces, DHCP/manual addresses ordered first; omitted entirely when no such address exists), `process.creation.time`.
4. Metrics: `AddMeter("*")`, plus ASP.NET Core, HttpClient, and Runtime instrumentation ([BR-SE-23](../business-rules.md#br-se-23-all-meters-and-activity-sources-are-collected%3B-all-traces-sampled))
5. Tracing: `AlwaysOnSampler`, `AddSource("*")`, plus ASP.NET Core and HttpClient instrumentation ([BR-SE-23](../business-rules.md#br-se-23-all-meters-and-activity-sources-are-collected%3B-all-traces-sampled))
6. If `OTEL_EXPORTER_OTLP_ENDPOINT` is non-blank: call `UseOtlpExporter()` (read from the process environment variable for `IHostBuilder`, or from `Configuration` for `IHostApplicationBuilder`) ([BR-SE-24](../business-rules.md#br-se-24-otlp-export-requires-the-otlp-endpoint-variable))
   - If blank: no OTLP exporter is registered; metrics/traces/logs are collected but not exported anywhere.

## Process flow

This diagram shows the one-time composition performed when `ConfigureOpenTelemetry` is called during host startup, not the ongoing runtime behavior of the logging/metrics/tracing pipelines it wires up.

```mermaid
flowchart TD
    Start([ConfigureOpenTelemetry called]) --> S1[Apply OpenTelemetryOptions]
    S1 --> S2["Clear logging providers, add OTel logging"]
    S2 --> S3[Build OTel resource attributes]
    S3 --> S4["Register metrics: AddMeter * + instrumentation"]
    S4 --> S5["Register tracing: AlwaysOnSampler +<br>AddSource * + instrumentation"]
    S5 --> S6{OTEL_EXPORTER_OTLP_ENDPOINT set?}
    S6 -->|Yes| S6a[UseOtlpExporter]
    S6 -->|No| EndOk([Telemetry collected but not exported])
    S6a --> EndOk2([Telemetry collected and exported via OTLP])
```

## Failure and edge-case behavior
- Enabling OpenTelemetry without re-adding a console logging provider removes existing console log output (see [BR-SE-22](../business-rules.md#br-se-22-enabling-opentelemetry-replaces-existing-logging-providers))
- A missing `OTEL_EXPORTER_OTLP_ENDPOINT` silently disables export without failing startup.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- `src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/OpenTelemetryExtensions.cs`
- `src/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/SAIF.NetCore.ServiceExtensions/OpenTelemetryOptions.cs`
