【问题标题】:Is it possible to tell dynamically NLog which target to log to?是否可以动态告诉 NLog 记录到哪个目标?
【发布时间】:2015-05-08 22:14:28
【问题描述】:

我想在我的 WPF 应用程序中实现AppDomain.FirstChanceException,用于选择性地记录每个发生、处理或未处理的异常。我不希望将这些异常记录到我为 NLog 配置的目标中。是否有可能在调用Logger.Error(或任何Logger 方法)时使NLog 仅记录到一个特定目标?

【问题讨论】:

  • 可能我误解了你的问题,但是你需要在AppDomain.FirstChanceException处理程序中更改你的NLog目标吗?
  • 非常正确,@IlVic,我想要一个 Logger 方法调用,例如Error,在AppDomain.FirstChanceException 内,只记录到文件,不记录到数据库,也不记录到内存。

标签: wpf logging nlog unhandled-exception first-chance-exception


【解决方案1】:

这是可能的,但这不是一个好主意,因为:

  1. 它不是线程安全的。
  2. 将重新配置指定工厂的所有记录器。

配置文件:

<?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">
  <targets async="true">
    <target name="file1" xsi:type="File" fileName="${basedir}/log1.txt" />
    <target name="file2" xsi:type="File" fileName="${basedir}/log2.txt" />
  </targets>
  <rules>
    <logger name="*" minlevel="Trace" writeTo="file1,file2" />
  </rules>
</nlog>

全局工厂配置示例:

var logger = LogManager.GetCurrentClassLogger();

logger.Error("Original Configuration");

var configOrig = LogManager.Configuration;
var configTemp = LogManager.Configuration.Reload();
var rule = configTemp.LoggingRules.First(r => r.NameMatches("*"));
var target = configTemp.FindTargetByName("file2");

rule.Targets.Remove(target);

LogManager.Configuration = configTemp;
logger.Error("Temporary Configuration");

LogManager.Configuration = configOrig;
logger.Error("Original Configuration");

用户创建的工厂配置示例:

var factory = new LogFactory(LogManager.Configuration);
var logger = factory.GetCurrentClassLogger();

logger.Error("Original Configuration");

var config = factory.Configuration;
var rule = config.LoggingRules.First(r => r.NameMatches("*"));
var target = config.FindTargetByName("file2");

rule.Targets.Remove(target);
factory.ReconfigExistingLoggers();
logger.Error("Temporary Configuration");

rule.Targets.Add(target);
factory.ReconfigExistingLoggers();
logger.Error("Original Configuration");

log1.txt

2015-03-16 21:46:04.5685|ERROR|ConsoleApplication.Program|Original Configuration
2015-03-16 21:46:04.5865|ERROR|ConsoleApplication.Program|Temporary Configuration
2015-03-16 21:46:04.5865|ERROR|ConsoleApplication.Program|Original Configuration

log2.txt

2015-03-16 21:45:26.4238|ERROR|ConsoleApplication.Program|Original Configuration
2015-03-16 21:45:26.4588|ERROR|ConsoleApplication.Program|Original Configuration

解决方案

该问题的最佳解决方案是为每个工厂创建两个工厂和一个记录器。在订阅AppDomain.FirstChanceException 之前,必须初始化工厂和记录器。否则,如果您有异步操作或其他线程,您将遇到线程安全问题。

【讨论】:

  • @Yoh,谢谢,一些不错的细节。因此,看起来我的工厂需要两个 GetLogger 方法,并在我想要更多细节的地方使用一个记录器,在其他地方使用另一个记录器。换句话说,我在使用记录器的时候实际上什么都做不了,只有在创建它的时候?
  • 您需要两个工厂和每个工厂一个记录仪。第一个工厂将使用默认配置,第二个工厂将使用修改后的配置,删除了一些目标。
猜你喜欢
  • 1970-01-01
  • 2018-10-27
  • 2011-01-13
  • 2012-10-26
  • 2011-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多