1

I started learning NLog yesterday. An answer to another question (Configuring NLog to log exceptions in an XML output?) said that you can use a NLog.config file to configure output as XML data.

I placed this file in my application folder:

<?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">

    <target name="xmlFile" xsi:type="File" fileName="d:\\${shortdate}.log" >
        <layout xsi:type="XmlLayout" includeAllProperties="false" elementName='logevent'>
            <attribute name="time" layout="${longdate}" />
            <attribute name="level" layout="${level:upperCase=true}"/>
            <element name="message" value="${message}" />
            <element name="exception_type" layout="${exception:format=Type}"/>
        </layout>
    </target>
    
</nlog>

And, I have dummy code in a test console application:

namespace TestConsoleNlog
{
    internal class Program
    {
        private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();

        static void Main(string[] args)
        {
            if(Logger != null)
            {
                Logger.Info("This is a note");
                try
                {
                    Logger.Info("Hello world");
                    System.Console.ReadKey();
                }
                catch (Exception ex)
                {
                    Logger.Error(ex, "Goodbye cruel world");
                }
            }
        }
    }
}

I expected it to create / update a log file in the root of D drive but there is no file. Why?


And, based on the question (Is there a way to put NLog.config information inside of my app.config file?) I tried to put it in the app.config instead:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
    </startup>
    <configSections>
        <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
    </configSections>
    <nlog>
        <targets>
            <target name="xmlFile" type="File" fileName="d:\\${shortdate}.log" >
                <layout type="XmlLayout" includeAllProperties="false" elementName='logevent'>
                    <attribute name="time" layout="${longdate}" />
                    <attribute name="level" layout="${level:upperCase=true}"/>
                    <element name="message" value="${message}" />
                    <element name="exception_type" layout="${exception:format=Type}"/>
                </layout>
            </target>
        </targets>
    </nlog>
</configuration>

No joy.


I have tried:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
    </startup>
    <configSections>
        <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
    </configSections>
    <nlog internalLogLevel="Trace">
        <targets>
            <target name="xmlFile" type="File" fileName="d:\\${shortdate}.log" >
                <layout type="XmlLayout" includeAllProperties="false" elementName='logevent'>
                    <attribute name="time" layout="${longdate}" />
                    <attribute name="level" layout="${level:upperCase=true}"/>
                    <element name="message" value="${message}" />
                    <element name="exception_type" layout="${exception:format=Type}"/>
                </layout>
            </target>
        </targets>
        <rules>
            <logger name="*" minlevel="Debug" writeTo="xmlFile" />
        </rules>
    </nlog>
</configuration>

But no joy still.


I added manual code to do internal logging and this is what it says:

2022-12-28 20:08:03.4444 Error Error has been raised. Exception: System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize ---> System.Configuration.ConfigurationErrorsException: Only one <configSections> element allowed per config file and if present must be the first child of the root <configuration> element. (D:\My Debug\TestConsoleNlog\TestConsoleNlog\bin\Debug\TestConsoleNlog.exe.Config line 6)
   at System.Configuration.ConfigurationSchemaErrors.ThrowIfErrors(Boolean ignoreLocal)
   at System.Configuration.BaseConfigurationRecord.ThrowIfParseErrors(ConfigurationSchemaErrors schemaErrors)
   at System.Configuration.BaseConfigurationRecord.ThrowIfInitErrors()
   at System.Configuration.ClientConfigurationSystem.EnsureInit(String configKey)
   --- End of inner exception stack trace ---
   at System.Configuration.ConfigurationManager.PrepareConfigSystem()
   at System.Configuration.ConfigurationManager.GetSection(String sectionName)
   at NLog.Config.LoggingConfigurationWatchableFileLoader.TryLoadFromAppConfig()
2022-12-28 20:08:03.4564 Debug No file exists at candidate config file location: D:\My Debug\TestConsoleNlog\TestConsoleNlog\bin\Debug\TestConsoleNlog.exe.nlog
2022-12-28 20:08:03.4564 Debug No file exists at candidate config file location: D:\My Debug\TestConsoleNlog\TestConsoleNlog\bin\Debug\NLog.config
2022-12-28 20:08:03.4564 Debug No file exists at candidate config file location: D:\My Debug\TestConsoleNlog\TestConsoleNlog\bin\Debug\NLog.dll.nlog
2022-12-28 20:08:05.6805 Debug No file exists at candidate config file location: D:\My Debug\TestConsoleNlog\TestConsoleNlog\bin\Debug\TestConsoleNlog.exe.nlog
2022-12-28 20:08:05.6805 Debug No file exists at candidate config file location: D:\My Debug\TestConsoleNlog\TestConsoleNlog\bin\Debug\NLog.config
2022-12-28 20:08:05.6805 Debug No file exists at candidate config file location: D:\My Debug\TestConsoleNlog\TestConsoleNlog\bin\Debug\NLog.dll.nlog
2022-12-28 20:08:05.6805 Info Shutdown() called. Logger closing...
2022-12-28 20:08:05.6805 Info Logger has been closed down.
2022-12-28 20:08:05.6865 Info AppDomain Shutting down. LogFactory closing...
2022-12-28 20:08:05.6865 Info LogFactory has been closed.
Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
  • 2
    There is a [troubleshooting guide](https://github.com/NLog/NLog/wiki/Logging-troubleshooting), if having issues with NLog. Enabling the [NLog InternalLogger](https://github.com/NLog/NLog/wiki/Internal-logging) is usually helpful for finding the issues. – Rolf Kristensen Dec 28 '22 at 17:39
  • 2
    I'm guessing the problem is that you have not specified any Logging-Rules for mapping Logger-output to the wanted NLog target. See also the [Tutorial](https://github.com/NLog/NLog/wiki/Tutorial) – Rolf Kristensen Dec 28 '22 at 17:40
  • @RolfKristensen I tried `` and no exceptions are thrown. – Andrew Truckle Dec 28 '22 at 18:49
  • Did you type a return in the console window? System.Console.ReadKey(); – jdweng Dec 28 '22 at 19:02
  • @jdweng Yes. The app went through to termination. – Andrew Truckle Dec 28 '22 at 19:05
  • 1
    NLog InternalLogger works fine for me when using `internalLogLevel="Debug" internalLogToConsole="True"`. Notice `throwConfigExceptions="true"` doesn't work well with app.config because it is a special file. The error-message says that `` is not good. Try changing to `` – Rolf Kristensen Dec 28 '22 at 20:14
  • 1
    Also remember to have `` at the very top (above ``). That is the meaning of the error `Only one element allowed per config file and if present must be the first child of the root element` – Rolf Kristensen Dec 28 '22 at 20:28

1 Answers1

1

The <configSections> in app.config must be at the top (above <startup>):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
    </configSections>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
    </startup>
    <nlog>
        <targets>
            <target name="xmlFile" type="File" fileName="d:\\${shortdate}.log" >
                <layout type="XmlLayout" includeAllProperties="false" elementName='logevent'>
                    <attribute name="time" layout="${longdate}" />
                    <attribute name="level" layout="${level:upperCase=true}"/>
                    <element name="message" value="${message}" />
                    <element name="exception_type" value="${exception:format=Type}"/>
                </layout>
            </target>
        </targets>
        <rules>
            <logger name="*" minlevel="Debug" writeTo="xmlFile" />
        </rules>
    </nlog>
</configuration>

Also remember to include NLog logging <rules> to perform mapping from NLog Logger-output to destination NLog Target.

Rolf Kristensen
  • 17,785
  • 1
  • 51
  • 70