【问题标题】:Is there any way to do a conditional in a NLog layout?有没有办法在 NLog 布局中做一个条件?
【发布时间】:2011-03-12 13:38:51
【问题描述】:

我正在尝试像这样创建一个 NLog 布局配置:

layout = "${callsite} > ${message} (${exception:format=tostring})"

这个布局的输出是(当我测试它时):

TestProject.Program.Main > 抛出异常(System.Exception:异常消息)

但是,如果我尝试输出一条没有异常的消息,它会显示如下:

TestProject.Program.Main > 没有抛出异常()

有没有什么办法可以修改这个布局,让括号只在实际出现异常时才显示?

【问题讨论】:

  • 我现在实际上也在想同样的事情。

标签: xml logging configuration layout nlog


【解决方案1】:

您可以像这样编写自己的 LayoutRenderer:

  [LayoutRenderer("MyCustomExceptionLayoutRenderer")]
  class MyCustomExceptionLayoutRenderer : LayoutRenderer
  {
    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
      if (logEvent.Exception == null)
      {
        builder.Append("no exception thrown");
      }
      else
      {
        //Might want fancier formatting of exception here...
        builder.Append("exception thrown ({0})", logEvent.Exception.ToString());
      }
    }

    protected override int GetEstimatedBufferSize(LogEventInfo logEvent)
    {
      return 100;
    }
  }

我认为(但还没有尝试过)您也可以将 LayoutRenderer 定义为采用这样的一个(或多个参数):

  public enum BracketOption
  {
    None,
    Parentheses,        // ()
    CurlyBraces,        // {}
    SquareBraces,       // []
    LessThanGreaterThan // <>
  }

  [LayoutRenderer("MyCustomExceptionLayoutRenderer")]
  class MyCustomExceptionLayoutRenderer : LayoutRenderer
  {
    public BracketOption Option { get; set; }

    private string left = "";
    private string right = "";

    public MyCustomExceptionLayoutRenderer()
      :base()
    {
      Option = BracketOption.None;
    }

    protected override void Initialize()
    {
      switch(Option)
      {
        case BracketOption.Parentheses:
          left = "(";
          right = ")";
          break;
        case BracketOption.CurlyBraces:
          left = "{";
          right = "}";
          break;
        case BracketOption.SquareBraces:
          left = "[";
          right = "]";
          break;
        case BracketOption.LessThanGreaterThan:
          left = "<";
          right = ">";
          break;
        case BracketOption.None:
        default:
          left = "";
          right = "";
          break;
      }
    }

    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
      if (logEvent.Exception == null)
      {
        builder.Append("no exception thrown");
      }
      else
      {
        //Might want fancier formatting of exception here...
        builder.Append(string.Format("exception thrown {0}{1}{2}", 
                        left, logEvent.Exception.ToString(), right);
      }
    }

    protected override int GetEstimatedBufferSize(LogEventInfo logEvent)
    {
      return 100;
    }
  }

要使用,请将这样的行添加到 NLog.config(或 app.config,如果配置内联):

<extensions>
  <add assembly="MyNLogExtensions" />
</extensions>

并像这样添加到您的布局中:

<targets>
  <target type="Console" layout="Exception: ${MyCustomException}" />
</targets>

参数化布局可能如下所示(不确定指定选项的确切格式):

<targets>
  <target type="Console" layout="Exception: ${MyCustomException:BracketOption=Parentheses}" />
</targets>

【讨论】:

  • 谢谢,我目前没有使用 NLog,但如果我需要使用它进行条件布局,我会参考你的答案。
  • 仅供参考,请参阅 Pat 对此问题的回答:stackoverflow.com/questions/4091606/… 以获取可能解决您的问题(或您最初询问时遇到的问题)的仅配置技术。本质上,他定义了两个具有相同输出文件名的目标。一个目标包含异常布局渲染器,一个不包含。 “异常目标”被包装在过滤包装器中,该包装器仅在 {exception} 的值的长度 > 0 时记录。无论如何,您或其他人可能会发现这些信息很有用。
猜你喜欢
  • 2014-05-09
  • 2020-07-16
  • 2022-11-17
  • 1970-01-01
  • 2018-08-10
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多