![](/img/trans.png)
[英]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.