.NET Core 7中如何在运行时通过NLog获取目标文件完整路径?
.NET 7中动态获取NLog目标文件路径的问题
我有一个在.NET Core 6中运行正常的控制台应用,当前正在将其迁移至刚发布的.NET Core 7,其他功能均正常,但动态获取NLog目标文件路径的部分出现问题。
NLog.config配置内容
<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogLevel="Warn" internalLogFile="internal-CimplDataLoader.log"> <extensions> <add assembly="NLog.Extensions.Logging" /> </extensions> <targets> <target xsi:type="File" name="allfile" fileName="${shortdate}.log" layout="${longdate}|${event-properties:item=EventId.Id}|${logger}|${uppercase:${level}}|${message} ${exception}" keepFileOpen="false"/> </targets> <rules> <!--All logs, including from Microsoft--> <logger name="*" minlevel="Trace" writeTo="allfile" /> </rules> </nlog>
.NET Core 6中可用的代码
if (LogManager.Configuration != null) { Target target = LogManager.Configuration.FindTargetByName("allfile"); var logEventInfo = new LogEventInfo { TimeStamp = DateTime.Now }; FileTarget? fileTarget; // Unwrap the target if necessary. if (target is not WrapperTargetBase wrapperTarget) fileTarget = target as FileTarget; else fileTarget = wrapperTarget.WrappedTarget as FileTarget; if (fileTarget != null) { string fileName = fileTarget.FileName.Render(logEventInfo); string LogPath = Path.GetDirectoryName(fileName)!; /* Work with LogPath */ } else { _logger.LogError("Unable to get NLog \"allfile\" base directory."); } } else { _logger.LogError("Unable to read NLog configuration."); }
这段代码在.NET Core 7中失效,因为LogManager.Configuration始终为null。请问是否有办法在.NET Core 7中仍能动态获取该路径?
解决方案
1. 通过依赖注入容器获取NLog配置
在.NET 7中,若使用依赖注入方式配置NLog,LogManager.Configuration不会自动初始化,需从DI容器中提取配置:
using NLog; using NLog.Extensions.Logging; using Microsoft.Extensions.Logging; using System.IO; // 从已构建的ServiceProvider中获取ILoggerFactory var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>(); var nLogFactory = loggerFactory as NLogLoggerFactory; if (nLogFactory != null) { var config = nLogFactory.Configuration; Target target = config.FindTargetByName("allfile"); var logEventInfo = new LogEventInfo { TimeStamp = DateTime.Now }; FileTarget? fileTarget; if (target is not WrapperTargetBase wrapperTarget) fileTarget = target as FileTarget; else fileTarget = wrapperTarget.WrappedTarget as FileTarget; if (fileTarget != null) { string fileName = fileTarget.FileName.Render(logEventInfo); string logPath = Path.GetDirectoryName(fileName)!; // 处理日志路径逻辑 } else { _logger.LogError("无法获取NLog \"allfile\"目标的基础目录。"); } }
2. 手动加载NLog配置文件
若未使用依赖注入,可手动加载配置文件初始化LogManager.Configuration:
using NLog; using NLog.Config; using System.IO; var config = new XmlLoggingConfiguration("NLog.config"); LogManager.Configuration = config; // 后续可复用原.NET 6中的代码逻辑 if (LogManager.Configuration != null) { // ... 原代码逻辑 }
3. 确认NLog在.NET 7中的初始化配置
检查Program.cs中的NLog初始化代码,确保配置正确:
var builder = WebApplication.CreateBuilder(args); // 清除默认日志提供器,添加NLog builder.Logging.ClearProviders(); builder.Logging.SetMinimumLevel(LogLevel.Trace); builder.Services.AddNLog(); var app = builder.Build(); // ... 应用其他逻辑
内容的提问来源于stack exchange,提问作者pdube
相关产品推荐
相关产品推荐

