tags:

views:

111

answers:

1

I have an NLog target:

<target name="AspNetAsyncWrapperForMail" xsi:type="ASPNetBufferingWrapper">
  <target name="mail" xsi:type="Mail"
      subject="Error: ${callsite:includeSourcePath=False}"
      smtpServer="MySMTP"
      from="[email protected]"
      to="[email protected]"
      smtpAuthentication="None"
      body="${date}${file-contents:${basedir}/error.html}"
      html="true"/>
</target>

Error.html looks like this:

<div>
    <b>Message</b>=${message}
</div>

How can I get NLog to parse the contents of error.html, so that the ${message} param gets rendered with NLog rules?

A: 

I took a stab at it and came up with this solution:

  • My new renderer inherits from NLog.LayoutRenderers.FileContentsLayoutRenderer
  • Then, in the Append() method, I have this code (which is very similar to the code in FileContentsLayoutRenderer's Append() method:

    lock (this)
    {
            var fileName = FileName.GetFormattedMessage(logEvent);
    
    
    
        if (fileName != m_LastFileName)
        {
            ReadFileContents(fileName);
        }
    
    
        var layoutString = new Layout(_fileContents);
        m_RenderedContent = layoutString.GetFormattedMessage(logEvent);
        m_LastFileName = fileName;
    
    } builder.Append(m_RenderedContent);

The biggest problem with this is that until the app's appdomain recycles, that file will remain in memory and never get re-read from disk. So making changes doesn't affect the output initially.

I've added some debug code to handle this, but need to add more robust code to recognize the change in a production environment.

slolife