Skip to content

NLog Memory Leak with slow log writer #2655

@grahambunce

Description

@grahambunce

Type (choose one):

  • Bug

NLog version: (e.g. 4.2.3)
4.4.12 and 4.5 (started with 4.4.12, tried an upgrade to 4.5)

Platform: .Net 4.6.1 (Azure Web App)

Current NLog config (xml or C#, if relevant)

    <extensions>
      <add assembly="NLog.AzureBlobStorage"/>
    </extensions>
    <targets>
      <target type="AsyncWrapper" name="logger" overflowAction="Grow">
        <target type="AzureAppendBlob" name="bloblog" connectionString="logs" container="logs"
          layout="${date:format=yyyy-MM-dd HH\:mm\:ss.fffff},${threadid},${logger},${message},${all-event-properties}"
          blobName="catalog-api\${date:universalTime=true:format=yyyy}/${date:universalTime=true:format=MM}/${date:universalTime=true:format=yyyy-MM-dd}/${date:universalTime=true:format=HH}:00.log"/>
      </target>
      <target type="AsyncWrapper" name="publisher" overflowAction="Grow">
        <target type="AzureAppendBlob" name="blobexception" connectionString="logs" container="logs"
          layout="${date:format=yyyy-MM-dd HH\:mm\:ss.fffff},${threadid},${exception:format=type}${newline}${exception:format=message}${newline}${event-properties:item=RootId},${event-properties:item=ParentId},${event-properties:item=Id}${newline}${exception:format=data}${newline}${newline}${exception:format=stacktrace}${newline}"
          blobName="catalog-api\${date:universalTime=true:format=yyyy}/${date:universalTime=true:format=MM}/${date:universalTime=true:format=yyyy-MM-dd}/${date:universalTime=true:format=HH}:00-exception.log"/>
      </target>
    </targets>
    <rules>
      <logger name="*" minlevel="Trace" writeTo="logger"/>
      <logger name="exception" minlevel="Error" writeTo="publisher" final="true"/>
    </rules>
  </nlog>

In case of a BUG:

  • What is the current result?
    As load increases on the site, AppPool increases in memory usage. This memory is never released.

  • What is the expected result?
    AppPool to increase in memory as load increases (due to buffering of logs) but then release this as load descreases

  • Did you checked the Internal log?
    yes

  • Please post full exception details (message, stacktrace, inner exceptions)
    n/a

  • Are there any workarounds? yes/no
    no

  • Is there a version in which it did work?
    no

  • Can you help us by writing an unit test?
    n/a

I know there have been a number of NLog memory leak issues raised before (#2369 #2220 #2343 #1846 #316) and these have been closed. However, I don't think that they have been closed with a proper resolution, more like "a workaround has been found that works, I'll close it".

The workaround appears to be finding a way to increase throughput of the file logger. So, I guess, the logger could then keep pace with the logs so objects did not start to grow in the async logger buffer, therefore the problem goes away.

In our case, we're using a custom Azure Blob logger and the existing workarounds for the async wrapper suggested by @snakefoot did not make any difference. I suspect that our logging throughput is high enough, and the write performance of the Blob Logger is slow enough, so that no matter what happens we cause the async buffer to grow, and therefore increase memory usage.

This would be fine (and expected behaviour) as long as when the site cools down the buffer eventually gets drained and memory is released. This does not appear to be happening, as although all log writes are completed, memory remains high - potential culprit is the LogEventInfo object which is reported in #2220

image

I did some digging and then found this fork: https://github.com/jkowalski/NLog/pull/19/files that appears to explicitly dispose of the object that may be causing all the trouble. As far as I can see, this code isn't implemented in the official NLog code base.

I've checked this Azure Blob Logger code and it appears pretty simple so I don't think the reason is this extension, besides, even if we could increase it's performance, I feel we are still masking an underlying issue with the async wrapper.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions