PollyOpenTelemetry 1.0.5
dotnet add package PollyOpenTelemetry --version 1.0.5
NuGet\Install-Package PollyOpenTelemetry -Version 1.0.5
<PackageReference Include="PollyOpenTelemetry" Version="1.0.5" />
<PackageVersion Include="PollyOpenTelemetry" Version="1.0.5" />
<PackageReference Include="PollyOpenTelemetry" />
paket add PollyOpenTelemetry --version 1.0.5
#r "nuget: PollyOpenTelemetry, 1.0.5"
#:package PollyOpenTelemetry@1.0.5
#addin nuget:?package=PollyOpenTelemetry&version=1.0.5
#tool nuget:?package=PollyOpenTelemetry&version=1.0.5
PollyOpenTelemetry
<img src="icon.png" width="100" align="right" />
OpenTelemetry instrumentation for Polly v8 resilience pipelines.
Emits distributed trace spans (Activity) and metrics for retry, circuit breaker, and timeout strategies — giving you full observability into your resilience layer.
Polly ships built-in logging and basic metrics via
ConfigureTelemetry(ILoggerFactory).
This package adds the missing piece: OpenTelemetry-native traces and enriched metrics.
Installation
dotnet add package PollyOpenTelemetry
Quick Start
1. Register with the OpenTelemetry SDK
services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddPollyInstrumentation() // register the "Polly" ActivitySource
.AddOtlpExporter())
.WithMetrics(metrics => metrics
.AddPollyInstrumentation() // register the "Polly" Meter
.AddOtlpExporter());
2. Add to your resilience pipeline
var pipeline = new ResiliencePipelineBuilder()
.AddPollyOpenTelemetry() // ← one call enables both traces + metrics
.AddRetry(new RetryStrategyOptions
{
MaxRetryAttempts = 3,
BackoffType = DelayBackoffType.Exponential,
})
.AddCircuitBreaker(new CircuitBreakerStrategyOptions
{
FailureRatio = 0.5,
MinimumThroughput = 10,
})
.AddTimeout(TimeSpan.FromSeconds(30))
.Build();
With Dependency Injection
services.AddResiliencePipeline("my-http-client", builder =>
{
builder
.AddPollyOpenTelemetry()
.AddRetry(new RetryStrategyOptions { MaxRetryAttempts = 3 })
.AddTimeout(TimeSpan.FromSeconds(30));
});
Emitted Telemetry
Activities (Traces)
| Activity name | When emitted |
|---|---|
polly.attempt |
Each individual execution attempt |
polly.retry |
Each retry decision |
polly.circuit_breaker.opened |
Circuit breaker transitions to open |
polly.circuit_breaker.closed |
Circuit breaker transitions to closed |
polly.circuit_breaker.half_opened |
Circuit breaker transitions to half-open |
polly.timeout |
Operation cancelled due to timeout |
Common Activity Tags
| Tag | Value |
|---|---|
polly.pipeline.name |
ResiliencePipelineBuilder.Name |
polly.pipeline.instance_name |
ResiliencePipelineBuilder.InstanceName |
polly.strategy.name |
Name of the individual strategy |
polly.outcome |
success, failure, or unknown |
error.type |
Exception type (on failure) |
Additional Tags per Activity
polly.attempt: polly.attempt.number, polly.attempt.handled
polly.retry: polly.attempt.number, polly.retry.delay_ms
polly.circuit_breaker.opened: polly.circuit_breaker.break_duration_ms, polly.circuit_breaker.is_manual
polly.timeout: polly.timeout_ms
Metrics
| Metric name | Type | Unit | Description |
|---|---|---|---|
polly.attempt.duration |
Histogram | ms | Duration of each individual execution attempt |
polly.retry.count |
Counter | {attempt} |
Number of retry decisions made |
polly.circuit_breaker.open |
Counter | {open} |
Number of times circuit breaker opened |
polly.timeout.count |
Counter | {timeout} |
Number of operations cancelled due to timeout |
Options
builder.AddPollyOpenTelemetry(options =>
{
options.EnableTracing = true; // default: true
options.EnableMetrics = true; // default: true
// Enrich activities with custom tags
options.EnrichActivity = (activity, resilienceEvent, source) =>
{
activity.SetTag("my.custom.tag", "value");
};
});
Composing with Polly's Built-in Logging
AddPollyOpenTelemetry() is safe to combine with Polly's built-in ConfigureTelemetry(ILoggerFactory) — both listeners are composed automatically:
var pipeline = new ResiliencePipelineBuilder()
.ConfigureTelemetry(loggerFactory) // Polly structured logging + basic metrics
.AddPollyOpenTelemetry() // OpenTelemetry traces + enriched metrics
.AddRetry(...)
.Build();
Sample Trace Output
▶ polly.attempt [polly.pipeline.name=payment-api] [polly.attempt.number=0] [polly.outcome=failure]
✗ error.type=System.Net.Http.HttpRequestException
▶ polly.retry [polly.retry.delay_ms=200] [polly.attempt.number=0]
▶ polly.attempt [polly.pipeline.name=payment-api] [polly.attempt.number=1] [polly.outcome=success]
Requirements
- .NET 8.0+
- Polly 8.x
- OpenTelemetry 1.x
Publishing
This package is published to NuGet.org via GitHub Actions using NuGet trusted publishing — no API key secret is stored in the repository.
Setup (one-time)
- On nuget.org, go to your package → Manage → Trusted Publishers → Add a publisher
- Choose GitHub Actions and enter:
- Owner:
Sweevo - Repository:
Polly-Contrib-OpenTelemetry - Workflow:
build.yml
- Owner:
- Push a
v*tag to trigger the publish workflow:git tag v1.0.0 git push --tags
The workflow requests a short-lived OIDC token from GitHub (audience api.nuget.org) and uses it as the push credential — no NUGET_API_KEY secret required.
License
MIT — Copyright © 2025 Justin Bannister
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- OpenTelemetry (>= 1.16.0)
- Polly.Core (>= 8.7.0)
-
net9.0
- OpenTelemetry (>= 1.16.0)
- Polly.Core (>= 8.7.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
1.0.2: Critical fix — Microsoft.Extensions.DependencyInjection.Abstractions dependency corrected from v10 to v8, enabling installation on .NET 8 projects. Added net9.0 target.