diff --git a/src/NLog.Extensions.Hosting/Extensions/ConfigureExtensions.cs b/src/NLog.Extensions.Hosting/Extensions/ConfigureExtensions.cs index 91038e03..b5a5f0de 100644 --- a/src/NLog.Extensions.Hosting/Extensions/ConfigureExtensions.cs +++ b/src/NLog.Extensions.Hosting/Extensions/ConfigureExtensions.cs @@ -44,7 +44,8 @@ public static IHostBuilder UseNLog(this IHostBuilder builder, NLogProviderOption private static void AddNLogLoggerProvider(IServiceCollection services, IConfiguration configuration, NLogProviderOptions options, Func factory) { ConfigurationItemFactory.Default.RegisterItemsFromAssembly(typeof(ConfigureExtensions).GetTypeInfo().Assembly); - services.TryAddEnumerable(ServiceDescriptor.Singleton(serviceProvider => factory(serviceProvider, configuration, options))); + + services.TryAddNLogLoggingProvider((svc, addlogging) => svc.AddLogging(addlogging), configuration, options, factory); } private static NLogLoggerProvider CreateNLogLoggerProvider(IServiceProvider serviceProvider, IConfiguration configuration, NLogProviderOptions options) diff --git a/src/NLog.Extensions.Hosting/NLog.Extensions.Hosting.csproj b/src/NLog.Extensions.Hosting/NLog.Extensions.Hosting.csproj index 96c4c4a4..cc8ccfb6 100644 --- a/src/NLog.Extensions.Hosting/NLog.Extensions.Hosting.csproj +++ b/src/NLog.Extensions.Hosting/NLog.Extensions.Hosting.csproj @@ -48,13 +48,17 @@ Full changelog: https://github.com/NLog/NLog.Extensions.Logging/blob/master/CHAN + + + + - + diff --git a/src/NLog.Extensions.Logging/Extensions/ConfigureExtensions.cs b/src/NLog.Extensions.Logging/Extensions/ConfigureExtensions.cs index e66fe1c5..505fca36 100644 --- a/src/NLog.Extensions.Logging/Extensions/ConfigureExtensions.cs +++ b/src/NLog.Extensions.Logging/Extensions/ConfigureExtensions.cs @@ -80,7 +80,7 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder factory) /// ILoggingBuilder for chaining public static ILoggingBuilder AddNLog(this ILoggingBuilder factory, IConfiguration configuration) { - AddNLogLoggerProvider(factory.Services, configuration, null, CreateNLogLoggerProvider); + AddNLogLoggerProvider(factory, configuration, null, CreateNLogLoggerProvider); return factory; } @@ -93,7 +93,7 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder factory, IConfigurati /// ILoggingBuilder for chaining public static ILoggingBuilder AddNLog(this ILoggingBuilder factory, IConfiguration configuration, NLogProviderOptions options) { - AddNLogLoggerProvider(factory.Services, configuration, options, CreateNLogLoggerProvider); + AddNLogLoggerProvider(factory, configuration, options, CreateNLogLoggerProvider); return factory; } @@ -105,7 +105,7 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder factory, IConfigurati /// ILoggingBuilder for chaining public static ILoggingBuilder AddNLog(this ILoggingBuilder factory, NLogProviderOptions options) { - AddNLogLoggerProvider(factory.Services, null, options, CreateNLogLoggerProvider); + AddNLogLoggerProvider(factory, null, options, CreateNLogLoggerProvider); return factory; } @@ -129,7 +129,7 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, LoggingConfi /// ILoggingBuilder for chaining public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, LoggingConfiguration configuration, NLogProviderOptions options) { - AddNLogLoggerProvider(builder.Services, null, options, (serviceProvider, config, options) => + AddNLogLoggerProvider(builder, null, options, (serviceProvider, config, options) => { var logFactory = configuration?.LogFactory ?? LogManager.LogFactory; var provider = CreateNLogLoggerProvider(serviceProvider, config, options, logFactory); @@ -148,7 +148,7 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, LoggingConfi /// ILoggingBuilder for chaining public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, string configFileRelativePath) { - AddNLogLoggerProvider(builder.Services, null, null, (serviceProvider, config, options) => + AddNLogLoggerProvider(builder, null, null, (serviceProvider, config, options) => { var provider = CreateNLogLoggerProvider(serviceProvider, config, options); // Delay initialization of targets until we have loaded config-settings @@ -166,7 +166,7 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, string confi /// ILoggingBuilder for chaining public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, Func factoryBuilder) { - AddNLogLoggerProvider(builder.Services, null, null, (serviceProvider, config, options) => + AddNLogLoggerProvider(builder, null, null, (serviceProvider, config, options) => { config = SetupConfiguration(serviceProvider, config); // Delay initialization of targets until we have loaded config-settings @@ -177,9 +177,9 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, Func factory) + private static void AddNLogLoggerProvider(ILoggingBuilder builder, IConfiguration configuration, NLogProviderOptions options, Func factory) { - services.TryAddEnumerable(ServiceDescriptor.Singleton(serviceProvider => factory(serviceProvider, configuration, options))); + builder.Services.TryAddNLogLoggingProvider((svc, addlogging) => addlogging(builder), configuration, options ?? NLogProviderOptions.Default, factory); } #endif diff --git a/src/NLog.Extensions.Logging/Internal/RegisterNLogLoggingProvider.cs b/src/NLog.Extensions.Logging/Internal/RegisterNLogLoggingProvider.cs new file mode 100644 index 00000000..b076b63d --- /dev/null +++ b/src/NLog.Extensions.Logging/Internal/RegisterNLogLoggingProvider.cs @@ -0,0 +1,35 @@ +namespace NLog.Extensions.Logging +{ +#if !NETCORE1_0 + using System; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.DependencyInjection.Extensions; + using Microsoft.Extensions.Logging; + + internal static class RegisterNLogLoggingProvider + { + internal static void TryAddNLogLoggingProvider(this IServiceCollection services, Action> addLogging, IConfiguration configuration, NLogProviderOptions options, Func factory) + { + var sharedFactory = factory; + + if (options?.ReplaceLoggerFactory == true) + { + NLogLoggerProvider singleInstance = null; // Ensure that registration of ILoggerFactory and ILoggerProvider shares the same single instance + sharedFactory = (provider, cfg, opt) => singleInstance ?? (singleInstance = factory(provider, cfg, opt)); + + addLogging?.Invoke(services, (builder) => builder?.ClearProviders()); // Cleanup the existing LoggerFactory, before replacing it with NLogLoggerFactory + services.Replace(ServiceDescriptor.Singleton(serviceProvider => new NLogLoggerFactory(sharedFactory(serviceProvider, configuration, options)))); + } + + services.TryAddEnumerable(ServiceDescriptor.Singleton(serviceProvider => sharedFactory(serviceProvider, configuration, options))); + + if (options?.RemoveLoggerFactoryFilter == true) + { + // Will forward all messages to NLog if not specifically overridden by user + addLogging?.Invoke(services, (builder) => builder?.AddFilter(null, Microsoft.Extensions.Logging.LogLevel.Trace)); + } + } + } +#endif +} diff --git a/src/NLog.Extensions.Logging/Logging/NLogLoggerFactory.cs b/src/NLog.Extensions.Logging/Logging/NLogLoggerFactory.cs index dd529ed8..42a3afeb 100644 --- a/src/NLog.Extensions.Logging/Logging/NLogLoggerFactory.cs +++ b/src/NLog.Extensions.Logging/Logging/NLogLoggerFactory.cs @@ -60,8 +60,6 @@ protected virtual void Dispose(bool disposing) } } - #region Implementation of ILoggerFactory - /// /// Creates a new instance. /// @@ -86,9 +84,7 @@ public Microsoft.Extensions.Logging.ILogger CreateLogger(string categoryName) /// The . public void AddProvider(ILoggerProvider provider) { - InternalLogger.Debug("AddProvider will be ignored"); + InternalLogger.Debug("NLogLoggerFactory: AddProvider has been ignored {0}", provider?.GetType()); } - - #endregion } } \ No newline at end of file diff --git a/src/NLog.Extensions.Logging/Logging/NLogProviderOptions.cs b/src/NLog.Extensions.Logging/Logging/NLogProviderOptions.cs index c1185a17..cc37aeca 100644 --- a/src/NLog.Extensions.Logging/Logging/NLogProviderOptions.cs +++ b/src/NLog.Extensions.Logging/Logging/NLogProviderOptions.cs @@ -56,6 +56,18 @@ public class NLogProviderOptions #endif public bool IncludeActivtyIdsWithBeginScope { get; set; } + /// + /// Resets the default Microsoft LoggerFactory Filter for the + /// + /// This option affects the building of service configuration, so assigning it from appsettings.json has no effect (loaded after). + public bool RemoveLoggerFactoryFilter { get; set; } + + /// + /// Replace Microsoft LoggerFactory with a pure + /// + /// This option affects the building of service configuration, so assigning it from appsettings.json has no effect (loaded after). + public bool ReplaceLoggerFactory { get; set; } + /// Initializes a new instance NLogProviderOptions with default values. public NLogProviderOptions() { diff --git a/src/NLog.Extensions.Logging/NLog.Extensions.Logging.csproj b/src/NLog.Extensions.Logging/NLog.Extensions.Logging.csproj index e242e36b..3b562292 100644 --- a/src/NLog.Extensions.Logging/NLog.Extensions.Logging.csproj +++ b/src/NLog.Extensions.Logging/NLog.Extensions.Logging.csproj @@ -114,7 +114,7 @@ Full changelog: https://github.com/NLog/NLog.Extensions.Logging/blob/master/CHAN - + diff --git a/test/NLog.Extensions.Hosting.Tests/ExtensionMethodTests.cs b/test/NLog.Extensions.Hosting.Tests/ExtensionMethodTests.cs index b1f14c4c..16905b7b 100644 --- a/test/NLog.Extensions.Hosting.Tests/ExtensionMethodTests.cs +++ b/test/NLog.Extensions.Hosting.Tests/ExtensionMethodTests.cs @@ -82,5 +82,15 @@ private static void TestHostingResult(IHost host, bool resetConfiguration) LogManager.Configuration = null; } } + + [Fact] + public void UseNLog_ReplaceLoggerFactory() + { + var actual = new HostBuilder().ConfigureServices(svc => svc.AddLogging()).UseNLog(new NLogProviderOptions() { ReplaceLoggerFactory = true, RemoveLoggerFactoryFilter = true }).Build(); + + var loggerFactory = actual.Services.GetService(); + + Assert.Equal(typeof(NLogLoggerFactory), loggerFactory.GetType()); + } } } \ No newline at end of file diff --git a/test/NLog.Extensions.Logging.Tests/Extensions/ConfigureExtensionsTests.cs b/test/NLog.Extensions.Logging.Tests/Extensions/ConfigureExtensionsTests.cs index 8056fd0b..e12a6f17 100644 --- a/test/NLog.Extensions.Logging.Tests/Extensions/ConfigureExtensionsTests.cs +++ b/test/NLog.Extensions.Logging.Tests/Extensions/ConfigureExtensionsTests.cs @@ -133,6 +133,22 @@ public void AddNLog_LogFactoryBuilder_LogInfo_ShouldLogToNLog() AssertSingleMessage(memoryTarget, "Info|test message with 1 arg"); } + [Fact] + public void AddNLog_ReplaceLoggerFactory() + { + // Arrange + ILoggingBuilder builder = new LoggingBuilderStub(); + + // Act + builder.AddNLog(new NLogProviderOptions() { ReplaceLoggerFactory = true, RemoveLoggerFactoryFilter = true }); + var loggerFactory = builder.Services.BuildServiceProvider().GetService(); + var loggerProvider = GetLoggerProvider(builder); + + // Assert + Assert.Equal(typeof(NLogLoggerFactory), loggerFactory.GetType()); + Assert.Equal(typeof(NLogLoggerProvider), loggerProvider.GetType()); + } + private static ILoggerProvider GetLoggerProvider(ILoggingBuilder builder) { var services = builder.Services;