NLog报“Failed to create file”但指定路径日志文件已正常创建的问题
NLog 警告“访问C:\nlog-all-xxx.log被拒绝”的原因及解决方法
问题原因
警告出现的核心原因是NLog加载配置的时机早于GlobalDiagnosticsContext(GDC)变量的设置:
- 代码中先执行了
NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();,此时NLog已经加载配置并尝试初始化allfile这个FileTarget,但GlobalDiagnosticsContext.Set("logfilesPath", "C:\Govmeeting\LOGS");还未执行,${gdc:item=logfilesPath}会返回空字符串。 - 空字符串与后续路径拼接后,最终解析出的路径变为
C:\nlog-all-2023-05-26.log(Windows环境下,空路径前缀会默认指向程序当前工作目录的根驱动器),而程序没有C盘根目录的写入权限,因此抛出UnauthorizedAccessException。 - 后续执行
builder.Host.UseNLog()时,NLog会重新加载配置,此时GDC变量已设置完成,能正确解析到指定路径C:\Govmeeting\LOGS\nlog-all-2023-05-26.log,所以可以正常创建和写入日志。
解决方法
有两种可行的修复方式:
1. 调整代码执行顺序
将GDC变量的设置放在NLog配置加载之前,确保解析路径时变量已存在:
// 先设置GDC日志路径变量 GlobalDiagnosticsContext.Set("logfilesPath", @"C:\Govmeeting\LOGS"); // 再加载NLog配置并初始化Logger NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); var builder = WebApplication.CreateBuilder(args); builder.Logging.ClearProviders(); builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); builder.Host.UseNLog();
2. 给GDC变量设置默认值
在nlog.config中为${gdc:item=logfilesPath}添加默认值,避免变量未初始化时出现空路径:
<target xsi:type="File" name="allfile" fileName="${gdc:item=logfilesPath:default=C:\Govmeeting\LOGS}/nlog-all-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId.Id}|${logger}|${uppercase:${level}}|${message} ${exception}" archiveEvery="Day" archiveFileName="${gdc:item=logfilesPath:default=C:\Govmeeting\LOGS}/nlog-${shortdate}.log" /> <logger name="*" minlevel="Trace" writeTo="allfile" />
内容的提问来源于stack exchange,提问作者John Pankowicz
相关产品推荐
相关产品推荐

