如何正确地将 NLog 添加到 .NET 5 控制台应用程序?
How do I correctly add NLog to a .NET 5 Console App?
我正在尝试将 NLog 添加到 .NET 5 控制台应用程序。
我知道我不想对其中一些设置进行硬编码,并且 link 很快就会有一个应用程序设置文件,但我只想先记录所有内容,最低限度。
到目前为止我有:
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}"
};
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
{
fileTarget = new FileTarget("fileTarget")
{
FileName = @"c:\AppLogs\TestApp_UAT\mylog-${shortdate}.log",
Layout = "${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}"
};
}
config.AddTarget(fileTarget);
// rules
config.AddRuleForOneLevel(NLog.LogLevel.Warn, fileTarget);
config.AddRuleForOneLevel(NLog.LogLevel.Error, fileTarget);
config.AddRuleForOneLevel(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 = ActivatorUtilities.CreateInstance<TestService>(host.Services);
svc.Run();
}
然后我尝试在 TestService 中记录一些东西:
public class TestService
{
public TestService(ILogger<TestService> logger)
{
Logger = logger;
}
public ILogger<TestService> Logger { get; }
public void Run()
{
Console.WriteLine("my first log");
Logger.LogInformation("my first log");
}
}
我没有收到任何错误,但也没有创建任何日志(文件或内容)。控制台输出,所以 TestServices 正确运行。
根据文档,我希望看到一个名为“BuildServiceProvider()”的方法链接在“ConfigureLogging()”之后,但我只有“Build()”。这与它有关吗,还是我错过了什么?
您正在执行 LogInformation
,但您仅使用 AddRuleForOneLevel
启用了 Warn
+ Error
+ Fatal
。也许用 AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, fileTarget)
代替?
您也可以尝试指定 RemoveLoggerFactoryFilter
(以避免 Microsoft ILogger 过滤问题):
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddNLog(new NLogProviderOptions { RemoveLoggerFactoryFilter = true );
})
这是我完整封装的 NLog(针对 Console/CommandLine/DotNetCore)应用程序。
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Extensions.Logging;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
namespace Me.Configuration.DependencyInjection
{
[ExcludeFromCodeCoverage]
public static class NlogSharedConfiguration
{
public const string NlogPerEnvironmentNameTemplate = "nlog.{0}.config";
public const string NlogDefaultFileName = "nlog.config";
public static IServiceCollection ConfigureSharedNlog(
this IServiceCollection services,
IConfiguration configuration,
IHostEnvironment hostEnvironmentProxy)
{
NLogProviderOptions nlpopts = new NLogProviderOptions
{
IgnoreEmptyEventId = true,
CaptureMessageTemplates = true,
CaptureMessageProperties = true,
ParseMessageTemplates = true,
IncludeScopes = true,
ShutdownOnDispose = true
};
/* Note, appsettings.json (or appsettings.ENVIRONMENT.json) control what gets sent to NLog. So the .json files must have the same (or more) detailed LogLevel set (compared to the Nlog setting)
* See */
services.AddLogging(
builder =>
{
builder.AddConsole().SetMinimumLevel(LogLevel.Trace);
builder.SetMinimumLevel(LogLevel.Trace);
builder.AddNLog(nlpopts);
});
string nlogPerEnvironmentName = string.Format(
NlogPerEnvironmentNameTemplate,
hostEnvironmentProxy.EnvironmentName);
string nlogConfigName = File.Exists(nlogPerEnvironmentName) ? nlogPerEnvironmentName : NlogDefaultFileName;
Console.WriteLine(string.Format("Nlog Configuration File. (FileName='{0}')", nlogConfigName));
if (!File.Exists(nlogConfigName))
{
throw new ArgumentOutOfRangeException(
string.Format("Nlog Configuration File NOT FOUND. (FileName='{0}')", nlogConfigName));
}
LogManager.LoadConfiguration(nlogConfigName);
NLogLoggerProvider nlogProv = new NLogLoggerProvider(nlpopts);
ILoggerProvider castLoggerProvider = nlogProv as ILoggerProvider;
services.AddSingleton<ILoggerProvider>(castLoggerProvider);
return services;
}
}
}
我有(在我的 .exe 的根文件夹中)以下文件:
nlog.config
nlog.Development.config
NLog.xsd
nlog.Development.config 是可选的,但这就是我为本地开发人员设置的设置与其他设置略有不同的方式。
您可以在上面看到我的“如果文件存在”代码。
IHostEnvironment 来自这里:
我正在尝试将 NLog 添加到 .NET 5 控制台应用程序。
我知道我不想对其中一些设置进行硬编码,并且 link 很快就会有一个应用程序设置文件,但我只想先记录所有内容,最低限度。
到目前为止我有:
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}"
};
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
{
fileTarget = new FileTarget("fileTarget")
{
FileName = @"c:\AppLogs\TestApp_UAT\mylog-${shortdate}.log",
Layout = "${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}"
};
}
config.AddTarget(fileTarget);
// rules
config.AddRuleForOneLevel(NLog.LogLevel.Warn, fileTarget);
config.AddRuleForOneLevel(NLog.LogLevel.Error, fileTarget);
config.AddRuleForOneLevel(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 = ActivatorUtilities.CreateInstance<TestService>(host.Services);
svc.Run();
}
然后我尝试在 TestService 中记录一些东西:
public class TestService
{
public TestService(ILogger<TestService> logger)
{
Logger = logger;
}
public ILogger<TestService> Logger { get; }
public void Run()
{
Console.WriteLine("my first log");
Logger.LogInformation("my first log");
}
}
我没有收到任何错误,但也没有创建任何日志(文件或内容)。控制台输出,所以 TestServices 正确运行。
根据文档,我希望看到一个名为“BuildServiceProvider()”的方法链接在“ConfigureLogging()”之后,但我只有“Build()”。这与它有关吗,还是我错过了什么?
您正在执行 LogInformation
,但您仅使用 AddRuleForOneLevel
启用了 Warn
+ Error
+ Fatal
。也许用 AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, fileTarget)
代替?
您也可以尝试指定 RemoveLoggerFactoryFilter
(以避免 Microsoft ILogger 过滤问题):
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddNLog(new NLogProviderOptions { RemoveLoggerFactoryFilter = true );
})
这是我完整封装的 NLog(针对 Console/CommandLine/DotNetCore)应用程序。
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Extensions.Logging;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
namespace Me.Configuration.DependencyInjection
{
[ExcludeFromCodeCoverage]
public static class NlogSharedConfiguration
{
public const string NlogPerEnvironmentNameTemplate = "nlog.{0}.config";
public const string NlogDefaultFileName = "nlog.config";
public static IServiceCollection ConfigureSharedNlog(
this IServiceCollection services,
IConfiguration configuration,
IHostEnvironment hostEnvironmentProxy)
{
NLogProviderOptions nlpopts = new NLogProviderOptions
{
IgnoreEmptyEventId = true,
CaptureMessageTemplates = true,
CaptureMessageProperties = true,
ParseMessageTemplates = true,
IncludeScopes = true,
ShutdownOnDispose = true
};
/* Note, appsettings.json (or appsettings.ENVIRONMENT.json) control what gets sent to NLog. So the .json files must have the same (or more) detailed LogLevel set (compared to the Nlog setting)
* See */
services.AddLogging(
builder =>
{
builder.AddConsole().SetMinimumLevel(LogLevel.Trace);
builder.SetMinimumLevel(LogLevel.Trace);
builder.AddNLog(nlpopts);
});
string nlogPerEnvironmentName = string.Format(
NlogPerEnvironmentNameTemplate,
hostEnvironmentProxy.EnvironmentName);
string nlogConfigName = File.Exists(nlogPerEnvironmentName) ? nlogPerEnvironmentName : NlogDefaultFileName;
Console.WriteLine(string.Format("Nlog Configuration File. (FileName='{0}')", nlogConfigName));
if (!File.Exists(nlogConfigName))
{
throw new ArgumentOutOfRangeException(
string.Format("Nlog Configuration File NOT FOUND. (FileName='{0}')", nlogConfigName));
}
LogManager.LoadConfiguration(nlogConfigName);
NLogLoggerProvider nlogProv = new NLogLoggerProvider(nlpopts);
ILoggerProvider castLoggerProvider = nlogProv as ILoggerProvider;
services.AddSingleton<ILoggerProvider>(castLoggerProvider);
return services;
}
}
}
我有(在我的 .exe 的根文件夹中)以下文件:
nlog.config
nlog.Development.config
NLog.xsd
nlog.Development.config 是可选的,但这就是我为本地开发人员设置的设置与其他设置略有不同的方式。 您可以在上面看到我的“如果文件存在”代码。
IHostEnvironment 来自这里: