From e8693a431df28553fe02b86795dd621e67616c80 Mon Sep 17 00:00:00 2001 From: Rolf Kristensen Date: Thu, 21 Nov 2024 21:26:55 +0100 Subject: [PATCH] UseNLog allow fallback to only EnvironmentName for NLog config (#1066) --- src/NLog.Web.AspNetCore/AspNetExtensions.cs | 72 ++++++++++++------- .../Config/SetupBuilderExtensions.cs | 62 ++++++++-------- .../AspNetCoreTests.cs | 26 +++++++ 3 files changed, 103 insertions(+), 57 deletions(-) diff --git a/src/NLog.Web.AspNetCore/AspNetExtensions.cs b/src/NLog.Web.AspNetCore/AspNetExtensions.cs index a4eb13d4..95e15cbf 100644 --- a/src/NLog.Web.AspNetCore/AspNetExtensions.cs +++ b/src/NLog.Web.AspNetCore/AspNetExtensions.cs @@ -387,15 +387,27 @@ private static NLogLoggerProvider CreateNLogLoggerProvider(IServiceProvider serv provider.LogFactory.ServiceRepository.RegisterService(typeof(IServiceProvider), serviceProvider); } - if (configuration != null) + if (configuration is null || !TryLoadConfigurationFromSection(provider, configuration)) { - TryLoadConfigurationFromSection(provider, configuration); - } + string nlogConfigFile = string.Empty; + string contentRootPath = hostEnvironment?.ContentRootPath; + string environmentName = hostEnvironment?.EnvironmentName; + if (!string.IsNullOrWhiteSpace(contentRootPath) || !string.IsNullOrWhiteSpace(environmentName)) + { + provider.LogFactory.Setup().LoadConfiguration(cfg => + { + if (!IsLoggingConfigurationLoaded(cfg.Configuration)) + { + nlogConfigFile = ResolveEnvironmentNLogConfigFile(contentRootPath, environmentName); + cfg.Configuration = null; + } + }); + } - var contentRootPath = hostEnvironment?.ContentRootPath; - if (!string.IsNullOrWhiteSpace(contentRootPath)) - { - TryLoadConfigurationFromContentRootPath(provider.LogFactory, contentRootPath, hostEnvironment.EnvironmentName); + if (!string.IsNullOrEmpty(nlogConfigFile)) + { + provider.LogFactory.Setup().LoadConfigurationFromFile(nlogConfigFile, optional: true); + } } if (provider.Options.ShutdownOnDispose || !provider.Options.AutoShutdown) @@ -406,28 +418,32 @@ private static NLogLoggerProvider CreateNLogLoggerProvider(IServiceProvider serv return provider; } - private static void TryLoadConfigurationFromContentRootPath(LogFactory logFactory, string contentRootPath, string environmentName) + private static string ResolveEnvironmentNLogConfigFile(string basePath, string environmentName) { - logFactory.Setup().LoadConfiguration(config => + if (!string.IsNullOrWhiteSpace(basePath)) { - if (IsLoggingConfigurationLoaded(config.Configuration)) - return; - - if (!string.IsNullOrEmpty(environmentName)) + if (!string.IsNullOrWhiteSpace(environmentName)) { - var nlogConfig = LoadXmlLoggingConfigurationFromPath(contentRootPath, $"NLog.{environmentName}.config", config.LogFactory) ?? - LoadXmlLoggingConfigurationFromPath(contentRootPath, $"nlog.{environmentName}.config", config.LogFactory) ?? - LoadXmlLoggingConfigurationFromPath(contentRootPath, "NLog.config", config.LogFactory) ?? - LoadXmlLoggingConfigurationFromPath(contentRootPath, "nlog.config", config.LogFactory); - config.Configuration = nlogConfig; + var nlogConfigEnvFilePath = System.IO.Path.Combine(basePath, $"nlog.{environmentName}.config"); + if (System.IO.File.Exists(nlogConfigEnvFilePath)) + return System.IO.Path.GetFullPath(nlogConfigEnvFilePath); + nlogConfigEnvFilePath = System.IO.Path.Combine(basePath, $"NLog.{environmentName}.config"); + if (System.IO.File.Exists(nlogConfigEnvFilePath)) + return System.IO.Path.GetFullPath(nlogConfigEnvFilePath); } - else - { - var nlogConfig = LoadXmlLoggingConfigurationFromPath(contentRootPath, "NLog.config", config.LogFactory) ?? - LoadXmlLoggingConfigurationFromPath(contentRootPath, "nlog.config", config.LogFactory); - config.Configuration = nlogConfig; - } - }); + + var nlogConfigFilePath = System.IO.Path.Combine(basePath, "nlog.config"); + if (System.IO.File.Exists(nlogConfigFilePath)) + return System.IO.Path.GetFullPath(nlogConfigFilePath); + nlogConfigFilePath = System.IO.Path.Combine(basePath, "NLog.config"); + if (System.IO.File.Exists(nlogConfigFilePath)) + return System.IO.Path.GetFullPath(nlogConfigFilePath); + } + + if (!string.IsNullOrWhiteSpace(environmentName)) + return $"nlog.{environmentName}.config"; + + return null; } private static LoggingConfiguration LoadXmlLoggingConfigurationFromPath(string contentRootPath, string nlogConfigFileName, LogFactory logFactory) @@ -451,10 +467,10 @@ private static IConfiguration SetupNLogConfigSettings(IServiceProvider servicePr return configuration; } - private static void TryLoadConfigurationFromSection(NLogLoggerProvider loggerProvider, IConfiguration configuration) + private static bool TryLoadConfigurationFromSection(NLogLoggerProvider loggerProvider, IConfiguration configuration) { if (string.IsNullOrEmpty(loggerProvider.Options.LoggingConfigurationSectionName)) - return; + return false; var nlogConfig = configuration.GetSection(loggerProvider.Options.LoggingConfigurationSectionName); if (nlogConfig?.GetChildren()?.Any() == true) @@ -466,10 +482,12 @@ private static void TryLoadConfigurationFromSection(NLogLoggerProvider loggerPro configBuilder.Configuration = new NLogLoggingConfiguration(nlogConfig, loggerProvider.LogFactory); } }); + return true; } else { Common.InternalLogger.Debug("Skip loading NLogLoggingConfiguration from empty config section: {0}", loggerProvider.Options.LoggingConfigurationSectionName); + return false; } } } diff --git a/src/NLog.Web.AspNetCore/Config/SetupBuilderExtensions.cs b/src/NLog.Web.AspNetCore/Config/SetupBuilderExtensions.cs index 4b3b94a9..44157b2b 100644 --- a/src/NLog.Web.AspNetCore/Config/SetupBuilderExtensions.cs +++ b/src/NLog.Web.AspNetCore/Config/SetupBuilderExtensions.cs @@ -45,37 +45,44 @@ public static ISetupBuilder LoadConfigurationFromAppSettings(this ISetupBuilder // "NLog"-section in appsettings.json has first priority return setupBuilder.SetupExtensions(e => e.RegisterNLogWeb().RegisterConfigSettings(config)).LoadConfigurationFromSection(config, nlogConfigSection); } - else + + setupBuilder.SetupExtensions(e => e.RegisterNLogWeb().RegisterConfigSettings(config)); + + var nlogConfigFile = ResolveEnvironmentNLogConfigFile(basePath, environment); + if (!string.IsNullOrEmpty(nlogConfigFile)) { - setupBuilder.SetupExtensions(e => e.RegisterNLogWeb().RegisterConfigSettings(config)); + return setupBuilder.LoadConfigurationFromFile(nlogConfigFile, optional: true); + } - if (!string.IsNullOrEmpty(basePath)) - { - if (!string.IsNullOrEmpty(environment)) - { - setupBuilder.LoadConfigurationFromFile(Path.Combine(basePath, $"nlog.{environment}.config"), optional: true); - setupBuilder.LoadConfiguration(config => - { - if (!IsLoggingConfigurationLoaded(config.Configuration)) - { - // Fallback when environment-specific NLog config could not load - var nlogConfigFilePath = Path.Combine(basePath, "nlog.config"); - config.Configuration = File.Exists(nlogConfigFilePath) ? new XmlLoggingConfiguration(nlogConfigFilePath, config.LogFactory) : null; - } - }); - } - else - { - setupBuilder.LoadConfigurationFromFile(Path.Combine(basePath, "nlog.config"), optional: true); - } - } - else if (!string.IsNullOrEmpty(environment)) + return setupBuilder.LoadConfigurationFromFile(); // No effect, if config already loaded + } + + private static string ResolveEnvironmentNLogConfigFile(string basePath, string environmentName) + { + if (!string.IsNullOrWhiteSpace(basePath)) + { + if (!string.IsNullOrWhiteSpace(environmentName)) { - setupBuilder.LoadConfigurationFromFile($"nlog.{environment}.config", optional: true); + var nlogConfigEnvFilePath = Path.Combine(basePath, $"nlog.{environmentName}.config"); + if (File.Exists(nlogConfigEnvFilePath)) + return Path.GetFullPath(nlogConfigEnvFilePath); + nlogConfigEnvFilePath = Path.Combine(basePath, $"NLog.{environmentName}.config"); + if (File.Exists(nlogConfigEnvFilePath)) + return Path.GetFullPath(nlogConfigEnvFilePath); } - return setupBuilder.LoadConfigurationFromFile(); // No effect, if config already loaded + var nlogConfigFilePath = Path.Combine(basePath, "nlog.config"); + if (File.Exists(nlogConfigFilePath)) + return Path.GetFullPath(nlogConfigFilePath); + nlogConfigFilePath = Path.Combine(basePath, "NLog.config"); + if (File.Exists(nlogConfigFilePath)) + return Path.GetFullPath(nlogConfigFilePath); } + + if (!string.IsNullOrWhiteSpace(environmentName)) + return $"nlog.{environmentName}.config"; + + return null; } private static string ResolveCurrentAppDirectory() @@ -92,11 +99,6 @@ private static string ResolveCurrentAppDirectory() return currentBasePath; } - private static bool IsLoggingConfigurationLoaded(LoggingConfiguration cfg) - { - return cfg?.LoggingRules?.Count > 0 && cfg?.AllTargets?.Count > 0; - } - private static string GetAspNetCoreEnvironment(string variableName) { try diff --git a/tests/NLog.Web.AspNetCore.Tests/AspNetCoreTests.cs b/tests/NLog.Web.AspNetCore.Tests/AspNetCoreTests.cs index 536dc630..3b61e762 100644 --- a/tests/NLog.Web.AspNetCore.Tests/AspNetCoreTests.cs +++ b/tests/NLog.Web.AspNetCore.Tests/AspNetCoreTests.cs @@ -14,6 +14,7 @@ using NLog.Layouts; using NLog.Targets; using ILoggerFactory = Microsoft.Extensions.Logging.ILoggerFactory; +using System.IO; namespace NLog.Web.Tests { @@ -252,6 +253,31 @@ public void LoadConfigurationFromAppSettingsShouldLogTest3() } } } + + [Fact] + public void LoadConfigurationFromAppSettingsUNC() + { + // Arrange + var tempPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), nameof(AspNetCoreTests), Guid.NewGuid().ToString()).Replace("\\", "/"); + var UNCtempPath = @"\\?\" + tempPath.Replace('/', '\\'); + Directory.CreateDirectory(tempPath); + + try + { + // Act + var logFactory = new LogFactory(); + + // Asssert + Assert.Throws(() => new Uri(UNCtempPath)); + + var logger = logFactory.Setup().LoadConfigurationFromAppSettings(basePath: UNCtempPath).GetCurrentClassLogger(); + logger.Info("Hello World"); + } + finally + { + Directory.Delete(tempPath); + } + } #endif private static LoggingConfiguration CreateConfigWithMemoryTarget(out MemoryTarget target, Layout layout)