public static TBuilder ConfigureOpenTelemetry<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
{
builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
});
builder.AddOpenTelemetryExporters()
.Select(telemetryBuilder => telemetryBuilder
.WithMetrics(metrics =>
{
metrics.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation();
})
.WithTracing(tracing =>
{
tracing.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddProcessor(new ErrorAndSlowRateSamplerProcessor(
predicate: activity => activity.OperationName == "CustomThingy",
samplingProbability: builder.Environment.IsProduction() ? 0.02 : 1,
maxDurationPredicate: TimeSpan.FromSeconds(1)))
.SetSampler(new ParentBasedSampler(
rootSampler: new AlwaysOnSampler(),
remoteParentNotSampled: new AlwaysOnSampler()));
}))
.ToArray();
return builder;
}
private static IEnumerable<IOpenTelemetryBuilder> AddOpenTelemetryExporters<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
{
if (!string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]))
{
yield return builder.Services
.AddOpenTelemetry()
.UseOtlpExporter();
}
if (!string.IsNullOrWhiteSpace(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]))
{
yield return builder.Services
.AddOpenTelemetry()
.UseAzureMonitor();
}
}
Last active
March 26, 2026 18:50
-
-
Save egil/748340ce5899c118ee45db502f680acf to your computer and use it in GitHub Desktop.
ErrorAndSlowRateSamplerProcessor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.Diagnostics; | |
| using OpenTelemetry.Trace; | |
| namespace OpenTelemetry; | |
| /// <summary> | |
| /// A high-performance probabilistic processor that samples activities based on a predicate and rate. | |
| /// </summary> | |
| public sealed class ErrorAndSlowRateSamplerProcessor : BaseProcessor<Activity> | |
| { | |
| private readonly Func<Activity, bool> predicate; | |
| private readonly TimeSpan maxDurationPredicate; | |
| private readonly TraceIdRatioBasedSampler sampler; | |
| /// <summary> | |
| /// Initializes a new instance of the <see cref="ErrorAndSlowRateSamplerProcessor"/> class. | |
| /// </summary> | |
| /// <param name="predicate">The predicate to determine if an activity should be sampled.</param> | |
| public ErrorAndSlowRateSamplerProcessor(Func<Activity, bool> predicate, double samplingProbability, TimeSpan maxDurationPredicate) | |
| { | |
| ArgumentNullException.ThrowIfNull(predicate); | |
| this.predicate = predicate; | |
| this.maxDurationPredicate = maxDurationPredicate; | |
| this.sampler = new TraceIdRatioBasedSampler(samplingProbability); | |
| } | |
| /// <inheritdoc/> | |
| public override void OnStart(Activity? data) | |
| { | |
| if (data is null || !predicate(data)) | |
| { | |
| return; | |
| } | |
| var samplingParameters = new SamplingParameters( | |
| new ActivityContext( | |
| data.TraceId, | |
| data.SpanId, | |
| data.ActivityTraceFlags | |
| ), | |
| data.TraceId, | |
| data.DisplayName, | |
| data.Kind, | |
| data.TagObjects, | |
| data.Links | |
| ); | |
| var result = sampler.ShouldSample(in samplingParameters); | |
| data.IsAllDataRequested = result.Decision is SamplingDecision.RecordAndSample; | |
| data.ActivityTraceFlags = result.Decision is SamplingDecision.RecordAndSample | |
| ? ActivityTraceFlags.Recorded | |
| : ActivityTraceFlags.None; | |
| } | |
| /// <inheritdoc/> | |
| public override void OnEnd(Activity? data) | |
| { | |
| if (data is not null && predicate(data) && (data.Status is ActivityStatusCode.Error || data.Duration > maxDurationPredicate)) | |
| { | |
| data.IsAllDataRequested = true; | |
| data.ActivityTraceFlags = ActivityTraceFlags.Recorded; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment