diff --git a/src/Grafana.OpenTelemetry.Base/GrafanaOpenTelemetryEventSource.cs b/src/Grafana.OpenTelemetry.Base/GrafanaOpenTelemetryEventSource.cs index c88744e2..530a6f25 100644 --- a/src/Grafana.OpenTelemetry.Base/GrafanaOpenTelemetryEventSource.cs +++ b/src/Grafana.OpenTelemetry.Base/GrafanaOpenTelemetryEventSource.cs @@ -7,10 +7,14 @@ using System.Diagnostics.Tracing; using System.Text.Json; +#if NET +using System.Text.Json.Serialization; +#endif + namespace Grafana.OpenTelemetry { [EventSource(Name = "OpenTelemetry-Grafana-Distribution")] - internal sealed class GrafanaOpenTelemetryEventSource : EventSource + internal sealed partial class GrafanaOpenTelemetryEventSource : EventSource { public static GrafanaOpenTelemetryEventSource Log = new GrafanaOpenTelemetryEventSource(); @@ -53,7 +57,11 @@ public void FailureEnablingTracingInstrumentation(string instrumentationLibrary, [NonEvent] public void InitializeDistribution(GrafanaOpenTelemetrySettings settings) { +#if NET + var settingsJson = JsonSerializer.Serialize(settings, GrafanaJsonSerializerContext.Default.GrafanaOpenTelemetrySettings); +#else var settingsJson = JsonSerializer.Serialize(settings); +#endif InitializeDistribution(settingsJson); } @@ -75,5 +83,11 @@ public void FailureEnablingInstrumentation(string signal, string instrumentation { this.WriteEvent(3, signal, instrumentationLibrary, ex); } + +#if NET + [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [JsonSerializable(typeof(GrafanaOpenTelemetrySettings))] + private sealed partial class GrafanaJsonSerializerContext : JsonSerializerContext; +#endif } } diff --git a/src/Grafana.OpenTelemetry.Base/GrafanaOpenTelemetrySettings.cs b/src/Grafana.OpenTelemetry.Base/GrafanaOpenTelemetrySettings.cs index da2292e2..721559e5 100644 --- a/src/Grafana.OpenTelemetry.Base/GrafanaOpenTelemetrySettings.cs +++ b/src/Grafana.OpenTelemetry.Base/GrafanaOpenTelemetrySettings.cs @@ -38,7 +38,12 @@ public class GrafanaOpenTelemetrySettings /// /// By default, all available instrumentations are activated. /// - public HashSet Instrumentations { get; } = new HashSet((Instrumentation[])Enum.GetValues(typeof(Instrumentation))); + public HashSet Instrumentations { get; } = +#if NET + [.. Enum.GetValues()]; +#else + new HashSet((Instrumentation[])Enum.GetValues(typeof(Instrumentation))); +#endif /// /// Gets the list of resource detectors to be activated. @@ -114,10 +119,11 @@ internal GrafanaOpenTelemetrySettings(IConfiguration configuration) Instrumentations.Remove(Instrumentation.AWSLambda); var disableInstrumentations = configuration[DisableInstrumentationsEnvVarName]; + char[] separators = new char[] { ',', ':' }; if (!string.IsNullOrEmpty(disableInstrumentations)) { - foreach (var instrumentationStr in disableInstrumentations.Split(new char[] { ',', ':' })) + foreach (var instrumentationStr in disableInstrumentations.Split(separators)) { if (Enum.TryParse(instrumentationStr, out var instrumentation)) { @@ -132,7 +138,7 @@ internal GrafanaOpenTelemetrySettings(IConfiguration configuration) { ResourceDetectors.Clear(); - foreach (var resourceDetectorStr in resourceDetectors.Split(new char[] { ',', ':' })) + foreach (var resourceDetectorStr in resourceDetectors.Split(separators)) { if (Enum.TryParse(resourceDetectorStr, out var resourceDetector)) { @@ -145,7 +151,7 @@ internal GrafanaOpenTelemetrySettings(IConfiguration configuration) if (!string.IsNullOrEmpty(disableResourceDetectors)) { - foreach (var resourceDetectorStr in disableResourceDetectors.Split(new char[] { ',', ':' })) + foreach (var resourceDetectorStr in disableResourceDetectors.Split(separators)) { if (Enum.TryParse(resourceDetectorStr, out var resourceDetector)) { diff --git a/src/Grafana.OpenTelemetry.Base/Instrumentations/InstrumentationInitializer.cs b/src/Grafana.OpenTelemetry.Base/Instrumentations/InstrumentationInitializer.cs index 345ac981..6a6b316a 100644 --- a/src/Grafana.OpenTelemetry.Base/Instrumentations/InstrumentationInitializer.cs +++ b/src/Grafana.OpenTelemetry.Base/Instrumentations/InstrumentationInitializer.cs @@ -4,38 +4,22 @@ // using System; +using System.Collections.Generic; using OpenTelemetry.Metrics; using OpenTelemetry.Trace; +#if NET +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +#endif + namespace Grafana.OpenTelemetry { internal abstract class InstrumentationInitializer { - public static InstrumentationInitializer[] Initializers = new InstrumentationInitializer[] - { -#if NETFRAMEWORK - new AspNetInitializer(), - new OwinInitializer(), -#endif - new AspNetCoreInitializer(), - new AWSInitializer(), - new AWSLambdaInitializer(), - new CassandraInitializer(), - new ElasticsearchClientInitializer(), - new EntityFrameworkCoreInitializer(), - new GrpcNetClientInitializer(), - new HangfireInitializer(), - new HttpClientInitializer(), - new MySqlDataInitializer(), - new NetRuntimeMetricsInitializer(), - new ProcessMetricsInitializer(), - new QuartzInitializer(), - new SqlClientInitializer(), - new StackExchangeRedisInitializer(), - new WcfInitializer(), - }; + public static InstrumentationInitializer[] Initializers = GetDefaults(); - abstract public Instrumentation Id { get; } + public abstract Instrumentation Id { get; } public void Initialize(TracerProviderBuilder builder) { @@ -70,5 +54,48 @@ protected virtual void InitializeTracing(TracerProviderBuilder builder) protected virtual void InitializeMetrics(MeterProviderBuilder builder) { } + +#if NET + [UnconditionalSuppressMessage( + "Trimming", + "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", + Justification = "Usage of is SqlClientInitializer guarded.")] +#endif + private static InstrumentationInitializer[] GetDefaults() + { + var initializers = new List + { +#if NETFRAMEWORK + new AspNetInitializer(), + new OwinInitializer(), +#endif + new AspNetCoreInitializer(), + new AWSInitializer(), + new AWSLambdaInitializer(), + new CassandraInitializer(), + new ElasticsearchClientInitializer(), + new EntityFrameworkCoreInitializer(), + new GrpcNetClientInitializer(), + new HangfireInitializer(), + new HttpClientInitializer(), + new MySqlDataInitializer(), + new NetRuntimeMetricsInitializer(), + new ProcessMetricsInitializer(), + new QuartzInitializer(), + new StackExchangeRedisInitializer(), + new WcfInitializer(), + }; + +#if NET + if (RuntimeFeature.IsDynamicCodeSupported) + { + initializers.Add(new SqlClientInitializer()); + } +#else + initializers.Add(new SqlClientInitializer()); +#endif + + return initializers.ToArray(); + } } } diff --git a/src/Grafana.OpenTelemetry.Base/Instrumentations/SqlClientInitializer.cs b/src/Grafana.OpenTelemetry.Base/Instrumentations/SqlClientInitializer.cs index 3885ef6a..ab4bdfbf 100644 --- a/src/Grafana.OpenTelemetry.Base/Instrumentations/SqlClientInitializer.cs +++ b/src/Grafana.OpenTelemetry.Base/Instrumentations/SqlClientInitializer.cs @@ -7,6 +7,9 @@ namespace Grafana.OpenTelemetry { +#if NET + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Trimming is not yet supported with SqlClient instrumentation.")] +#endif internal class SqlClientInitializer : InstrumentationInitializer { public override Instrumentation Id { get; } = Instrumentation.SqlClient;