Skip to content

Commit

Permalink
NLogProviderOptions - Added ReplaceLoggerFactory and RemoveLoggerFact…
Browse files Browse the repository at this point in the history
…oryFilter (#482)
  • Loading branch information
snakefoot authored Mar 1, 2021
1 parent 97adf10 commit b6955c5
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ public static IHostBuilder UseNLog(this IHostBuilder builder, NLogProviderOption
private static void AddNLogLoggerProvider(IServiceCollection services, IConfiguration configuration, NLogProviderOptions options, Func<IServiceProvider, IConfiguration, NLogProviderOptions, NLogLoggerProvider> factory)
{
ConfigurationItemFactory.Default.RegisterItemsFromAssembly(typeof(ConfigureExtensions).GetTypeInfo().Assembly);
services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, NLogLoggerProvider>(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)
Expand Down
6 changes: 5 additions & 1 deletion src/NLog.Extensions.Hosting/NLog.Extensions.Hosting.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,17 @@ Full changelog: https://github.com/NLog/NLog.Extensions.Logging/blob/master/CHAN
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" />
</ItemGroup>

<ItemGroup>
<Compile Include="..\NLog.Extensions.Logging\Internal\RegisterNLogLoggingProvider.cs" Link="Internal\RegisterNLogLoggingProvider.cs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<ProjectReference Include="..\NLog.Extensions.Logging\NLog.Extensions.Logging.csproj" />
</ItemGroup>

<ItemGroup>
<None Include="N.png" Pack="true" PackagePath="" />
<None Include="N.png" Pack="true" PackagePath="" Visible="false" />
</ItemGroup>
<Target Name="DownloadMissingContent" BeforeTargets="GenerateNuspec">
<DownloadFile SourceUrl="https://nlog-project.org/N.png" DestinationFolder="$(MSBuildThisFileDirectory)" />
Expand Down
16 changes: 8 additions & 8 deletions src/NLog.Extensions.Logging/Extensions/ConfigureExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder factory)
/// <returns>ILoggingBuilder for chaining</returns>
public static ILoggingBuilder AddNLog(this ILoggingBuilder factory, IConfiguration configuration)
{
AddNLogLoggerProvider(factory.Services, configuration, null, CreateNLogLoggerProvider);
AddNLogLoggerProvider(factory, configuration, null, CreateNLogLoggerProvider);
return factory;
}

Expand All @@ -93,7 +93,7 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder factory, IConfigurati
/// <returns>ILoggingBuilder for chaining</returns>
public static ILoggingBuilder AddNLog(this ILoggingBuilder factory, IConfiguration configuration, NLogProviderOptions options)
{
AddNLogLoggerProvider(factory.Services, configuration, options, CreateNLogLoggerProvider);
AddNLogLoggerProvider(factory, configuration, options, CreateNLogLoggerProvider);
return factory;
}

Expand All @@ -105,7 +105,7 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder factory, IConfigurati
/// <returns>ILoggingBuilder for chaining</returns>
public static ILoggingBuilder AddNLog(this ILoggingBuilder factory, NLogProviderOptions options)
{
AddNLogLoggerProvider(factory.Services, null, options, CreateNLogLoggerProvider);
AddNLogLoggerProvider(factory, null, options, CreateNLogLoggerProvider);
return factory;
}

Expand All @@ -129,7 +129,7 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, LoggingConfi
/// <returns>ILoggingBuilder for chaining</returns>
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);
Expand All @@ -148,7 +148,7 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, LoggingConfi
/// <returns>ILoggingBuilder for chaining</returns>
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
Expand All @@ -166,7 +166,7 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, string confi
/// <returns>ILoggingBuilder for chaining</returns>
public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, Func<IServiceProvider, LogFactory> 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
Expand All @@ -177,9 +177,9 @@ public static ILoggingBuilder AddNLog(this ILoggingBuilder builder, Func<IServic
return builder;
}

private static void AddNLogLoggerProvider(IServiceCollection services, IConfiguration configuration, NLogProviderOptions options, Func<IServiceProvider, IConfiguration, NLogProviderOptions, NLogLoggerProvider> factory)
private static void AddNLogLoggerProvider(ILoggingBuilder builder, IConfiguration configuration, NLogProviderOptions options, Func<IServiceProvider, IConfiguration, NLogProviderOptions, NLogLoggerProvider> factory)
{
services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, NLogLoggerProvider>(serviceProvider => factory(serviceProvider, configuration, options)));
builder.Services.TryAddNLogLoggingProvider((svc, addlogging) => addlogging(builder), configuration, options ?? NLogProviderOptions.Default, factory);
}
#endif

Expand Down
Original file line number Diff line number Diff line change
@@ -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<IServiceCollection, Action<ILoggingBuilder>> addLogging, IConfiguration configuration, NLogProviderOptions options, Func<IServiceProvider, IConfiguration, NLogProviderOptions, NLogLoggerProvider> 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<ILoggerFactory, NLogLoggerFactory>(serviceProvider => new NLogLoggerFactory(sharedFactory(serviceProvider, configuration, options))));
}

services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, NLogLoggerProvider>(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<NLogLoggerProvider>(null, Microsoft.Extensions.Logging.LogLevel.Trace));
}
}
}
#endif
}
6 changes: 1 addition & 5 deletions src/NLog.Extensions.Logging/Logging/NLogLoggerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ protected virtual void Dispose(bool disposing)
}
}

#region Implementation of ILoggerFactory

/// <summary>
/// Creates a new <see cref="T:Microsoft.Extensions.Logging.ILogger" /> instance.
/// </summary>
Expand All @@ -86,9 +84,7 @@ public Microsoft.Extensions.Logging.ILogger CreateLogger(string categoryName)
/// <param name="provider">The <see cref="T:Microsoft.Extensions.Logging.ILoggerProvider" />.</param>
public void AddProvider(ILoggerProvider provider)
{
InternalLogger.Debug("AddProvider will be ignored");
InternalLogger.Debug("NLogLoggerFactory: AddProvider has been ignored {0}", provider?.GetType());
}

#endregion
}
}
12 changes: 12 additions & 0 deletions src/NLog.Extensions.Logging/Logging/NLogProviderOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ public class NLogProviderOptions
#endif
public bool IncludeActivtyIdsWithBeginScope { get; set; }

/// <summary>
/// Resets the default Microsoft LoggerFactory Filter for the <see cref="NLogLoggerProvider"/>
/// </summary>
/// <remarks>This option affects the building of service configuration, so assigning it from appsettings.json has no effect (loaded after).</remarks>
public bool RemoveLoggerFactoryFilter { get; set; }

/// <summary>
/// Replace Microsoft LoggerFactory with a pure <see cref="NLogLoggerFactory" />
/// </summary>
/// <remarks>This option affects the building of service configuration, so assigning it from appsettings.json has no effect (loaded after).</remarks>
public bool ReplaceLoggerFactory { get; set; }

/// <summary>Initializes a new instance NLogProviderOptions with default values.</summary>
public NLogProviderOptions()
{
Expand Down
2 changes: 1 addition & 1 deletion src/NLog.Extensions.Logging/NLog.Extensions.Logging.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ Full changelog: https://github.com/NLog/NLog.Extensions.Logging/blob/master/CHAN
</ItemGroup>

<ItemGroup>
<None Include="N.png" Pack="true" PackagePath=""/>
<None Include="N.png" Pack="true" PackagePath="" Visible="false" />
</ItemGroup>
<Target Name="DownloadMissingContent" BeforeTargets="GenerateNuspec">
<DownloadFile SourceUrl="https://nlog-project.org/N.png" DestinationFolder="$(MSBuildThisFileDirectory)" />
Expand Down
10 changes: 10 additions & 0 deletions test/NLog.Extensions.Hosting.Tests/ExtensionMethodTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ILoggerFactory>();

Assert.Equal(typeof(NLogLoggerFactory), loggerFactory.GetType());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<ILoggerFactory>();
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;
Expand Down

0 comments on commit b6955c5

Please sign in to comment.