< 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    {
 17228        services
 17229            .AddOptions<ApplicationOpenTelemetryOptions>()
 17230            .Bind(configuration.GetSection(ApplicationOpenTelemetryOptions.SectionName))
 14431            .Validate(options => !string.IsNullOrWhiteSpace(options.ServiceName),
 17232                "ProjectTemplate:OpenTelemetry:ServiceName must not be empty.")
 14433            .Validate(options => !options.Otlp.Enabled || Uri.TryCreate(options.Otlp.Endpoint, UriKind.Absolute, out _),
 17234                "ProjectTemplate:OpenTelemetry:Otlp:Endpoint must be a valid absolute URI when OTLP export is enabled.")
 17235            .ValidateOnStart();
 36
 17237        ApplicationOpenTelemetryOptions options = configuration
 17238            .GetSection(ApplicationOpenTelemetryOptions.SectionName)
 17239            .Get<ApplicationOpenTelemetryOptions>() ?? new ApplicationOpenTelemetryOptions();
 40
 17241        if (!options.Enabled)
 42        {
 643            return services;
 44        }
 45
 16646        string serviceVersion = ResolveServiceVersion(options);
 47
 16648        OpenTelemetryBuilder openTelemetryBuilder = services
 16649            .AddOpenTelemetry()
 43850            .ConfigureResource(resource => resource
 43851                .AddService(
 43852                    serviceName: options.ServiceName,
 43853                    serviceVersion: serviceVersion)
 43854                .AddAttributes(new Dictionary<string, object>
 43855                {
 43856                    ["deployment.environment.name"] = environment.EnvironmentName
 43857                }));
 58
 16659        if (options.EnableTracing)
 60        {
 16461            openTelemetryBuilder.WithTracing(tracing =>
 16462            {
 16463                if (options.EnableAspNetCoreInstrumentation)
 16464                {
 16265                    tracing.AddAspNetCoreInstrumentation();
 16466                }
 16467
 16468                if (options.EnableHttpClientInstrumentation)
 16469                {
 16270                    tracing.AddHttpClientInstrumentation();
 16471                }
 16472
 16473                if (options.Otlp.Enabled)
 16474                {
 475                    tracing.AddOtlpExporter(exporterOptions => ConfigureOtlpExporter(exporterOptions, options.Otlp));
 16476                }
 32877            });
 78        }
 79
 16680        if (options.EnableMetrics)
 81        {
 16482            openTelemetryBuilder.WithMetrics(metrics =>
 16483            {
 16484                if (options.EnableAspNetCoreInstrumentation)
 16485                {
 16286                    metrics.AddAspNetCoreInstrumentation();
 16487                }
 16488
 16489                if (options.EnableHttpClientInstrumentation)
 16490                {
 16291                    metrics.AddHttpClientInstrumentation();
 16492                }
 16493
 16494                if (options.Otlp.Enabled)
 16495                {
 496                    metrics.AddOtlpExporter(exporterOptions => ConfigureOtlpExporter(exporterOptions, options.Otlp));
 16497                }
 32898            });
 99        }
 100
 166101        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    {
 174119        if (!string.IsNullOrWhiteSpace(options.ServiceVersion))
 120        {
 168121            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}