Real Web Developers

Service collection Jaeger

Author
Scott Rickman
Last updated
2026-08-19

ActivityHelper.cs


namespace RealWebDevelopers;

using System.Diagnostics;

public sealed class ActivityHelper
{
    private ActivitySource? ActivitySource { get; }

    public ActivityHelper(string name)
    {
        this.ActivitySource = new ActivitySource(name);
    }

    public Activity? StartActivity(string operationName)
    {
        return this.ActivitySource?.StartActivity(operationName);
    }
}
    

Program.cs


namespace RealWebDevelopers;

using Microsoft.Extensions.Options;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

public class Program
{
    public static void Main(string[] args)
    {
        // boiler plate web application
        builder.Services.AddOpenTelemetry()
            .WithTracing(configure =>
            {
                configure.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(builder.Environment.ApplicationName))
                    .AddAspNetCoreInstrumentation()
                    .AddHttpClientInstrumentation()
                    .AddSource(builder.Environment.ApplicationName)
                    .AddOtlpExporter(config => { config.Endpoint = new Uri("http://localhost:4317"); });
            });
        builder.Services.AddSingleton(provider => new ActivityHelper(builder.Environment.ApplicationName));
        // etc.
    }
}

Provider.cs


namespace RealWebDevelopers;

public class Provider
{
    private readonly ActivityHelper activityHelper;
    // other fields

    public UnderwritingProvider(ActivityHelper activityHelper //, other services)
    {
        this.activityHelper = activityHelper;
        // other setters
    }

    public async Task<IEnumerable<int>?> GetCoverLevelsAsync(string riskType, CancellationToken cancellationToken)
    {
        using var activity = this.activityHelper.StartActivity("GetCoverLevelsAsync");
        var httpClient = this.httpClientFactory.CreateClient(Constants.HttpClients.UnderwritingApi);
        var httpResponseMessage = await httpClient.GetAsync($"v1/CoverLevel/{riskType}", cancellationToken);
        if (!httpResponseMessage.IsSuccessStatusCode)
        {
            activity?.SetTag(ActivityTags.HttpError, await httpResponseMessage.Content.ReadAsStringAsync(cancellationToken));
            return null;
        }

        return await httpResponseMessage.Content.ReadFromJsonAsync<IEnumerable<int>?>(cancellationToken);
    }
}