Распечатать многострочное сообщение с NLog.Extensions.Logging (1.6.1) - PullRequest
0 голосов
/ 17 февраля 2020

Я разрабатываю консольное приложение. NET Core 3.1 с NLog.Extensions.Logging (v1.6.1) и хотел бы напечатать сообщение, содержащее несколько строк. Я следовал примеру, ранее предоставленному в StackOverflow, с использованием средства визуализации макета оболочки, скопированного ниже. Я вижу, как заменяются новые строки; однако начало многострочного сообщения (т. е. первая строка) не имеет префикса (?)

Вывод из примера выглядит следующим образом:

line 1> Hello world 
line 2> 19:30:45.2313 Hello World , again

Код предоставленного ранее примера:

using System;
using System.Text;
using NLog.Config;
using NLog.LayoutRenderers;
using NLog.LayoutRenderers.Wrappers;
using NLog.Layouts;

namespace My.Namespace
{
    [LayoutRenderer("replace-newlines-withlayout")]
    [ThreadAgnostic]
    public class ReplaceNewLinesFormatLayoutRendererWrapper : WrapperLayoutRendererBase
    {
        private string m_replacementString = " ";

        public ReplaceNewLinesFormatLayoutRendererWrapper()
        {
            // Changed from
            // Replacement = " ";
            Replacement = Layout.FromString(" ");
        }

        // Changed from
        // public string Replacement { get; set; }
        public Layout Replacement { get; set; }

        // Override Append in order to render the replacement.
        protected override void  Append(StringBuilder builder, NLog.LogEventInfo logEvent)
        {
            // Render...
            m_replacementString = Replacement.Render(logEvent);

            // The base functionality of append is fine.
            base.Append(builder, logEvent);
        }   

        // Called from base.Append()
        protected override string Transform(string text)
        {
            // Changed from 
            // return text.Replace(Environment.NewLine, Replacement);

            // Now just put in the rendered replacement string.
            return text.Replace(Environment.NewLine, m_replacementString);
        }
    }
}

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:\temp\console-example-internal.log"
      internalLogLevel="Info" >

  <!-- the targets to write to -->
  <targets>
    <!-- write logs to file -->
    <target xsi:type="File" name="target1" fileName="c:\temp\console-example.log"
        layout="${replace-newlines-withlayout:replacement=${newline}${time}:${message}}" />
    <target xsi:type="ColoredConsole" name="target2"
        layout="${replace-newlines-withlayout:replacement=${newline}${time}:${message}}" />
    />
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <logger name="*" minlevel="Trace" writeTo="target1,target2" />
  </rules>
</nlog>

Пример:

class Program
{
    private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();

    static void Main(string[] args)
    {
        try
        {
            var ReplaceNewLinesFormatLayoutRendererWrapper = new ReplaceNewLinesFormatLayoutRendererWrapper();
            ReplaceNewLinesFormatLayoutRendererWrapper.Register<NLogTest.ReplaceNewLinesFormatLayoutRendererWrapper>("replace-newlines-withlayout");

            Logger.Info($"Hello world {Environment.NewLine} Hello World , again");
            System.Console.ReadKey();
        }
        catch (Exception ex)
        {
            Logger.Error(ex, "yeah, here again");
        }
    }
}

1 Ответ

1 голос
/ 18 февраля 2020

Проблема здесь в том, что Transform вызывается раньше Append, а ваш Transform зависит от Append.

К счастью, в настоящее время есть лучший Transform для переопределения, один это также будет включать LogEventInfo в качестве параметра. (NLog 4.5 +)

Таким образом, вы можете удалить текущие перезаписи «Добавить» и «Преобразовать» и заменить на:

protected override string Transform(LogEventInfo logEvent, string text)
{
    // Render...
    var replacementString = Replacement.Render(logEvent);

    // Now just put in the rendered replacement string.
    return text.Replace(Environment.NewLine, replacementString);
}

Полный код (после некоторой очистки):

using System;
using NLog;
using NLog.Config;
using NLog.LayoutRenderers;
using NLog.LayoutRenderers.Wrappers;
using NLog.Layouts;

namespace My.Namespace
{
    [LayoutRenderer("replace-newlines-withlayout")]
    [ThreadAgnostic]
    public class ReplaceNewLinesFormatLayoutRendererWrapper : WrapperLayoutRendererBase
    {
        public Layout Replacement { get; set; } = " ";

        protected override string Transform(LogEventInfo logEvent, string text)
        {
            // Render...
            var replacementString = Replacement.Render(logEvent);

            // Now just put in the rendered replacement string.
            return text.Replace(Environment.NewLine, replacementString);
        }
    }
}
...