nlog меняет поведение в зависимости от приоритета логгера - PullRequest
0 голосов
/ 15 октября 2018

Я хочу войти в определенную раскладку:

Message: {the message}  
Properties: {key}: {value} | {key}: {value} | ...

Моя основная задача:

static void Main(string[] args)
    {
        Loggers.TxtLogger.LogInfo();
        Loggers.TxtLogger.LogInfo("My custom message");
        Loggers.TxtLogger.LogInfo(new { id = 1, issue = "my custom issue" });


        Console.ReadKey();
    }

Мой класс Loggers:

public static class Loggers
{
    public static ILogger TxtLogger { get; private set; }

    static Loggers()
    {
        TxtLogger = LogManager.GetLogger("TxtLogger");
    }


    public static void LogInfo(this ILogger @this, object message = null)
    {
        @this.Info()
            .Property("Property1Key", "Property1Value")
            .Property("Property2Key", "Property2value")
            .Message(message == null ? "" : "{@message}", message)
            .Write();

    }

    public static void LogError(this ILogger @this, Exception e, object message = null)
    {
        @this.Error()
           .Exception(e)
           .Property("Property1Key", "Property1Value")
           .Property("Property2Key", "Property2value")
           .Message(message == null ? "" : "{@message}", message)
           .Write();
    }
}

Мой NLog.конфиг:

 <?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"
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false"
      throwConfigExceptions="true"
      internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">

    <variable name="logFile" value="./logs/${shortdate}/${logger}.log" />

    <variable name="colon" value="${literal:text=\:}"/>
    <variable name="quotationMark" value="${literal:text=&quot;}"/>
    <variable name="messageIfNotEmpty" value="${when:when=length('${message}')>0:inner=Message${colon} ${message}${newline}}"/>
    <variable name="properties" value="Properties${colon} ${all-event-properties:format=[key]\: [value]:separator= | }${newline}"/>

    <variable name="layout2" value="${messageIfNotEmpty}${properties}"/>

    <targets>
        <target name="ConsoleLog" xsi:type="Console" layout="${layout2}"/>
        <target name="TxtLog" xsi:type="File" fileName="${logFile}" layout="${layout2}"/>
    </targets>

    <rules>
        <logger name="*" writeTo="ConsoleLog" final="true"/>
        <logger name="*" writeTo="TxtLog" />
    </rules>

</nlog>

С этим набором я получаю желаемый результат:

Properties: Property1Key: Property1Value | Property2Key: Property2value  

Message: "My custom message"  
Properties: Property1Key: Property1Value | Property2Key: Property2value 

Message: {"id":1, "issue":"my custom issue"}  
Properties: Property1Key: Property1Value | Property2Key: Property2value 

Но когда я пытаюсь записать его также в файл .txt (я удаляю _final="true"_атрибут из ConsoleLog logger), я получаю такой результат:

Properties: Property1Key: Property1Value | Property2Key: Property2value

Message: "My custom message"  
Properties: message: My custom message | Property1Key: Property1Value | Property2Key: Property2value  

Message: {"id":1, "issue":"my custom issue"}  
Properties: message: { id = 1, issue = my custom issue } | Property1Key: Property1Value | Property2Key: Property2value  

Теперь есть обходной путь, и это, если я изменю параметр _object message = null_ в методе _LogInfo_ на _string message_ и я использую _newtonsoft json serializer_ для сериализации объекта, но я хочу использовать сериализатор NLog.
Есть мысли?

ОБНОВЛЕНИЕ

В NLog.Я изменил конфигурацию:
<variable name="layout2" value="${messageIfNotEmpty}${properties}"/>
на
<variable name="layout2" value="${properties}${messageIfNotEmpty}"/>
(поместите переменную сообщения после переменной свойств)
И:
<rules> <logger name="*" writeTo="ConsoleLog" final="true"/> <logger name="*" writeTo="TxtLog" /> </rules>
на
<rules> <logger name="*" writeTo="ConsoleLog"/> <logger name="*" writeTo="TxtLog" /> </rules>
(убрал атрибут final=true)

Итак, теперь мой результат консоли:

Properties: Property1Key: Property1Value | Property2Key: Property2value

Properties: Property1Key: Property1Value | Property2Key: Property2value
Message: "My custom message"

Properties: Property1Key: Property1Value | Property2Key: Property2value
Message: {"id":1, "issue":"my custom issue"}  

, который является желаемым результатом (с сообщением после свойств),
но в TXT-файле я получаю OUtcome:

Properties: Property1Key: Property1Value | Property2Key: Property2value

Properties: message: My custom message | Property1Key: Property1Value | Property2Key: Property2value
Message: "My custom message"

Properties: message: { id = 1, issue = my custom issue } | Property1Key: Property1Value | Property2Key: Property2value
Message: {"id":1, "issue":"my custom issue"}  

, что, очевидно, не является желаемым результатом.

Теперь я снова изменяю NLog.Config:

<rules>
    <logger name="*" writeTo="ConsoleLog"/>
    <logger name="*" writeTo="TxtLog" />
</rules>  

на:

<rules>
    <logger name="*" writeTo="TxtLog" />
    <logger name="*" writeTo="ConsoleLog"/>
</rules>  

(сначала я поставил TxtLog)
А теперьрезультаты уважаются,
Консоль: Не желаемый результат (сообщение печатается дважды)
TXT: Желаемый результат
И последнее, если я изменяю:

<variable name="layout2" value="${properties}${messageIfNotEmpty}"/>  

обратно на:

<variable name="layout2" value="${messageIfNotEmpty}${properties}"/>  

(поместите переменную сообщения перед свойствами),
Я не получаю желаемого результата, каким бы ни был порядок ведения журнала.

1 Ответ

0 голосов
/ 21 октября 2018

В NLog ver есть ошибка4.5.10, но вы можете обойти это, изменив свой код на это:

public static class Loggers
{
    public static ILogger TxtLogger { get; private set; }

    static Loggers()
    {
        TxtLogger = LogManager.GetLogger("TxtLogger");
    }


    public static void LogInfo(this ILogger @this, object message = null)
    {
        @this.Info()
            .Message("{0}", message ?? (object)string.Empty)
            .Property("Property1Key", "Property1Value")
            .Property("Property2Key", "Property2value")
            .Write();
    }

    public static void LogError(this ILogger @this, Exception e, object message = null)
    {
        @this.Error()
           .Message("{0}", message ?? (object)string.Empty)
           .Exception(e)
           .Property("Property1Key", "Property1Value")
           .Property("Property2Key", "Property2value")
           .Write();
    }
}

См. Также https://github.com/NLog/NLog/pull/2963

...