Randall W
Randall W

Reputation: 229

NLog Buffering Wrapper With PostSharp.Diagnostics

I have a set of REST services that serve as an API for a client. It is written in .NET Core 2.2. I am having problems figuring out how to get logging to work with a BufferingWrapper using Postsharp to generate messages and NLog as the logging backend. The objective is to allow the BufferingWrapper to dump out log messages regardless of the log level if an error occurs.

Here are the details.

I am using PostSharp.Diagnostics to generate logging messages.

This is my GlobalAspects definition.

[assembly: Log("default", AttributeTargetTypes = "My.Namespace.Bl.*", AttributePriority = 1, AttributeTargetMemberAttributes = MulticastAttributes.Protected | MulticastAttributes.Public)]
[assembly: Log(AttributePriority = 2, AttributeExclude = true, AttributeTargetMembers = "get_*")]
[assembly: Log(AttributePriority = 3, AttributeExclude = true, AttributeTargetMembers = "set_*")]
[assembly: Log(AttributePriority = 4, AttributeExclude = true, AttributeTargetMembers = "*ctor*")]

This is my logging profile in the PostSharp.config file.

  <Logging xmlns="clr-namespace:PostSharp.Patterns.Diagnostics;assembly:PostSharp.Patterns.Diagnostics">
    <Profiles>
      <LoggingProfile Name="default" IncludeExecutionTime="True">
        <DefaultOptions>
          <LoggingOptions IncludeParameterType="True" IncludeParameterName="True" />
        </DefaultOptions>
      </LoggingProfile>
    </Profiles>
  </Logging>

I created a console log and a BuffingWrapper for my target in the nlog.config file.

    <wrapper-target name="buffer" xsi:type="BufferingWrapper" bufferSize="50" overflowAction="Flush" flushTimeout="1000">
      <wrapper-target xsi:type="PostFilteringWrapper">
        <defaultFilter>level >= LogLevel.Warn</defaultFilter>
        <when exists="level >= LogLevel.Error" filter="level >= LogLevel.Trace" />
        <target xsi:type="File" fileName="${var:logDirectory}/MyLogFile-${shortdate}.log"
                layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />
      </wrapper-target>
    </wrapper-target>

    <target xsi:type="ColoredConsole"
            name="consoleLog"
            layout="${longdate}|${threadid}|${mdlc:item=EventTier}|${machinename}|${uppercase:${level}}|${message} ${exception:format=message}" />

<rules>
    <logger name="*" minlevel="Trace" writeTo="buffer" >
    <logger name="*" minlevel="Trace" writeTo="consoleLog" />
</rules

Triggering an exception can be done by sending in a field value that is larger than the database field size. When that happens, the console log that logs everything displays all the log messages as expected including those generated by Postsharp. The buffer logger shows log messages that are purposefully written (e.g. _logger.LogError("something bad happened")) but not those that are generated by Postsharp. It also shows those error messages that are generated by Entity Framework about the exception.

What I Have Tried

I'm using Microsoft.Extensions.Logging. I set that up according to the instructions found here. Logging classes are injected into the class using DI. There are a few explicit logging statements but most of the logs are generated by Postsharp. The results are as described above.

Next, I tried not using Microsoft.Extensions.Logging and using only NLog. Same results.

I created a smaller console program to test the buffer. I get the same results. Log messages that I explicitly create (e.g. _logger.LogInformation("I did a thing.")) are captured in the buffer but the Postsharp generated ones are not.

I would appreciate any ideas on how to resolve this.

Thanks

Upvotes: 1

Views: 159

Answers (1)

Petr Hudeček
Petr Hudeček

Reputation: 1773

Most PostSharp tracing, such as entering and exiting method, is done at the Trace or Debug level.

This line in your NLog configuration

<defaultFilter>level >= LogLevel.Warn</defaultFilter>

makes it so that only messages of that level or above cause the buffer to flush. The consoleLog target has no such default filter, hence it contains PostSharp messages.

If you cause the buffer to flush afterwards, with an error message, it will contain PostSharp messages.

Upvotes: 1

Related Questions