[英]NLOG: Creating multiple instances of same class writing log to same file
[英]NLog multiple loggers in same class
我有一个 class 应该像往常一样记录,但有时它应该记录到特定目标(例如文件)。
这是我的 NLog 配置文件:
nlog.config
<?xml version="1.0" encoding="utf-8" ?>
<!-- XSD manual extracted from package NLog.Schema: https://www.nuget.org/packages/NLog.Schema-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogFile="C:\Logs\logfile.log"
internalLogLevel="Info" >
<targets>
<target xsi:type="File" name="logfile" fileName="C:\Logs\logfile.log"
layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
<target xsi:type="Console" name="logconsole"
layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile,logconsole" />
</rules>
</nlog>
和额外的.config
<?xml version="1.0" encoding="utf-8" ?>
<!-- XSD manual extracted from package NLog.Schema: https://www.nuget.org/packages/NLog.Schema-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogFile="C:\Logs\extra.log"
internalLogLevel="Info" >
<targets>
<target xsi:type="File" name="extra" fileName="C:\Logs\extra.log"
layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<logger name="*" minlevel="Trace" writeTo="extra" />
</rules>
</nlog>
我正在尝试这样的事情:
public class Program
{
private static IConfiguration _configuration;
public static void Main(string[] args)
{
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
try
{
logger.Debug("init main");
var environment = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Production";
_configuration = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json", false)
.AddJsonFile($"appsettings.{environment}.json", true)
.Build();
CreateHostBuilder(args).Build().Run();
}
catch (Exception exception)
{
//NLog: catch setup errors
logger.Error(exception, "Stopped program because of exception");
throw;
}
finally
{
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
NLog.LogManager.Shutdown();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host
.CreateDefaultBuilder(args)
.ConfigureLogging(logBuilder =>
{
logBuilder.ClearProviders();
logBuilder.SetMinimumLevel(LogLevel.Trace);
})
.ConfigureServices((hostContext, services) =>
{
//serviceConfig
})
.UseNLog()
.UseWindowsService();
}
class 我想要两个记录器:
public class MyClass
{
private readonly ILogger<MyClass> _logger;
private readonly Logger _extraLogger;
public MyClass(ILogger<MyClass> logger)
{
_logger = logger;
_extraLogger = NLogBuilder.ConfigureNLog("extra.config").GetLogger("extra");
}
public void doBothTypesOfLogging()
{
var msg = "Hello";
_extraLogger.Info(msg);
_logger.LogInformation("Message sendt");
}
}
但这使得应用程序(甚至其他类)完成的所有日志记录最终都在由 extra.config 定义的extra.log
文件中。 例如。 msg
和"Message sendt"
都以该文件结尾。
我想要的是拥有
logfile.log
中的"Message sendt"
msg
中的extra.log
这有可能吗?
为什么要在同一个 class 上创建两个日志? 如果您的 class 上有一个子组件,您想单独记录它,那么没关系,您只需要一个适当的配置文件......但是,通常,这将是一种代码味道。
你可以用一个配置做你想做的一切:
<?xml version="1.0" encoding="utf-8" ?>
<!-- XSD manual extracted from package NLog.Schema: https://www.nuget.org/packages/NLog.Schema-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogFile="C:\Logs\logfile.log"
internalLogLevel="Info" >
<targets>
<target xsi:type="File" name="logfile" fileName="C:\Logs\logfile.log"
layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
<target xsi:type="Console" name="logconsole"
layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
<target xsi:type="File" name="extra" fileName="C:\Logs\extra.log"
layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<logger name="extra" minlevel="Trace" writeTo="extra" final="true" />
<logger name="*" minlevel="Trace" writeTo="logfile,logconsole" />
</rules>
</nlog>
注意“extra”日志规则中的“final”属性。 它将防止将额外的日志写入其他日志。
无需使用不同的配置创建此记录器。 只需执行以下操作:
public class MyClass
{
private readonly ILogger<MyClass> _logger;
private readonly Logger _extraLogger = LogManager.GetLogger("extra");
public MyClass(ILogger<MyClass> logger)
{
_logger = logger;
}
public void doBothTypesOfLogging()
{
var msg = "Hello";
_extraLogger.Info(msg);
_logger.LogInformation("Message sendt");
}
}
但我认为你应该重新考虑是否真的需要两个记录器来处理同一个 class。
更新
根据您的需要,您可以通过使用开箱即用的 NLog 功能并遵循更加 nlogish 的模式来大大简化您的代码。 配置文件几乎相同,只是将“extra”记录器的规则更改为“syslog”,因为我们将在代码中更改它的名称:
<?xml version="1.0" encoding="utf-8" ?>
<!-- XSD manual extracted from package NLog.Schema: https://www.nuget.org/packages/NLog.Schema-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogFile="C:\Logs\logfile.log"
internalLogLevel="Info" >
<targets>
<target xsi:type="File" name="logfile" fileName="C:\Logs\logfile.log"
layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
<target xsi:type="Console" name="logconsole"
layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
<!-- This will probably be a network target -->
<target xsi:type="File" name="extra" fileName="C:\Logs\extra.log"
layout="${longdate}|${level}|${message} |${all-event-properties} ${exception:format=tostring}" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<logger name="syslog" minlevel="Trace" writeTo="extra" final="true" />
<logger name="*" minlevel="Trace" writeTo="logfile,logconsole" />
</rules>
</nlog>
我们将把“syslog”记录器放在一个帮助器 static class 中的 static 变量中:
public static class CommonLoggers
{
public static Logger SysLogger { get; private set; } = LogManager.GetLogger("syslog");
// you can put other centralized loggers here if you want
}
然后,您应该将 class 代码更改为:
public class MyClass
{
// the "correct" pattern is to use a logger that follows the class name
// put this in each class you create
private static Logger logger = LogManager.GetCurrentClassLogger();
// nothing to do on the constructor (can be removed as it's redundant)
public MyClass() { }
public void doBothTypesOfLogging() {
var msg = "Hello";
CommonLoggers.SysLogger.Info(msg);
logger.Info("Message sent");
}
}
重要的部分是要了解 NLog 规则用于过滤 output 给定记录器名称,您可以执行以下操作,例如:
<rules>
<logger name="SomeNamespace.Somewhere.*" minlevel="Trace" writeTo="extra" final="true"/>
<logger name="SomeNamespace.SomewhereElse.MyClass" minlevel="Info" writeTo="some_other_target" />
<logger name="*" minlevel="error" writeTo="logfile" />
<logger name="*" minlevel="info" writeTo="logconsole" />
</rules>
这样,您可以将“SomeNamespace.Somewhere.*”中所有类的所有日志跟踪到“额外”目标。 将“MyClass”的所有 INFO 日志写入“some_other_target”。 将 ERROR 消息发送到“logfile”,将 INFO 消息发送到“logconsole”。
阅读有关规则、目标和过滤器的文档将对您有很大帮助!
这是一篇好文章: https://www.codeproject.com/Articles/4051307/NLog-Rules-and-filters
官方文档: https://github.com/nlog/nlog/wiki/Configuration-file#rules
还有这个精彩的 SO 问题: 最有用的 NLog 配置
快乐阅读!
而不是直接使用 NLog LogManager,那么我建议你留在 ILogger-path 上,但像这样调用ILoggerFactory :
public class MyClass
{
private readonly ILogger _logger;
private readonly ILogger _extraLogger;
public MyClass(ILoggerFactory logfactory)
{
_logger = logfactory.CreateLogger(GetType().ToString());
_extraLogger = logfactory.CreateLogger("extra");
}
public void doBothTypesOfLogging()
{
var msg = "Hello";
_extraLogger.LogInformation(msg);
_logger.LogInformation("Message sendt");
}
}
但我同意接受的答案,即应该使用单个NLog.config
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.