From d74cc78252f6b85258c902d423356843b224c590 Mon Sep 17 00:00:00 2001 From: Ben Stein Date: Mon, 6 Oct 2025 16:41:09 -0400 Subject: [PATCH 1/8] WIP service defaults lib --- .github/workflows/release-package.yml | 1 + .../Crucible.Common.ServiceDefaults.csproj | 38 +++++ src/Crucible.Common.ServiceDefaults/README.md | 3 + .../CrucibleOpenTelemetryExtensions.cs | 160 ++++++++++++++++++ .../CrucibleOpenTelemetryOptions.cs | 11 ++ 5 files changed, 213 insertions(+) create mode 100644 src/Crucible.Common.ServiceDefaults/Crucible.Common.ServiceDefaults.csproj create mode 100644 src/Crucible.Common.ServiceDefaults/README.md create mode 100644 src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs create mode 100644 src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml index 50fe29b..2cf9edb 100644 --- a/.github/workflows/release-package.yml +++ b/.github/workflows/release-package.yml @@ -9,6 +9,7 @@ on: type: choice options: - Crucible.Common.Authentication + - Crucible.Common.ServiceDefaults - Crucible.Common.Utilities versionNumber: description: "A semver version string (e.g. 1.0.0)" diff --git a/src/Crucible.Common.ServiceDefaults/Crucible.Common.ServiceDefaults.csproj b/src/Crucible.Common.ServiceDefaults/Crucible.Common.ServiceDefaults.csproj new file mode 100644 index 0000000..f667d4b --- /dev/null +++ b/src/Crucible.Common.ServiceDefaults/Crucible.Common.ServiceDefaults.csproj @@ -0,0 +1,38 @@ + + + + net8.0 + enable + enable + + + + + README.md + + + + + + + + + LICENSE.md + + + + + + + + + + + + + + + + + + diff --git a/src/Crucible.Common.ServiceDefaults/README.md b/src/Crucible.Common.ServiceDefaults/README.md new file mode 100644 index 0000000..4301622 --- /dev/null +++ b/src/Crucible.Common.ServiceDefaults/README.md @@ -0,0 +1,3 @@ +# Crucible.Common.ServiceDefaults + +Default service configuration for Crucible API apps. Right now, this is mostly just configuration for [OpenTelemetry](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/observability-with-otel), but may involve more stuff as we get going. diff --git a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs new file mode 100644 index 0000000..af388ba --- /dev/null +++ b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs @@ -0,0 +1,160 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +namespace Crucible.Common.ServiceDefaults.OpenTelemetry; + +public static class CrucibleOpenTelemetryExtensions +{ + public static IHostApplicationBuilder AddCrucibleOpenTelemetryServiceDefaults(this IHostApplicationBuilder builder, Action? optionsBuilder = null) + { + var options = new CrucibleOpenTelemetryOptions(); + if (optionsBuilder is not null) + { + optionsBuilder(options); + } + + builder.ConfigureOpenTelemetry(options); + // builder.AddDefaultHealthChecks(); + // builder.Services.AddServiceDiscovery(); + + // builder.Services.ConfigureHttpClientDefaults(http => + // { + // // Turn on resilience by default + // http.AddStandardResilienceHandler(); + + // // Turn on service discovery by default + // http.UseServiceDiscovery(); + // }); + + return builder; + } + + private static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder, CrucibleOpenTelemetryOptions options) + { + builder.Logging.AddOpenTelemetry(x => + { + x.IncludeScopes = true; + x.IncludeFormattedMessage = true; + + // Not doing this yet, but protects against "unknown_service" in traces/metrics, maybe? + // x.SetResourceBuilder + // ( + // ResourceBuilder + // .CreateDefault() + // .AddService + // ( + // serviceName: builder.Environment.ApplicationName, + // serviceVersion: typeof(Program).Assembly.GetName().Version?.ToString(), + // serviceInstanceId: Environment.MachineName + // ) + // ); + }); + + builder.Services + .AddOpenTelemetry() + .WithMetrics(x => + { + x.AddRuntimeInstrumentation(); + + if (options.IncludeDefaultMeters) + { + x.AddMeter + ( + "Microsoft.AspNetCore.Hosting", + "Microsoft.AspNetCore.Server.Kestrel", + "Microsoft.EntityFrameworkCore", + "System.Net.Http" + ); + } + + if (options.CustomMeters.Any()) + { + x.AddMeter([.. options.CustomMeters]); + } + }) + .WithTracing(x => + { + if (options.IncludeDefaultActivitySources) + { + x.AddSource("Microsoft.AspNetCore"); + x.AddSource("Microsoft.EntityFrameworkCore"); + x.AddSource("System.Net.Http"); + } + + if (options.CustomActivitySources.Any()) + { + x.AddSource([.. options.CustomActivitySources]); + } + + if (builder.Environment.IsDevelopment()) + { + x.SetSampler(); + } + + x + // record structured logs for traces + .AddAspNetCoreInstrumentation(o => o.RecordException = true) + .AddHttpClientInstrumentation() + .AddEntityFrameworkCoreInstrumentation(); + }); + + builder.AddOpenTelemetryExporters(options); + + return builder; + } + + private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostApplicationBuilder builder, CrucibleOpenTelemetryOptions options) + { + var isOtlpEndpointConfigured = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]); + + builder.Services.Configure(logging => + { + if (isOtlpEndpointConfigured) + { + logging.AddOtlpExporter(); + } + + if (options.AddConsoleExporter) + { + logging.AddConsoleExporter(); + } + }); + + builder.Services.ConfigureOpenTelemetryMeterProvider(metrics => + { + if (isOtlpEndpointConfigured) + { + metrics.AddOtlpExporter(); + } + + if (options.AddConsoleExporter) + { + metrics.AddConsoleExporter(); + } + + if (options.AddPrometheusExporter) + { + metrics.AddPrometheusExporter(); + } + }); + + builder.Services.ConfigureOpenTelemetryTracerProvider(tracing => + { + if (isOtlpEndpointConfigured) + { + tracing.AddOtlpExporter(); + } + + if (options.AddConsoleExporter) + { + tracing.AddConsoleExporter(); + } + }); + + return builder; + } +} diff --git a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs new file mode 100644 index 0000000..18d9cf9 --- /dev/null +++ b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs @@ -0,0 +1,11 @@ +namespace Crucible.Common.ServiceDefaults.OpenTelemetry; + +public sealed class CrucibleOpenTelemetryOptions +{ + public bool AddConsoleExporter { get; set; } = false; + public bool AddPrometheusExporter { get; set; } = false; + public IEnumerable CustomActivitySources { get; set; } = []; + public bool IncludeDefaultActivitySources { get; set; } = true; + public IEnumerable CustomMeters { get; set; } = []; + public bool IncludeDefaultMeters { get; set; } = true; +} From 914911ea821390772e02fada258e21189a7741c4 Mon Sep 17 00:00:00 2001 From: Ben Stein Date: Mon, 6 Oct 2025 16:52:48 -0400 Subject: [PATCH 2/8] Add projects to sln --- Crucible.Common.slnx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Crucible.Common.slnx b/Crucible.Common.slnx index 0ba2e84..8c49a80 100644 --- a/Crucible.Common.slnx +++ b/Crucible.Common.slnx @@ -6,6 +6,8 @@ + + From ecd51c73b2b27e0655663c666ac3dd4a542996b1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 20:59:41 +0000 Subject: [PATCH 3/8] Add missing document markings --- .../src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs | 3 +++ .../src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs index af388ba..453e14f 100644 --- a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs +++ b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs @@ -1,3 +1,6 @@ +// Copyright 2025 Carnegie Mellon University. All Rights Reserved. +// Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information. + using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; diff --git a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs index 18d9cf9..487d323 100644 --- a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs +++ b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs @@ -1,3 +1,6 @@ +// Copyright 2025 Carnegie Mellon University. All Rights Reserved. +// Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information. + namespace Crucible.Common.ServiceDefaults.OpenTelemetry; public sealed class CrucibleOpenTelemetryOptions From b641d1b9dbf5e84c34423c2ca227e73f8b382c67 Mon Sep 17 00:00:00 2001 From: Ben Stein Date: Tue, 7 Oct 2025 11:28:19 -0400 Subject: [PATCH 4/8] Add wrapper for OTEL config for IHostBuilder-style apps --- .../CrucibleOpenTelemetryExtensions.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs index af388ba..89fb639 100644 --- a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs +++ b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs @@ -9,6 +9,21 @@ namespace Crucible.Common.ServiceDefaults.OpenTelemetry; public static class CrucibleOpenTelemetryExtensions { + // wrapper for apps still using IHostBuilder (most apps created pre .NET Core 8) + public static IHostBuilder AddCrucibleOpenTelemetryServiceDefaults(this IHostBuilder builder, Action? optionsBuilder = null) + { + builder.ConfigureServices((context, services) => + { + var appBuilder = Host.CreateApplicationBuilder(); + appBuilder.AddCrucibleOpenTelemetryServiceDefaults(optionsBuilder); + + foreach (var svc in appBuilder.Services) + services.Add(svc); + }); + + return builder; + } + public static IHostApplicationBuilder AddCrucibleOpenTelemetryServiceDefaults(this IHostApplicationBuilder builder, Action? optionsBuilder = null) { var options = new CrucibleOpenTelemetryOptions(); From 2860d1ca404dada029c5d2e265551e6fd2614adf Mon Sep 17 00:00:00 2001 From: Ben Stein Date: Tue, 7 Oct 2025 12:43:56 -0400 Subject: [PATCH 5/8] Refactor for IHostBuilder --- .../CrucibleOpenTelemetryExtensions.cs | 75 ++++++++++++------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs index b8a0f1e..eb5b043 100644 --- a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs +++ b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs @@ -1,7 +1,8 @@ // Copyright 2025 Carnegie Mellon University. All Rights Reserved. // Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information. -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using OpenTelemetry.Logs; @@ -13,27 +14,26 @@ namespace Crucible.Common.ServiceDefaults.OpenTelemetry; public static class CrucibleOpenTelemetryExtensions { // wrapper for apps still using IHostBuilder (most apps created pre .NET Core 8) - public static IHostBuilder AddCrucibleOpenTelemetryServiceDefaults(this IHostBuilder builder, Action? optionsBuilder = null) + public static ILoggingBuilder AddCrucibleOpenTelemetryLogging(this ILoggingBuilder logging) { - builder.ConfigureServices((context, services) => - { - var appBuilder = Host.CreateApplicationBuilder(); - appBuilder.AddCrucibleOpenTelemetryServiceDefaults(optionsBuilder); + AddLogging(logging); + return logging; + } - foreach (var svc in appBuilder.Services) - services.Add(svc); - }); + // wrapper for apps still using IHostBuilder (most apps created pre .NET Core 8) + public static IServiceCollection AddCrucibleOpenTelemetryServices(this IServiceCollection services, IHostEnvironment hostEnvironment, IConfigurationManager configuration, Action? optionsBuilder = null) + { + var options = BuildOptions(optionsBuilder); - return builder; + AddServices(services, hostEnvironment, options); + AddExporters(services, configuration["OTEL_EXPORTER_OTLP_ENDPOINT"], options); + + return services; } public static IHostApplicationBuilder AddCrucibleOpenTelemetryServiceDefaults(this IHostApplicationBuilder builder, Action? optionsBuilder = null) { - var options = new CrucibleOpenTelemetryOptions(); - if (optionsBuilder is not null) - { - optionsBuilder(options); - } + var options = BuildOptions(optionsBuilder); builder.ConfigureOpenTelemetry(options); // builder.AddDefaultHealthChecks(); @@ -53,7 +53,17 @@ public static IHostApplicationBuilder AddCrucibleOpenTelemetryServiceDefaults(th private static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder, CrucibleOpenTelemetryOptions options) { - builder.Logging.AddOpenTelemetry(x => + // configure logging + AddLogging(builder.Logging); + AddServices(builder.Services, builder.Environment, options); + AddExporters(builder.Services, builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"], options); + + return builder; + } + + private static void AddLogging(this ILoggingBuilder logging) + { + logging.AddOpenTelemetry(x => { x.IncludeScopes = true; x.IncludeFormattedMessage = true; @@ -71,8 +81,11 @@ private static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicat // ) // ); }); + } - builder.Services + private static void AddServices(this IServiceCollection services, IHostEnvironment env, CrucibleOpenTelemetryOptions options) + { + services .AddOpenTelemetry() .WithMetrics(x => { @@ -108,7 +121,7 @@ private static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicat x.AddSource([.. options.CustomActivitySources]); } - if (builder.Environment.IsDevelopment()) + if (env.IsDevelopment()) { x.SetSampler(); } @@ -119,17 +132,13 @@ private static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicat .AddHttpClientInstrumentation() .AddEntityFrameworkCoreInstrumentation(); }); - - builder.AddOpenTelemetryExporters(options); - - return builder; } - private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostApplicationBuilder builder, CrucibleOpenTelemetryOptions options) + private static void AddExporters(this IServiceCollection services, string? otelExporterEndpoint, CrucibleOpenTelemetryOptions options) { - var isOtlpEndpointConfigured = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]); + var isOtlpEndpointConfigured = !string.IsNullOrWhiteSpace(otelExporterEndpoint); - builder.Services.Configure(logging => + services.Configure(logging => { if (isOtlpEndpointConfigured) { @@ -142,7 +151,7 @@ private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostAppli } }); - builder.Services.ConfigureOpenTelemetryMeterProvider(metrics => + services.ConfigureOpenTelemetryMeterProvider(metrics => { if (isOtlpEndpointConfigured) { @@ -160,7 +169,7 @@ private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostAppli } }); - builder.Services.ConfigureOpenTelemetryTracerProvider(tracing => + services.ConfigureOpenTelemetryTracerProvider(tracing => { if (isOtlpEndpointConfigured) { @@ -172,7 +181,17 @@ private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostAppli tracing.AddConsoleExporter(); } }); + } - return builder; + private static CrucibleOpenTelemetryOptions BuildOptions(Action? optionsBuilder = null) + { + var options = new CrucibleOpenTelemetryOptions(); + + if (optionsBuilder is not null) + { + optionsBuilder(options); + } + + return options; } } From 7f1292a868606c10255b0e8809a536f870c81a7b Mon Sep 17 00:00:00 2001 From: Ben Stein Date: Tue, 7 Oct 2025 12:49:06 -0400 Subject: [PATCH 6/8] Pull legacy configuration from IConfiguration rather than IConfigurationManager --- .../src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs index eb5b043..1ab6e93 100644 --- a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs +++ b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs @@ -21,7 +21,7 @@ public static ILoggingBuilder AddCrucibleOpenTelemetryLogging(this ILoggingBuild } // wrapper for apps still using IHostBuilder (most apps created pre .NET Core 8) - public static IServiceCollection AddCrucibleOpenTelemetryServices(this IServiceCollection services, IHostEnvironment hostEnvironment, IConfigurationManager configuration, Action? optionsBuilder = null) + public static IServiceCollection AddCrucibleOpenTelemetryServices(this IServiceCollection services, IHostEnvironment hostEnvironment, IConfiguration configuration, Action? optionsBuilder = null) { var options = BuildOptions(optionsBuilder); From f9d465256d5943cac27aba13e49b5f983bf7a1a6 Mon Sep 17 00:00:00 2001 From: Ben Stein Date: Tue, 7 Oct 2025 15:08:29 -0400 Subject: [PATCH 7/8] Clarify exposed extension function comments --- .../CrucibleOpenTelemetryExtensions.cs | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs index 1ab6e93..18f88cb 100644 --- a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs +++ b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs @@ -13,14 +13,31 @@ namespace Crucible.Common.ServiceDefaults.OpenTelemetry; public static class CrucibleOpenTelemetryExtensions { - // wrapper for apps still using IHostBuilder (most apps created pre .NET Core 8) + /// + /// Call to configure default configuration for OpenTelemetry-enhanced logging. + /// + /// NOTE: This function is exposed primarily for apps created before .NET Core 8 that bootstrap with IHostBuilder rather than the newer IHostApplicationBuilder. + /// If your app uses IHostApplicationBuilder, you shouldn't need to call this function directly. + /// + /// + /// public static ILoggingBuilder AddCrucibleOpenTelemetryLogging(this ILoggingBuilder logging) { AddLogging(logging); return logging; } - // wrapper for apps still using IHostBuilder (most apps created pre .NET Core 8) + /// + /// Call to configure default OpenTelemetry services. Customizable with the optionsBuilder parameter. See its properties for details. + /// + /// NOTE: This function is exposed primarily for apps created before .NET Core 8 that bootstrap with IHostBuilder rather than the newer IHostApplicationBuilder. + /// If your app uses IHostApplicationBuilder, you shouldn't need to call this function directly. + /// + /// Your app's service collection. + /// The hosting environment in which your app is starting up. + /// Your app's configuration. + /// A builder used to customize OpenTelemetry configuration. + /// public static IServiceCollection AddCrucibleOpenTelemetryServices(this IServiceCollection services, IHostEnvironment hostEnvironment, IConfiguration configuration, Action? optionsBuilder = null) { var options = BuildOptions(optionsBuilder); @@ -31,6 +48,12 @@ public static IServiceCollection AddCrucibleOpenTelemetryServices(this IServiceC return services; } + /// + /// Add default service and logging configuration for OpenTelemetry. Customizable with the optionsBuilder parameter. See its properties for details. + /// + /// Your app's + /// + /// public static IHostApplicationBuilder AddCrucibleOpenTelemetryServiceDefaults(this IHostApplicationBuilder builder, Action? optionsBuilder = null) { var options = BuildOptions(optionsBuilder); From 88715be0c6c5283972ecad60eae078c8ff38c3b9 Mon Sep 17 00:00:00 2001 From: Ben Stein Date: Tue, 7 Oct 2025 16:34:28 -0400 Subject: [PATCH 8/8] Parameterize always on sampler --- .../src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs | 2 +- .../src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs index 18f88cb..4402d10 100644 --- a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs +++ b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryExtensions.cs @@ -144,7 +144,7 @@ private static void AddServices(this IServiceCollection services, IHostEnvironme x.AddSource([.. options.CustomActivitySources]); } - if (env.IsDevelopment()) + if (options.AddAlwaysOnTracingSampler) { x.SetSampler(); } diff --git a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs index 487d323..196ae90 100644 --- a/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs +++ b/src/Crucible.Common.ServiceDefaults/src/OpenTelemetry/CrucibleOpenTelemetryOptions.cs @@ -5,6 +5,7 @@ namespace Crucible.Common.ServiceDefaults.OpenTelemetry; public sealed class CrucibleOpenTelemetryOptions { + public bool AddAlwaysOnTracingSampler { get; set; } = false; public bool AddConsoleExporter { get; set; } = false; public bool AddPrometheusExporter { get; set; } = false; public IEnumerable CustomActivitySources { get; set; } = [];