如何为.NET 5控制台应用正确集成NLog?日志无生成及相关配置问题排查
Let's break down why your logs aren't appearing and fix the issues step by step:
Your Current Setup Recap
You've configured NLog programmatically, set up a file target, and injected ILogger<TestService> into your service. The app runs without errors, but no log files are created—even though your TestService.Run() method executes correctly.
Core Issue: Mismatched Log Level Rules
The biggest problem here is that your NLog configuration only includes rules for Warn, Error, and Fatal levels, but your code is calling Logger.LogInformation()—which falls outside those rules. NLog will ignore any log messages that don't match an active rule.
Additional Optimizations & Fixes
Let's adjust your code to fix this and clean up some redundant logic:
1. Fix Log Level Rules
Update your NLog rules to include the Information level (or all levels if you want full visibility):
// Replace your three AddRuleForOneLevel lines with this // This covers Info, Warn, Error, Fatal config.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, fileTarget); // OR if you want to explicitly list each level: // config.AddRuleForOneLevel(NLog.LogLevel.Info, fileTarget); // config.AddRuleForOneLevel(NLog.LogLevel.Warn, fileTarget); // config.AddRuleForOneLevel(NLog.LogLevel.Error, fileTarget); // config.AddRuleForOneLevel(NLog.LogLevel.Fatal, fileTarget);
2. Simplify Environment-Based Target Configuration
Instead of creating a new FileTarget when in Development, just update the existing target's FileName property. This keeps your code cleaner and avoids redundant object creation:
var fileTarget = new FileTarget("fileTarget") { FileName = @"c:\AppLogs\TestApp\mylog-${shortdate}.log", Layout = "${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}", CreateDirs = true // Add this to auto-create log directories if they don't exist }; if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") { fileTarget.FileName = @"c:\AppLogs\TestApp_UAT\mylog-${shortdate}.log"; }
The CreateDirs = true property ensures NLog creates the log directory if it doesn't exist—this is a common pitfall that can silently prevent log files from being written.
3. Clarify Host Build Behavior
You mentioned expecting a BuildServiceProvider() method—rest assured, Host.CreateDefaultBuilder().Build() already constructs the service provider under the hood. You can simplify how you retrieve your TestService too:
// Replace ActivatorUtilities with this more direct approach var svc = host.Services.GetRequiredService<TestService>();
Full Modified Main Method
Here's the complete, fixed version of your Main method:
static void Main(string[] args) { Console.WriteLine("Hello World!"); var config = new LoggingConfiguration(); var fileTarget = new FileTarget("fileTarget") { FileName = @"c:\AppLogs\TestApp\mylog-${shortdate}.log", Layout = "${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}", CreateDirs = true }; if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") { fileTarget.FileName = @"c:\AppLogs\TestApp_UAT\mylog-${shortdate}.log"; } config.AddTarget(fileTarget); config.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, fileTarget); LogManager.Configuration = config; var host = Host.CreateDefaultBuilder() .ConfigureServices((context, services) => { services.AddTransient<TestService>(); }) .ConfigureLogging(logging => { logging.ClearProviders(); logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); logging.AddNLog(); }) .Build(); var svc = host.Services.GetRequiredService<TestService>(); svc.Run(); }
After making these changes, your Logger.LogInformation() call should generate a log file in the correct directory, matching your environment.
内容的提问来源于stack exchange,提问作者user3280560

