简体   繁体   中英

NLog Mail Target not working with BufferingWrapper\PostFilteringWrapper

I want to send the logs in case of failure by email. However, this also works if I use the mail target directly without BufferingWrapper & PostFilteringWrapper (Target: mailLog3), then I get for each log entry a separate email. If I use the BufferingWrapper & PostFilteringWrapper (Target: mailLog1), this works sometimes for the first time, but not a second time.

<configuration>
  <configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    throwExceptions="true" internalLogToConsole="true" internalLogLevel="Warn" internalLogFile="nlog.log">

<variable name="Error" value="Logs\${shortdate}_ErrorLog.xml"/>

<targets async="true">
  <!--The following will keep the default number of log messages in a buffer and write out certain levels if there is an error and other levels if there is not. Messages that appeared before the error (in code) will be included, since they are buffered.-->
  <wrapper-target xsi:type="BufferingWrapper" name="smartLog">
    <wrapper-target xsi:type="PostFilteringWrapper">
      <!--<target-ref name="fileAsCsv"/>-->
      <target xsi:type="File" fileName="${Error}"
      archiveAboveSize="4194304" concurrentWrites="false" maxArchiveFiles="1" archiveNumbering="Sequence">
        <layout xsi:type="Log4JXmlEventLayout">
        </layout>
      </target>

      <!--during normal execution only log certain messages-->
      <defaultFilter>level >= LogLevel.Warn</defaultFilter>

      <!--if there is at least one error, log everything from trace level-->
      <when exists="level >= LogLevel.Error" filter="level >= LogLevel.Trace" />
    </wrapper-target>
  </wrapper-target>

  <wrapper-target xsi:type="BufferingWrapper" name="mailLog1" slidingTimeout="true" bufferSize="1000" flushTimeout="-1">
    <wrapper-target xsi:type="PostFilteringWrapper" name="mailLog2" defaultFilter="level = LogLevel.Fatal">
      <target xsi:type="Mail" name="mailLog3"
                smtpServer="xxx"
                smtpPort="25"
                smtpAuthentication="None"
              subject="Error"
                from="xxx"
                to="xx"
                layout="${longdate} ${uppercase:${level}} ${callsite:className=true:includeSourcePath=true:methodName=true} ${message}${newline}" />
      <when exists="level = LogLevel.Fatal" filter="level >= LogLevel.Trace"/>
    </wrapper-target>
  </wrapper-target>


</targets>
<rules>
  <logger name="*" minlevel="Trace" writeTo="smartLog"/>
  <logger name="*" minlevel="Trace" writeTo="mailLog1"/>
</rules>
</nlog>
</configuration>

Thanks for help.

If slidingTimeout is set to true (default and so in this case) on the BufferingWrapper, then the messages are already written asynchronously.

So there is no no need to combine the BufferingWrapper with the async attribute or the AsyncWrapper. As you have noticed, combining the BufferingWrapper with async writing could lead to losing messages. This because in the async written, messages are written to another async writer.

See documentation of the BufferingWrapper

I found the problem. If i set:

<targets async="false">

It works fine.The funny thing is in other projects, this also works with:

<targets async="true">

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM