Optimize metrics loading (#1532)
This commit is contained in:
parent
885b2c4e43
commit
6f27769b7b
|
|
@ -15,8 +15,8 @@
|
|||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using OpenTelemetry.AutoInstrumentation.Logging;
|
||||
using OpenTelemetry.Metrics;
|
||||
|
||||
|
|
@ -25,13 +25,6 @@ namespace OpenTelemetry.AutoInstrumentation.Configuration;
|
|||
internal static class EnvironmentConfigurationMetricHelper
|
||||
{
|
||||
private static readonly ILogger Logger = OtelLogging.GetLogger();
|
||||
private static readonly Dictionary<MetricInstrumentation, Action<MeterProviderBuilder>> AddMeters = new()
|
||||
{
|
||||
[MetricInstrumentation.AspNet] = builder => builder.AddSdkAspNetInstrumentation(),
|
||||
[MetricInstrumentation.HttpClient] = builder => builder.AddHttpClientInstrumentation(),
|
||||
[MetricInstrumentation.NetRuntime] = builder => builder.AddRuntimeInstrumentation(),
|
||||
[MetricInstrumentation.Process] = builder => builder.AddProcessInstrumentation(),
|
||||
};
|
||||
|
||||
public static MeterProviderBuilder UseEnvironmentVariables(this MeterProviderBuilder builder, MetricSettings settings)
|
||||
{
|
||||
|
|
@ -41,31 +34,79 @@ internal static class EnvironmentConfigurationMetricHelper
|
|||
|
||||
foreach (var enabledMeter in settings.EnabledInstrumentations)
|
||||
{
|
||||
if (AddMeters.TryGetValue(enabledMeter, out var addMeter))
|
||||
_ = enabledMeter switch
|
||||
{
|
||||
addMeter(builder);
|
||||
}
|
||||
MetricInstrumentation.AspNet => Wrappers.AddSdkAspNetInstrumentation(builder),
|
||||
MetricInstrumentation.HttpClient => Wrappers.AddHttpClientInstrumentation(builder),
|
||||
MetricInstrumentation.NetRuntime => Wrappers.AddRuntimeInstrumentation(builder),
|
||||
MetricInstrumentation.Process => Wrappers.AddProcessInstrumentation(builder),
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static MeterProviderBuilder AddSdkAspNetInstrumentation(this MeterProviderBuilder builder)
|
||||
{
|
||||
#if NET462
|
||||
builder.AddAspNetInstrumentation();
|
||||
#elif NETCOREAPP3_1_OR_GREATER
|
||||
builder.AddMeter("OpenTelemetry.Instrumentation.AspNetCore");
|
||||
#endif
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static MeterProviderBuilder SetExporter(this MeterProviderBuilder builder, MetricSettings settings)
|
||||
{
|
||||
if (settings.ConsoleExporterEnabled)
|
||||
{
|
||||
builder.AddConsoleExporter((_, metricReaderOptions) =>
|
||||
Wrappers.AddConsoleExporter(builder, settings);
|
||||
}
|
||||
|
||||
return settings.MetricExporter switch
|
||||
{
|
||||
MetricsExporter.Prometheus => Wrappers.AddPrometheusExporter(builder),
|
||||
MetricsExporter.Otlp => Wrappers.AddOtlpExporter(builder, settings),
|
||||
MetricsExporter.None => builder,
|
||||
_ => throw new ArgumentOutOfRangeException($"Metrics exporter '{settings.MetricExporter}' is incorrect")
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class wraps external extension methods to ensure the dlls are not loaded, if not necessary.
|
||||
/// .NET Framework is aggressively inlining these wrappers. Inlining must be disabled to ensure the wrapping effect.
|
||||
/// </summary>
|
||||
private static class Wrappers
|
||||
{
|
||||
// Meters
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static MeterProviderBuilder AddSdkAspNetInstrumentation(MeterProviderBuilder builder)
|
||||
{
|
||||
#if NET462
|
||||
builder.AddAspNetInstrumentation();
|
||||
#elif NETCOREAPP3_1_OR_GREATER
|
||||
builder.AddMeter("OpenTelemetry.Instrumentation.AspNetCore");
|
||||
#endif
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static MeterProviderBuilder AddHttpClientInstrumentation(MeterProviderBuilder builder)
|
||||
{
|
||||
return builder.AddHttpClientInstrumentation();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static MeterProviderBuilder AddRuntimeInstrumentation(MeterProviderBuilder builder)
|
||||
{
|
||||
return builder.AddRuntimeInstrumentation();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static MeterProviderBuilder AddProcessInstrumentation(MeterProviderBuilder builder)
|
||||
{
|
||||
return builder.AddProcessInstrumentation();
|
||||
}
|
||||
|
||||
// Exporters
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static MeterProviderBuilder AddConsoleExporter(MeterProviderBuilder builder, MetricSettings settings)
|
||||
{
|
||||
return builder.AddConsoleExporter((_, metricReaderOptions) =>
|
||||
{
|
||||
if (settings.MetricExportInterval != null)
|
||||
{
|
||||
|
|
@ -74,45 +115,43 @@ internal static class EnvironmentConfigurationMetricHelper
|
|||
});
|
||||
}
|
||||
|
||||
switch (settings.MetricExporter)
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static MeterProviderBuilder AddPrometheusExporter(MeterProviderBuilder builder)
|
||||
{
|
||||
case MetricsExporter.Prometheus:
|
||||
Logger.Warning("Prometheus exporter is configured. It is intended for the inner dev loop. Do NOT use in production");
|
||||
builder.AddPrometheusExporter(options =>
|
||||
{
|
||||
options.StartHttpListener = true;
|
||||
options.ScrapeResponseCacheDurationMilliseconds = 300;
|
||||
});
|
||||
break;
|
||||
case MetricsExporter.Otlp:
|
||||
#if NETCOREAPP3_1
|
||||
if (settings.Http2UnencryptedSupportEnabled)
|
||||
{
|
||||
// Adding the OtlpExporter creates a GrpcChannel.
|
||||
// This switch must be set before creating a GrpcChannel/HttpClient when calling an insecure gRPC service.
|
||||
// See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client
|
||||
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
|
||||
}
|
||||
#endif
|
||||
builder.AddOtlpExporter((options, metricReaderOptions) =>
|
||||
{
|
||||
if (settings.OtlpExportProtocol.HasValue)
|
||||
{
|
||||
options.Protocol = settings.OtlpExportProtocol.Value;
|
||||
}
|
||||
Logger.Warning("Prometheus exporter is configured. It is intended for the inner dev loop. Do NOT use in production");
|
||||
|
||||
if (settings.MetricExportInterval != null)
|
||||
{
|
||||
metricReaderOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = settings.MetricExportInterval;
|
||||
}
|
||||
});
|
||||
break;
|
||||
case MetricsExporter.None:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException($"Metrics exporter '{settings.MetricExporter}' is incorrect");
|
||||
return builder.AddPrometheusExporter(options =>
|
||||
{
|
||||
options.StartHttpListener = true;
|
||||
options.ScrapeResponseCacheDurationMilliseconds = 300;
|
||||
});
|
||||
}
|
||||
|
||||
return builder;
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static MeterProviderBuilder AddOtlpExporter(MeterProviderBuilder builder, MetricSettings settings)
|
||||
{
|
||||
#if NETCOREAPP3_1
|
||||
if (settings.Http2UnencryptedSupportEnabled)
|
||||
{
|
||||
// Adding the OtlpExporter creates a GrpcChannel.
|
||||
// This switch must be set before creating a GrpcChannel/HttpClient when calling an insecure gRPC service.
|
||||
// See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client
|
||||
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
|
||||
}
|
||||
#endif
|
||||
|
||||
return builder.AddOtlpExporter((options, metricReaderOptions) =>
|
||||
{
|
||||
if (settings.OtlpExportProtocol.HasValue)
|
||||
{
|
||||
options.Protocol = settings.OtlpExportProtocol.Value;
|
||||
}
|
||||
|
||||
if (settings.MetricExportInterval != null)
|
||||
{
|
||||
metricReaderOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = settings.MetricExportInterval;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,7 @@
|
|||
OpenTelemetry.AutoInstrumentation,
|
||||
OpenTelemetry.AutoInstrumentation.Loader,
|
||||
OpenTelemetry.AutoInstrumentation.StartupHook,
|
||||
OpenTelemetry.Exporter.Console,
|
||||
OpenTelemetry.Exporter.OpenTelemetryProtocol,
|
||||
OpenTelemetry.Exporter.Prometheus,
|
||||
OpenTelemetry.Instrumentation.GrpcNetClient,
|
||||
OpenTelemetry.Instrumentation.Http,
|
||||
OpenTelemetry.Instrumentation.Process,
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@
|
|||
OpenTelemetry.Api,
|
||||
OpenTelemetry.AutoInstrumentation,
|
||||
OpenTelemetry.AutoInstrumentation.Loader,
|
||||
OpenTelemetry.Exporter.Console,
|
||||
OpenTelemetry.Exporter.OpenTelemetryProtocol,
|
||||
OpenTelemetry.Exporter.Prometheus,
|
||||
OpenTelemetry.Instrumentation.AspNet,
|
||||
OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule,
|
||||
OpenTelemetry.Instrumentation.GrpcNetClient,
|
||||
|
|
|
|||
|
|
@ -4,11 +4,6 @@
|
|||
OpenTelemetry.AutoInstrumentation,
|
||||
OpenTelemetry.AutoInstrumentation.Loader,
|
||||
OpenTelemetry.AutoInstrumentation.StartupHook,
|
||||
OpenTelemetry.Exporter.Console,
|
||||
OpenTelemetry.Exporter.OpenTelemetryProtocol,
|
||||
OpenTelemetry.Exporter.Prometheus,
|
||||
OpenTelemetry.Instrumentation.Http,
|
||||
OpenTelemetry.Instrumentation.Process,
|
||||
OpenTelemetry.Instrumentation.Runtime,
|
||||
OpenTelemetry.Shims.OpenTracing
|
||||
]
|
||||
|
|
@ -3,13 +3,6 @@
|
|||
OpenTelemetry.Api,
|
||||
OpenTelemetry.AutoInstrumentation,
|
||||
OpenTelemetry.AutoInstrumentation.Loader,
|
||||
OpenTelemetry.Exporter.Console,
|
||||
OpenTelemetry.Exporter.OpenTelemetryProtocol,
|
||||
OpenTelemetry.Exporter.Prometheus,
|
||||
OpenTelemetry.Instrumentation.AspNet,
|
||||
OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule,
|
||||
OpenTelemetry.Instrumentation.Http,
|
||||
OpenTelemetry.Instrumentation.Process,
|
||||
OpenTelemetry.Instrumentation.Runtime,
|
||||
OpenTelemetry.Shims.OpenTracing
|
||||
]
|
||||
|
|
@ -51,8 +51,11 @@ public class ModuleTests : TestHelper
|
|||
public async Task Minimal()
|
||||
{
|
||||
SetEnvironmentVariable(ConfigurationKeys.Traces.Instrumentations, Constants.ConfigurationValues.None);
|
||||
SetEnvironmentVariable(ConfigurationKeys.Metrics.Instrumentations, Constants.ConfigurationValues.None);
|
||||
SetEnvironmentVariable(ConfigurationKeys.Traces.Exporter, Constants.ConfigurationValues.None);
|
||||
SetEnvironmentVariable(ConfigurationKeys.Metrics.Exporter, Constants.ConfigurationValues.None);
|
||||
SetEnvironmentVariable(ConfigurationKeys.Traces.ConsoleExporterEnabled, bool.FalseString);
|
||||
SetEnvironmentVariable(ConfigurationKeys.Metrics.ConsoleExporterEnabled, bool.FalseString);
|
||||
|
||||
string verifyTestName =
|
||||
#if NETFRAMEWORK
|
||||
|
|
|
|||
Loading…
Reference in New Issue