diff --git a/SumoLogic.Logging.AspNetCore.Tests/LoggerProviderTests.cs b/SumoLogic.Logging.AspNetCore.Tests/LoggerProviderTests.cs index d186634..ce65f07 100644 --- a/SumoLogic.Logging.AspNetCore.Tests/LoggerProviderTests.cs +++ b/SumoLogic.Logging.AspNetCore.Tests/LoggerProviderTests.cs @@ -23,10 +23,14 @@ * specific language governing permissions and limitations * under the License. */ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using SumoLogic.Logging.Common.Sender; using SumoLogic.Logging.Common.Tests; using System; +using System.Collections.Generic; using System.Threading; using Xunit; @@ -136,6 +140,38 @@ public void TestBatchingByWindow() }); } + [Fact] + public void TestConfigIsReadFromConfigProvider() + { + var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] + { + new KeyValuePair("SumoLogic:Uri", "http://www.fakeadress2.com"), + new KeyValuePair("SumoLogic:FlushingAccuracy", "00:00:00.123"), + }).Build(); + + var loggerProvider = new ServiceCollection() + .AddLogging(builder => builder.AddConfiguration(configuration).AddSumoLogic()) + .BuildServiceProvider() + .GetRequiredService(); + + var sumoLogicLoggerProvider = Assert.IsType(loggerProvider); + Assert.Equal("http://www.fakeadress2.com/", sumoLogicLoggerProvider.LoggerOptions.Uri); + Assert.Equal(123, sumoLogicLoggerProvider.LoggerOptions.FlushingAccuracy.Milliseconds); + } + + [Fact] + public void TestConfigUpdatesWithConfigProvider() + { + var monitor = new TestOptionsMonitor(new LoggerOptions() { Uri = "http://www.fakeadress2.com"}); + var loggerProvider = new LoggerProvider(monitor); + + Assert.Equal("http://www.fakeadress2.com/", loggerProvider.LoggerOptions.Uri); + + monitor.Set(new LoggerOptions() { Uri = "https://www.fakeadress2.com" }); + + Assert.Equal("https://www.fakeadress2.com/", loggerProvider.LoggerOptions.Uri); + } + /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// @@ -153,8 +189,8 @@ protected virtual void Dispose(bool disposing) { if (disposing) { - _provider.Dispose(); - _messagesHandler.Dispose(); + _provider?.Dispose(); + _messagesHandler?.Dispose(); } } @@ -196,5 +232,33 @@ private void SetupLogger(long messagesPerRequest, long maxFlushInterval, long fl _logger = _provider.CreateLogger("OverriddenCategory"); } + + // Taken from https://github.com/aspnet/Extensions/blob/2.2.0/src/Logging/test/ConsoleLoggerTest.cs#L1081 + public class TestOptionsMonitor : IOptionsMonitor + { + private LoggerOptions _options; + private event Action _onChange; + + public TestOptionsMonitor(LoggerOptions options) + { + _options = options; + } + + public LoggerOptions Get(string name) => _options; + + public IDisposable OnChange(Action listener) + { + _onChange += listener; + return null; + } + + public LoggerOptions CurrentValue => _options; + + public void Set(LoggerOptions options) + { + _options = options; + _onChange?.Invoke(options, ""); + } + } } } diff --git a/SumoLogic.Logging.AspNetCore.Tests/SumoLogic.Logging.AspNetCore.Tests.csproj b/SumoLogic.Logging.AspNetCore.Tests/SumoLogic.Logging.AspNetCore.Tests.csproj index 71efcb7..4b1c0ee 100644 --- a/SumoLogic.Logging.AspNetCore.Tests/SumoLogic.Logging.AspNetCore.Tests.csproj +++ b/SumoLogic.Logging.AspNetCore.Tests/SumoLogic.Logging.AspNetCore.Tests.csproj @@ -4,6 +4,7 @@ false + diff --git a/SumoLogic.Logging.AspNetCore/LoggerFactoryExtensions.cs b/SumoLogic.Logging.AspNetCore/LoggerFactoryExtensions.cs index b4de98e..9f887c7 100644 --- a/SumoLogic.Logging.AspNetCore/LoggerFactoryExtensions.cs +++ b/SumoLogic.Logging.AspNetCore/LoggerFactoryExtensions.cs @@ -23,8 +23,12 @@ * specific language governing permissions and limitations * under the License. */ -using Microsoft.Extensions.Logging; +using System; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Configuration; +using Microsoft.Extensions.Options; namespace SumoLogic.Logging.AspNetCore { @@ -55,7 +59,7 @@ public static ILoggerFactory AddSumoLogic(this ILoggerFactory factory) /// Adds a Sumo Logic logger named 'SumoLogic' to the factory. /// /// The factory. - /// Sets the uri of Sumo Logic ingesting endpoint/param> + /// Sets the uri of Sumo Logic ingesting endpoint public static ILoggerFactory AddSumoLogic(this ILoggerFactory factory, string uri) => factory.AddSumoLogic(new LoggerOptions() { Uri = uri }); @@ -76,13 +80,38 @@ public static ILoggingBuilder AddSumoLogic(this ILoggingBuilder builder, LoggerO /// /// The to use. public static ILoggingBuilder AddSumoLogic(this ILoggingBuilder builder) - => builder.AddSumoLogic(new LoggerOptions()); + { + builder.AddConfiguration(); + + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, LoggerOptionsSetup>()); + builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, LoggerProviderOptionsChangeTokenSource>()); + return builder; + } + + /// + /// Adds a Sumo Logic logger named 'SumoLogic' to the factory. + /// + /// The to use. + /// + public static ILoggingBuilder AddSumoLogic(this ILoggingBuilder builder, Action configure) + { + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + builder.AddSumoLogic(); + builder.Services.Configure(configure); + + return builder; + } /// /// Adds a Sumo Logic logger named 'SumoLogic' to the factory. /// /// The to use. - /// Sets the uri of Sumo Logic ingesting endpoint/param> + /// Sets the uri of Sumo Logic ingesting endpoint public static ILoggingBuilder AddSumoLogic(this ILoggingBuilder builder, string uri) => builder.AddSumoLogic(new LoggerOptions() { Uri = uri }); #endif diff --git a/SumoLogic.Logging.AspNetCore/LoggerOptionsSetup.cs b/SumoLogic.Logging.AspNetCore/LoggerOptionsSetup.cs new file mode 100644 index 0000000..7b1ab00 --- /dev/null +++ b/SumoLogic.Logging.AspNetCore/LoggerOptionsSetup.cs @@ -0,0 +1,12 @@ +using Microsoft.Extensions.Logging.Configuration; +using Microsoft.Extensions.Options; + +namespace SumoLogic.Logging.AspNetCore +{ + internal class LoggerOptionsSetup : ConfigureFromConfigurationOptions + { + public LoggerOptionsSetup(ILoggerProviderConfiguration providerConfiguration) : base(providerConfiguration.Configuration) + { + } + } +} diff --git a/SumoLogic.Logging.AspNetCore/LoggerProvider.cs b/SumoLogic.Logging.AspNetCore/LoggerProvider.cs index 2d45426..4d16191 100644 --- a/SumoLogic.Logging.AspNetCore/LoggerProvider.cs +++ b/SumoLogic.Logging.AspNetCore/LoggerProvider.cs @@ -51,8 +51,11 @@ public class LoggerProvider : ILoggerProvider private volatile BufferWithEviction messagesQueue = null; + private readonly IDisposable optionsReloadToken; + public LoggerProvider(IOptionsMonitor options) { + optionsReloadToken = options.OnChange(ReConfig); ReConfig(options.CurrentValue); } @@ -73,6 +76,8 @@ public void Dispose() flushBufferTask?.FlushAndSend().GetAwaiter().GetResult(); SumoLogicMessageSender?.Dispose(); + + optionsReloadToken?.Dispose(); } /// diff --git a/SumoLogic.Logging.AspNetCore/SumoLogic.Logging.AspNetCore.csproj b/SumoLogic.Logging.AspNetCore/SumoLogic.Logging.AspNetCore.csproj index d51f902..01f3d4a 100644 --- a/SumoLogic.Logging.AspNetCore/SumoLogic.Logging.AspNetCore.csproj +++ b/SumoLogic.Logging.AspNetCore/SumoLogic.Logging.AspNetCore.csproj @@ -26,5 +26,6 @@ +