I am using NLog for my logger. Everything works fine when logging when I run an .exe, or even debug through Visual Studio, NLog will still write to the file.
But, if I run an object that calls the logger through a Unit test, the file is created but it is empty. Is there an extra setting/rule I need to add to the config to have NLog write to files under unit tests?
I could mock NLog for this and not have log dumps, but I'd like to see if I can get this to work before I decide to just mock NLog. Even though this is only happening in unit tests and is working otherwise, here is my config and code for logging. I left out the filenames.
public static void Info(string app, string m) => EngineLogger.Logger.Info($"{app} : {m}");
<targets>
<target name="infoFile"
xsi:type="File"
layout="${date:format=yyyy-MM-dd HH\:mm\:ss} ${pad:padding=5:inner=${level:uppercase=true}} ${logger} ${message}"
fileName="leftoutForQuestion"
keepFileOpen="false"
encoding="iso-8859-2" />
<target name="errorFile"
xsi:type="File"
layout="${date:format=yyyy-MM-dd HH\:mm\:ss} ${pad:padding=5:inner=${level:uppercase=true}} ${logger} ${message}"
fileName="leftOutForQuestion"
keepFileOpen="false"
encoding="iso-8859-2" />
</targets>
<rules>
<logger name="*" minlevel="Debug" maxlevel="Info" writeTo="infoFile" />
<logger name="*" minlevel="Warn" maxlevel="Fatal" writeTo="errorFile" />
</rules>
Here is the error from internal log:
Error Error has been raised. Exception: System.Runtime.InteropServices.COMException (0x800700A1): The specified path is invalid. (Exception from HRESULT: 0x800700A1)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at NLog.Internal.FileAppenders.BaseFileAppender.WindowsCreateFile(String fileName, Boolean allowFileSharedWriting)
at NLog.Internal.FileAppenders.BaseFileAppender.TryCreateFileStream(Boolean allowFileSharedWriting)
at NLog.Internal.FileAppenders.BaseFileAppender.CreateFileStream(Boolean allowFileSharedWriting)
at NLog.Internal.FileAppenders.RetryingMultiProcessFileAppender.Write(Byte[] bytes)
at NLog.Targets.FileTarget.WriteToFile(String fileName, LogEventInfo logEvent, Byte[] bytes, Boolean justData)
at NLog.Targets.FileTarget.ProcessLogEvent(LogEventInfo logEvent, String fileName, Byte[] bytesToWrite)
at NLog.Targets.FileTarget.Write(LogEventInfo logEvent)
at NLog.Targets.Target.Write(AsyncLogEventInfo logEvent)
Not sure if this is the problem, but pretty sure it is:
Reading the NLog.config from an unit test environment could be difficult, therefor is more robust to read the config from string in the unit tests. We use the helper:
and then:
don't forget to reset the
LogManager.Configuration
before or after each test.Update : enabled throwExceptions in config.
Also about the error. You need probably an absolute path in the unit test.
I found that all the configuration resides within a app.config for a Unit Test Project as opposed to the NLog.Config file. Be sure to declare the config section and then the NLog configuration. Below is my sample app.config
When executing units test in parallel, then it is a good idea to use isolated NLog LogFactory for each parallel execution:
See also https://github.com/NLog/NLog/wiki/Configure-component-logging
If you need to load NLog config from a string instead of a file:
See also https://github.com/NLog/NLog/wiki/Explicit-NLog-configuration-loading