< Summary

Information
Class: ProjectTemplate.Web.Extensions.OpenTelemetryServiceExtensions
Assembly: ProjectTemplate.Web
File(s): /home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/src/ProjectTemplate.Web/Extensions/OpenTelemetryServiceExtensions.cs
Line coverage
100%
Covered lines: 76
Uncovered lines: 0
Coverable lines: 76
Total lines: 132
Line coverage: 100%
Branch coverage
76%
Covered branches: 29
Total branches: 38
Branch coverage: 76.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
AddApplicationOpenTelemetry(...)88.46%2626100%
ConfigureOtlpExporter(...)100%22100%
ResolveServiceVersion(...)40%1010100%

File(s)

/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/src/ProjectTemplate.Web/Extensions/OpenTelemetryServiceExtensions.cs

#LineLine coverage
 1using System.Reflection;
 2using OpenTelemetry;
 3using OpenTelemetry.Exporter;
 4using OpenTelemetry.Metrics;
 5using OpenTelemetry.Resources;
 6using OpenTelemetry.Trace;
 7using ProjectTemplate.Web.Options;
 8
 9namespace ProjectTemplate.Web.Extensions;
 10
 11/// <summary>
 12/// Provides extension methods to register OpenTelemetry services for the application.
 13/// </summary>
 14public static class OpenTelemetryServiceExtensions
 15{
 16    /// <summary>
 17    /// Adds baseline OpenTelemetry tracing and metrics support.
 18    /// </summary>
 19    /// <param name="services">The service collection to add OpenTelemetry services to.</param>
 20    /// <param name="configuration">The application configuration source.</param>
 21    /// <param name="environment">The current hosting environment.</param>
 22    /// <returns>The same service collection instance so calls can be chained.</returns>
 23    public static IServiceCollection AddApplicationOpenTelemetry(
 24        this IServiceCollection services,
 25        IConfiguration configuration,
 26        IHostEnvironment environment)
 27    {
 16028        services
 16029            .AddOptions<ApplicationOpenTelemetryOptions>()
 16030            .Bind(configuration.GetSection(ApplicationOpenTelemetryOptions.SectionName))
 13631            .Validate(options => !string.IsNullOrWhiteSpace(options.ServiceName),
 16032                "ProjectTemplate:OpenTelemetry:ServiceName must not be empty.")
 13633            .Validate(options => !options.Otlp.Enabled || Uri.TryCreate(options.Otlp.Endpoint, UriKind.Absolute, out _),
 16034                "ProjectTemplate:OpenTelemetry:Otlp:Endpoint must be a valid absolute URI when OTLP export is enabled.")
 16035            .ValidateOnStart();
 36
 16037        ApplicationOpenTelemetryOptions options = configuration
 16038            .GetSection(ApplicationOpenTelemetryOptions.SectionName)
 16039            .Get<ApplicationOpenTelemetryOptions>() ?? new ApplicationOpenTelemetryOptions();
 40
 16041        if (!options.Enabled)
 42        {
 643            return services;
 44        }
 45
 15446        string serviceVersion = ResolveServiceVersion(options);
 47
 15448        OpenTelemetryBuilder openTelemetryBuilder = services
 15449            .AddOpenTelemetry()
 40850            .ConfigureResource(resource => resource
 40851                .AddService(
 40852                    serviceName: options.ServiceName,
 40853                    serviceVersion: serviceVersion)
 40854                .AddAttributes(new Dictionary<string, object>
 40855                {
 40856                    ["deployment.environment.name"] = environment.EnvironmentName
 40857                }));
 58
 15459        if (options.EnableTracing)
 60        {
 15261            openTelemetryBuilder.WithTracing(tracing =>
 15262            {
 15263                if (options.EnableAspNetCoreInstrumentation)
 15264                {
 15065                    tracing.AddAspNetCoreInstrumentation();
 15266                }
 15267
 15268                if (options.EnableHttpClientInstrumentation)
 15269                {
 15070                    tracing.AddHttpClientInstrumentation();
 15271                }
 15272
 15273                if (options.Otlp.Enabled)
 15274                {
 475                    tracing.AddOtlpExporter(exporterOptions => ConfigureOtlpExporter(exporterOptions, options.Otlp));
 15276                }
 30477            });
 78        }
 79
 15480        if (options.EnableMetrics)
 81        {
 15282            openTelemetryBuilder.WithMetrics(metrics =>
 15283            {
 15284                if (options.EnableAspNetCoreInstrumentation)
 15285                {
 15086                    metrics.AddAspNetCoreInstrumentation();
 15287                }
 15288
 15289                if (options.EnableHttpClientInstrumentation)
 15290                {
 15091                    metrics.AddHttpClientInstrumentation();
 15292                }
 15293
 15294                if (options.Otlp.Enabled)
 15295                {
 496                    metrics.AddOtlpExporter(exporterOptions => ConfigureOtlpExporter(exporterOptions, options.Otlp));
 15297                }
 30498            });
 99        }
 100
 154101        return services;
 102    }
 103
 104    private static void ConfigureOtlpExporter(
 105        OtlpExporterOptions exporterOptions,
 106        ApplicationOtlpExporterOptions options)
 107    {
 8108        exporterOptions.Endpoint = new Uri(options.Endpoint);
 8109        exporterOptions.Protocol = string.Equals(
 8110            options.Protocol,
 8111            "HttpProtobuf",
 8112            StringComparison.OrdinalIgnoreCase)
 8113            ? OtlpExportProtocol.HttpProtobuf
 8114            : OtlpExportProtocol.Grpc;
 8115    }
 116
 117    private static string ResolveServiceVersion(ApplicationOpenTelemetryOptions options)
 118    {
 162119        if (!string.IsNullOrWhiteSpace(options.ServiceVersion))
 120        {
 156121            return options.ServiceVersion.Trim();
 122        }
 123
 6124        Assembly assembly = typeof(Program).Assembly;
 125
 6126        string? informationalVersion = assembly
 6127            .GetCustomAttribute<AssemblyInformationalVersionAttribute>()
 6128            ?.InformationalVersion;
 129
 6130        return !string.IsNullOrWhiteSpace(informationalVersion) ? informationalVersion : assembly.GetName().Version?.ToS
 131    }
 132}