diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/AzureMonitorExporterMetricExtensions.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/AzureMonitorExporterMetricExtensions.cs index 87442f602f1c..91596b02d83b 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/AzureMonitorExporterMetricExtensions.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/AzureMonitorExporterMetricExtensions.cs @@ -3,7 +3,6 @@ using System; using Azure.Core; -using Azure.Monitor.OpenTelemetry.Exporter.Internals; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Metrics; @@ -47,8 +46,6 @@ public static MeterProviderBuilder AddAzureMonitorMetricExporter( builder.ConfigureServices(services => services.Configure(finalOptionsName, configure)); } - builder.AddMeter(StandardMetricConstants.StandardMetricMeterName); - return builder.AddReader(sp => { var exporterOptions = sp.GetRequiredService>().Get(finalOptionsName); diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/AzureMonitorExporterTraceExtensions.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/AzureMonitorExporterTraceExtensions.cs index 8067cd34e6d5..a6fcbb0c4f86 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/AzureMonitorExporterTraceExtensions.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/AzureMonitorExporterTraceExtensions.cs @@ -72,7 +72,7 @@ public static TracerProviderBuilder AddAzureMonitorTraceExporter( return new CompositeProcessor(new BaseProcessor[] { - new StandardMetricsExtractionProcessor(), + new StandardMetricsExtractionProcessor(new AzureMonitorMetricExporter(exporterOptions)), new BatchActivityExportProcessor(new AzureMonitorTraceExporter(exporterOptions)) }); }); diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/StandardMetricsExtractionProcessor.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/StandardMetricsExtractionProcessor.cs index db78a988316d..900090499ca1 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/StandardMetricsExtractionProcessor.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/src/Internals/StandardMetricsExtractionProcessor.cs @@ -7,6 +7,7 @@ using System.Diagnostics.Metrics; using Azure.Monitor.OpenTelemetry.Exporter.Models; using OpenTelemetry; +using OpenTelemetry.Metrics; namespace Azure.Monitor.OpenTelemetry.Exporter.Internals { @@ -14,6 +15,7 @@ internal class StandardMetricsExtractionProcessor : BaseProcessor { private bool _disposed; private AzureMonitorResource? _resource; + internal readonly MeterProvider? _meterProvider; private readonly Meter _meter; private readonly Histogram _requestDuration; private readonly Histogram _dependencyDuration; @@ -26,8 +28,13 @@ internal class StandardMetricsExtractionProcessor : BaseProcessor internal AzureMonitorResource? StandardMetricResource => _resource ??= ParentProvider?.GetResource().CreateAzureMonitorResource(); - internal StandardMetricsExtractionProcessor() + internal StandardMetricsExtractionProcessor(AzureMonitorMetricExporter metricExporter) { + _meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter(StandardMetricConstants.StandardMetricMeterName) + .AddReader(new PeriodicExportingMetricReader(metricExporter) + { TemporalityPreference = MetricReaderTemporalityPreference.Delta }) + .Build(); _meter = new Meter(StandardMetricConstants.StandardMetricMeterName); _requestDuration = _meter.CreateHistogram(StandardMetricConstants.RequestDurationInstrumentName); _dependencyDuration = _meter.CreateHistogram(StandardMetricConstants.DependencyDurationInstrumentName); @@ -111,6 +118,7 @@ protected override void Dispose(bool disposing) { try { + _meterProvider?.Dispose(); _meter?.Dispose(); } catch (Exception) diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/tests/Azure.Monitor.OpenTelemetry.Exporter.Tests/StandardMetricTests.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/tests/Azure.Monitor.OpenTelemetry.Exporter.Tests/StandardMetricTests.cs index f1ff7f7e9ae1..98ca6c2431b2 100644 --- a/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/tests/Azure.Monitor.OpenTelemetry.Exporter.Tests/StandardMetricTests.cs +++ b/sdk/monitor/Azure.Monitor.OpenTelemetry.Exporter/tests/Azure.Monitor.OpenTelemetry.Exporter.Tests/StandardMetricTests.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Linq; using System.Threading; +using OpenTelemetry.Resources; using Azure.Monitor.OpenTelemetry.Exporter.Internals; using Azure.Monitor.OpenTelemetry.Exporter.Models; using Azure.Monitor.OpenTelemetry.Exporter.Tests.CommonTestFramework; @@ -25,21 +26,19 @@ public void ValidateRequestDurationMetric() var traceTelemetryItems = new List(); var metricTelemetryItems = new List(); - var standardMetricCustomProcessor = new StandardMetricsExtractionProcessor(); + var standardMetricCustomProcessor = new StandardMetricsExtractionProcessor(new AzureMonitorMetricExporter(new MockTransmitter(metricTelemetryItems))); + + var traceServiceName = new KeyValuePair("service.name", "trace.service"); + var resourceAttributes = new KeyValuePair[] { traceServiceName }; using var tracerProvider = Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddAttributes(resourceAttributes)) .AddSource(nameof(StandardMetricTests.ValidateRequestDurationMetric)) .AddProcessor(standardMetricCustomProcessor) .AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new MockTransmitter(traceTelemetryItems)))) .Build(); - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter(StandardMetricConstants.StandardMetricMeterName) - .AddReader(new PeriodicExportingMetricReader(new AzureMonitorMetricExporter(new MockTransmitter(metricTelemetryItems))) - { TemporalityPreference = MetricReaderTemporalityPreference.Delta }) - .Build(); - using (var activity = activitySource.StartActivity("Test", ActivityKind.Server)) { activity?.SetTag(SemanticConventions.AttributeHttpStatusCode, 200); @@ -49,7 +48,7 @@ public void ValidateRequestDurationMetric() WaitForActivityExport(traceTelemetryItems); - meterProvider?.ForceFlush(); + standardMetricCustomProcessor._meterProvider?.ForceFlush(); // Standard Metrics + Resource Metrics. Assert.Single(metricTelemetryItems); @@ -64,7 +63,8 @@ public void ValidateRequestDurationMetric() Assert.True(metricData.Properties.TryGetValue(StandardMetricConstants.IsAutoCollectedKey, out var isAutoCollectedFlag)); Assert.Equal("True", isAutoCollectedFlag); Assert.True(metricData.Properties.TryGetValue(StandardMetricConstants.CloudRoleInstanceKey, out _)); - Assert.True(metricData.Properties.TryGetValue(StandardMetricConstants.CloudRoleNameKey, out _)); + Assert.True(metricData.Properties.TryGetValue(StandardMetricConstants.CloudRoleNameKey, out var cloudRoleName)); + Assert.Equal("trace.service", cloudRoleName); Assert.True(metricData.Properties.TryGetValue(StandardMetricConstants.MetricIdKey, out var metricId)); Assert.Equal(StandardMetricConstants.RequestDurationMetricIdValue, metricId); } @@ -76,21 +76,19 @@ public void ValidateDependencyDurationMetric() var traceTelemetryItems = new List(); var metricTelemetryItems = new List(); - var standardMetricCustomProcessor = new StandardMetricsExtractionProcessor(); + var standardMetricCustomProcessor = new StandardMetricsExtractionProcessor(new AzureMonitorMetricExporter(new MockTransmitter(metricTelemetryItems))); + + var traceServiceName = new KeyValuePair("service.name", "trace.service"); + var resourceAttributes = new KeyValuePair[] { traceServiceName }; using var tracerProvider = Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddAttributes(resourceAttributes)) .AddSource(nameof(StandardMetricTests.ValidateDependencyDurationMetric)) .AddProcessor(standardMetricCustomProcessor) .AddProcessor(new BatchActivityExportProcessor(new AzureMonitorTraceExporter(new MockTransmitter(traceTelemetryItems)))) .Build(); - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter(StandardMetricConstants.StandardMetricMeterName) - .AddReader(new PeriodicExportingMetricReader(new AzureMonitorMetricExporter(new MockTransmitter(metricTelemetryItems))) - { TemporalityPreference = MetricReaderTemporalityPreference.Delta }) - .Build(); - using (var activity = activitySource.StartActivity("Test", ActivityKind.Client)) { activity?.SetTag(SemanticConventions.AttributeHttpStatusCode, 200); @@ -102,7 +100,7 @@ public void ValidateDependencyDurationMetric() WaitForActivityExport(traceTelemetryItems); - meterProvider?.ForceFlush(); + standardMetricCustomProcessor._meterProvider?.ForceFlush(); // Standard Metrics + Resource Metrics. Assert.Single(metricTelemetryItems); @@ -117,7 +115,8 @@ public void ValidateDependencyDurationMetric() Assert.True(metricData.Properties.TryGetValue(StandardMetricConstants.IsAutoCollectedKey, out var isAutoCollectedFlag)); Assert.Equal("True", isAutoCollectedFlag); Assert.True(metricData.Properties.TryGetValue(StandardMetricConstants.CloudRoleInstanceKey, out _)); - Assert.True(metricData.Properties.TryGetValue(StandardMetricConstants.CloudRoleNameKey, out _)); + Assert.True(metricData.Properties.TryGetValue(StandardMetricConstants.CloudRoleNameKey, out var cloudRoleName)); + Assert.Equal("trace.service", cloudRoleName); Assert.True(metricData.Properties.TryGetValue(StandardMetricConstants.MetricIdKey, out var metricId)); Assert.Equal(StandardMetricConstants.DependencyDurationMetricIdValue, metricId); Assert.True(metricData.Properties.TryGetValue(StandardMetricConstants.DependencyTypeKey, out var dependencyType));