From 482bfb96ccd63da733bea3fe1f7f65fb4a3b6c67 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 23 Aug 2023 14:43:00 -0700 Subject: [PATCH] [release/8.0] Only initialize listeners once (#90932) * Only initialize listeners once. * Add test * Second call --------- Co-authored-by: Chris R --- .../Microsoft.Extensions.Diagnostics.sln | 49 ++++++++++++++++++++++ .../src/Metrics/MetricsServiceExtensions.cs | 10 ++++- .../tests/MetricsSubscriptionManagerTests.cs | 44 +++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 src/libraries/Microsoft.Extensions.Diagnostics/tests/MetricsSubscriptionManagerTests.cs diff --git a/src/libraries/Microsoft.Extensions.Diagnostics/Microsoft.Extensions.Diagnostics.sln b/src/libraries/Microsoft.Extensions.Diagnostics/Microsoft.Extensions.Diagnostics.sln index 5e4931e..5b249c3 100644 --- a/src/libraries/Microsoft.Extensions.Diagnostics/Microsoft.Extensions.Diagnostics.sln +++ b/src/libraries/Microsoft.Extensions.Diagnostics/Microsoft.Extensions.Diagnostics.sln @@ -59,6 +59,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Config EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options", "..\Microsoft.Extensions.Options\ref\Microsoft.Extensions.Options.csproj", "{DBAB1C82-A3A0-4ADC-95BC-B87557C61C42}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Primitives", "..\Microsoft.Extensions.Primitives\ref\Microsoft.Extensions.Primitives.csproj", "{6BB43905-3DBD-47E4-A38F-2BE319300B15}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Primitives", "..\Microsoft.Extensions.Primitives\src\Microsoft.Extensions.Primitives.csproj", "{711B2905-FDC7-4D67-B40B-9DEFF042CB01}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options", "..\Microsoft.Extensions.Options\src\Microsoft.Extensions.Options.csproj", "{B233AB55-788C-48B6-9557-098B8D0DDBFF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Configuration.Binder", "..\Microsoft.Extensions.Configuration.Binder\src\Microsoft.Extensions.Configuration.Binder.csproj", "{ECF14067-8633-4DDA-8EAE-124989F8E09E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Configuration.Binder", "..\Microsoft.Extensions.Configuration.Binder\ref\Microsoft.Extensions.Configuration.Binder.csproj", "{D835A0A8-C213-461F-8B41-6F2715DBEC43}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options.ConfigurationExtensions", "..\Microsoft.Extensions.Options.ConfigurationExtensions\ref\Microsoft.Extensions.Options.ConfigurationExtensions.csproj", "{F2C0D619-8CAF-4F81-B681-3F75AF79661F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Configuration", "..\Microsoft.Extensions.Configuration\ref\Microsoft.Extensions.Configuration.csproj", "{57AF678A-3671-4B9E-9608-053E2197D0A4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -161,6 +175,34 @@ Global {DBAB1C82-A3A0-4ADC-95BC-B87557C61C42}.Debug|Any CPU.Build.0 = Debug|Any CPU {DBAB1C82-A3A0-4ADC-95BC-B87557C61C42}.Release|Any CPU.ActiveCfg = Release|Any CPU {DBAB1C82-A3A0-4ADC-95BC-B87557C61C42}.Release|Any CPU.Build.0 = Release|Any CPU + {6BB43905-3DBD-47E4-A38F-2BE319300B15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6BB43905-3DBD-47E4-A38F-2BE319300B15}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6BB43905-3DBD-47E4-A38F-2BE319300B15}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6BB43905-3DBD-47E4-A38F-2BE319300B15}.Release|Any CPU.Build.0 = Release|Any CPU + {711B2905-FDC7-4D67-B40B-9DEFF042CB01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {711B2905-FDC7-4D67-B40B-9DEFF042CB01}.Debug|Any CPU.Build.0 = Debug|Any CPU + {711B2905-FDC7-4D67-B40B-9DEFF042CB01}.Release|Any CPU.ActiveCfg = Release|Any CPU + {711B2905-FDC7-4D67-B40B-9DEFF042CB01}.Release|Any CPU.Build.0 = Release|Any CPU + {B233AB55-788C-48B6-9557-098B8D0DDBFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B233AB55-788C-48B6-9557-098B8D0DDBFF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B233AB55-788C-48B6-9557-098B8D0DDBFF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B233AB55-788C-48B6-9557-098B8D0DDBFF}.Release|Any CPU.Build.0 = Release|Any CPU + {ECF14067-8633-4DDA-8EAE-124989F8E09E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ECF14067-8633-4DDA-8EAE-124989F8E09E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ECF14067-8633-4DDA-8EAE-124989F8E09E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ECF14067-8633-4DDA-8EAE-124989F8E09E}.Release|Any CPU.Build.0 = Release|Any CPU + {D835A0A8-C213-461F-8B41-6F2715DBEC43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D835A0A8-C213-461F-8B41-6F2715DBEC43}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D835A0A8-C213-461F-8B41-6F2715DBEC43}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D835A0A8-C213-461F-8B41-6F2715DBEC43}.Release|Any CPU.Build.0 = Release|Any CPU + {F2C0D619-8CAF-4F81-B681-3F75AF79661F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F2C0D619-8CAF-4F81-B681-3F75AF79661F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F2C0D619-8CAF-4F81-B681-3F75AF79661F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F2C0D619-8CAF-4F81-B681-3F75AF79661F}.Release|Any CPU.Build.0 = Release|Any CPU + {57AF678A-3671-4B9E-9608-053E2197D0A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {57AF678A-3671-4B9E-9608-053E2197D0A4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {57AF678A-3671-4B9E-9608-053E2197D0A4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {57AF678A-3671-4B9E-9608-053E2197D0A4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -190,6 +232,13 @@ Global {A2853038-B04A-4BAA-B0B4-0481457003B8} = {A447D0CB-601B-479E-A2B2-76E48F5D4D61} {A77E804D-4576-4962-A248-92E538ED997C} = {A447D0CB-601B-479E-A2B2-76E48F5D4D61} {DBAB1C82-A3A0-4ADC-95BC-B87557C61C42} = {9BF048D0-411D-4C2A-8C32-3A3255501D27} + {6BB43905-3DBD-47E4-A38F-2BE319300B15} = {9BF048D0-411D-4C2A-8C32-3A3255501D27} + {711B2905-FDC7-4D67-B40B-9DEFF042CB01} = {A447D0CB-601B-479E-A2B2-76E48F5D4D61} + {B233AB55-788C-48B6-9557-098B8D0DDBFF} = {A447D0CB-601B-479E-A2B2-76E48F5D4D61} + {ECF14067-8633-4DDA-8EAE-124989F8E09E} = {A447D0CB-601B-479E-A2B2-76E48F5D4D61} + {D835A0A8-C213-461F-8B41-6F2715DBEC43} = {9BF048D0-411D-4C2A-8C32-3A3255501D27} + {F2C0D619-8CAF-4F81-B681-3F75AF79661F} = {9BF048D0-411D-4C2A-8C32-3A3255501D27} + {57AF678A-3671-4B9E-9608-053E2197D0A4} = {9BF048D0-411D-4C2A-8C32-3A3255501D27} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7D279EE5-E38F-4125-AE82-6ADE52D72F26} diff --git a/src/libraries/Microsoft.Extensions.Diagnostics/src/Metrics/MetricsServiceExtensions.cs b/src/libraries/Microsoft.Extensions.Diagnostics/src/Metrics/MetricsServiceExtensions.cs index 79a08c7..47fa1e0 100644 --- a/src/libraries/Microsoft.Extensions.Diagnostics/src/Metrics/MetricsServiceExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Diagnostics/src/Metrics/MetricsServiceExtensions.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Diagnostics.Metrics; using Microsoft.Extensions.Diagnostics.Metrics.Configuration; +using Microsoft.Extensions.Options; using System; using System.Diagnostics.Metrics; @@ -32,7 +33,9 @@ namespace Microsoft.Extensions.DependencyInjection services.TryAddSingleton(); // Make sure the subscription manager is started when the host starts. // The host will trigger options validation. - services.AddOptions().Configure((_, manager) => manager.Initialize()).ValidateOnStart(); + services.AddOptions().ValidateOnStart(); + // Make sure this is only registered/run once. + services.TryAddSingleton, SubscriptionActivator>(); services.TryAddSingleton(); @@ -66,5 +69,10 @@ namespace Microsoft.Extensions.DependencyInjection } private sealed class NoOpOptions { } + + private sealed class SubscriptionActivator(MetricsSubscriptionManager manager) : IConfigureOptions + { + public void Configure(NoOpOptions options) => manager.Initialize(); + } } } diff --git a/src/libraries/Microsoft.Extensions.Diagnostics/tests/MetricsSubscriptionManagerTests.cs b/src/libraries/Microsoft.Extensions.Diagnostics/tests/MetricsSubscriptionManagerTests.cs new file mode 100644 index 0000000..60049f6 --- /dev/null +++ b/src/libraries/Microsoft.Extensions.Diagnostics/tests/MetricsSubscriptionManagerTests.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics.Metrics; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.Metrics; +using Microsoft.Extensions.Options; +using Xunit; + +namespace Microsoft.Extensions.Diagnostics.Tests +{ + public class MetricsSubscriptionManagerTests + { + [Fact] + public void AddMetrics_InitializesListeners() + { + var serviceCollection = new ServiceCollection(); + serviceCollection.AddMetrics(); // Duplicate call, should not add things twice. + serviceCollection.AddMetrics(l => l.AddListener()); + var serviceProvider = serviceCollection.BuildServiceProvider(); + + // Make sure the subscription manager is started. + serviceProvider.GetRequiredService().Validate(); + + var listeners = serviceProvider.GetRequiredService>(); + + var listener = Assert.Single(listeners); + var fakeListener = Assert.IsType(listener); + Assert.Equal(1, fakeListener.InitializeCount); + } + + private class FakeListener : IMetricsListener + { + public string Name => "Fake"; + public int InitializeCount { get; private set; } + public MeasurementHandlers GetMeasurementHandlers() => new MeasurementHandlers(); + public void Initialize(IObservableInstrumentsSource source) => InitializeCount++; + public bool InstrumentPublished(Instrument instrument, out object? userState) => throw new NotImplementedException(); + public void MeasurementsCompleted(Instrument instrument, object? userState) => throw new NotImplementedException(); + } + } +} -- 2.7.4