Есть ли способ сделать условное в макете NLog?

Я пытаюсь создать конфигурацию макета NLog следующим образом:

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

Вывод для этого макета (когда я его тестирую):

TestProject.Program.Main> создано исключение (System.Exception: сообщение об исключении)

Однако, если я попытаюсь вывести сообщение, не имеющее исключения, оно будет выглядеть так:

TestProject.Program.Main> исключение не выброшено ()

Есть ли способ изменить этот макет, чтобы скобки появлялись только тогда, когда на самом деле есть исключение?


person Daniel T.    schedule 06.07.2010    source источник
comment
Я на самом деле задаюсь вопросом о том же самом прямо сейчас.   -  person quentin-starin    schedule 27.07.2010


Ответы (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>
person wageoghe    schedule 27.10.2010
comment
Спасибо, в настоящее время я не использую NLog, но если мне когда-нибудь понадобится сделать с ним условный макет, я обращусь к вашему ответу. - person Daniel T.; 28.10.2010
comment
К вашему сведению, см. ответ Пэта на этот вопрос: stackoverflow.com/questions/4091606 / только для метода настройки, который может решить вашу проблему (или проблему, которая у вас была, когда вы изначально спрашивали). По сути, он определяет две цели с одинаковым именем выходного файла. Одна цель содержит средство визуализации макета исключения, а другая — нет. Цель исключения помещается в фильтрующую оболочку, которая регистрируется только в том случае, если длина значения {exception} равна › 0. В любом случае, вы или кто-то еще может найти эту информацию полезной. - person wageoghe; 05.11.2010