13

I've added NLog using nuget to a project and added NLog.config. I'm running the debugger and getting a NullReferenceException due to the fact LogManager.Configuration is null:

LogManager.Configuration.AddTarget("sentinel", sentinalTarget);

This line of code runs in a static constructor.

  • NLog.config is located in the project root alongside the web.config.
  • This occurs in visual studio debugger
  • NLog.config property "Copy to output directory" = "Copy Always"
  • I updated NLog.config throwExceptions="true" and at runtime LogManager.ThrowExceptions was false so I suspect an issue with the config
  • Tried removing the targets with name: viewer, DbWin and their associated rules

NLog.config contents:

<?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"
      autoReload="true"
      throwExceptions="false">

  <variable name="appName" value="YourAppName" />

  <targets async="true">
    <target xsi:type="File"
            name="default"
            layout="${longdate} - ${level:uppercase=true}: ${message}${onexception:${newline}EXCEPTION\: ${exception:format=ToString}}"
            fileName="${specialfolder:ApplicationData}\${appName}\Debug.log"
            keepFileOpen="false"
            archiveFileName="${specialfolder:ApplicationData}\${appName}\Debug_${shortdate}.{##}.log"
            archiveNumbering="Sequence"
            archiveEvery="Day"
            maxArchiveFiles="30"
            />

    <target xsi:type="EventLog"
            name="eventlog"
            source="${appName}"
            layout="${message}${newline}${exception:format=ToString}"/>

    <target xsi:type="NLogViewer"
            name="viewer"
            address="udp://127.0.0.1:9999"/>

    <target xsi:type="OutputDebugString" name="DbWin" layout="Log4JXmlEventLayout">
      <layout xsi:type="Log4JXmlEventLayout" />
    </target>
  </targets>
  <rules>
    <logger name="*" writeTo="default" minlevel="Info" />
    <logger name="*" writeTo="eventlog" minlevel="Error" />
    <logger name="*" minlevel="Debug" writeTo="viewer" />
    <logger name="*" minlevel="Trace" writeTo="DbWin" />
  </rules>
</nlog>

Update
I discovered the source. The issue occurs only when running unit tests. Running the full application (web app) the issue is not there. I copied the NLog.config file to the unit test home directory. The issue is still there when running unit tests.

Julian
  • 33,915
  • 22
  • 119
  • 174
P.Brian.Mackey
  • 43,228
  • 68
  • 238
  • 348
  • I'm sure that you've tried simpler NLog configurations (like just going to a file), but I'll ask anyway. Also, is it possible that the static constructor where you are adding the target to the Configuration object executes before the NLog.config file is read? – wageoghe Apr 30 '14 at 13:54
  • @wageoghe Yes, the issue is narrowed down. See update – P.Brian.Mackey Apr 30 '14 at 13:55
  • Assuming you are using Microsoft's unit testing framework, you might need to make the NLog.config file a DeploymentItem. – wageoghe Apr 30 '14 at 13:58

2 Answers2

20
  • Copy NLog.config to the Test projects top level folder
  • Add DeploymentItemAttribute to test classes (more info)

Like this:

[TestClass]
[DeploymentItem("ProjectName\\NLog.config")]
public class GeneralTests

Alternatively, you can load the configuration programmatically:

LogManager.Configuration = new XmlLoggingConfiguration(@"c:\path\to\NLog.config")

Corio
  • 395
  • 7
  • 20
P.Brian.Mackey
  • 43,228
  • 68
  • 238
  • 348
  • 2
    To set the configuration programatically,declare `var config = new LoggingConfiguration()`, set the properties of `config`, then set `LogManager.Configuration = config`. – David Ching Aug 28 '16 at 19:02
  • 1
    LogManager.Configuration = new XmlLoggingConfiguration(@".\\NLog.config") works for me. thanks. – JimiOr2 Apr 19 '19 at 06:54
1

Make sure your nlog.config is in one of the folders NLog scans to look for the config file. For example the folder of your executable.

If you are using Visual Studio, you can configure this like this to automate the copy process: enter image description here

Stefan
  • 919
  • 2
  • 13
  • 24