.NET Core下NLog读取Azure Blob连接串及日志异常排查
1. UpdateNLogConfig 方法调用位置
你需要在加载NLog配置之前,先完成appsettings配置的加载和GDC值的写入,正确调用位置如下:
public class Program { public static void Main(string[] args) { // 第一步:先加载appsettings配置 var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true) .Build(); // 第二步:调用UpdateNLogConfig,将连接字符串存入GDC UpdateNLogConfig(config); // 第三步:再加载NLog配置,此时GDC已赋值可以正常读取 var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger(); try { logger.Debug("应用启动初始化"); CreateHostBuilder(args).Build().Run(); } catch (Exception exception) { logger.Error(exception, "程序因异常终止"); throw; } finally { NLog.LogManager.Shutdown(); } } // UpdateNLogConfig示例实现 private static void UpdateNLogConfig(IConfiguration config) { // 从appsettings读取Blob连接字符串,key替换为你实际的配置项 var blobConnStr = config.GetValue<string>("AzureBlobStorage:ConnectionString"); // 存入GDC,key要和nlog.config里引用的${gdc:item=BlobConnectionString}保持一致 NLog.GlobalDiagnosticsContext.Set("BlobConnectionString", blobConnStr); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }) .ConfigureLogging(logging => { logging.ClearProviders(); logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); }) .UseNLog(); }
同步修改nlog.config里Blob target的connectionString属性为${gdc:item=BlobConnectionString}即可。
2. 切换到appsettings配置NLog后LocalTarget不生效的问题
当前代码和配置存在4个明显错误,逐一修正即可:
- 错误1:Program.cs中构建了
nlogConfig但未传递给NLog,还是加载了默认空配置 - 错误2:JSON配置中路径使用了单斜杠
\,未做转义,导致解析后路径错误 - 错误3:NLog的extensions配置格式错误,应为数组而非对象
- 错误4:JSON结构错误,targets节点的闭合括号缺失
修正后的Program.cs代码
public class Program { public static void Main(string[] args) { var config = new ConfigurationBuilder() .SetBasePath(System.IO.Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true) .Build(); // 直接将构建好的NLog配置赋值给LogManager NLog.LogManager.Configuration = new NLogLoggingConfiguration(config.GetSection("NLog")); var logger = NLog.LogManager.GetCurrentClassLogger(); try { logger.Debug("Initialize main"); CreateHostBuilder(args).Build().Run(); } catch (Exception ex) { logger.Error(ex, "Stopped program because of exception."); } finally { NLog.LogManager.Shutdown(); } } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }) .ConfigureLogging(logging => { logging.ClearProviders(); logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); }) // 告诉NLog使用已加载的配置,不要重新加载 .UseNLog(config => { config.Configuration = NLog.LogManager.Configuration; config.LoadConfigurationFromSection = false; }); }
修正后的appsettings.json配置
"NLog": { "internalLogLevel": "Info", "internalLogFile": "c:\\temp\\NLog\\internal-nlog.txt", "extensions": [ { "assembly": "NLog.Web.AspNetCore" } ], "targets": { "LocalTarget": { "type": "File", "fileName": "c:\\temp\\NLog\\PayDocs_${shortdate}.log", "layout": "${longdate} | ${uppercase:${level}} | ${callsite} | ${message}" } }, "rules": [ { "logger": "Microsoft.*", "maxLevel": "Info", "final": "true" }, { "logger": "*", "minLevel": "Trace", "writeTo": "LocalTarget" } ] }
注:这里调整了规则顺序,优先过滤Microsoft前缀的日志,避免无效日志写入LocalTarget
内容的提问来源于stack exchange,提问作者Caverman
相关产品推荐
相关产品推荐

