In this blog post, I will show you how to create a nlog config file for logging messages in your .NET applications. Nlog is a popular and flexible logging framework that allows you to write logs to various targets, such as files, databases, email, console, etc. Nlog also supports structured logging, which is a way of formatting log messages with key-value pairs that can be easily parsed and analyzed.

To use nlog in your project, you need to install the NLog NuGet package and create a nlog.config file in the root folder of your project. Here is my default nlog.config file I use in all my projects:

<?xml version="1.0" encoding="utf-8" ?>
<!--https://github.com/NLog/NLog/wiki/Configuration-file-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogFile="${basedir}/logs/log-internal.log" throwConfigExceptions="true" internalLogLevel="Off">
	<variable name='globalLevel' value='debug'/>
	<variable name='' value=''/>
	<targets async="true">
		<!--Blackhole Target-->
		<target xsi:type="Null" name="blackhole" />

		<!--Visual Studio Debug Console Target-->
		<target name="debugger" xsi:type="Debugger" layout="${level:uppercase=true:padding=-5}|${threadid:padding=-2}|${callsite}|${message}" />

		<!--Console Target-->
		<target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />

		<!--Color Console Target-->
		<target xsi:type="ColoredConsole" name="coloredConsole" layout="${MicrosoftConsoleLayout}" useDefaultRowHighlightingRules="true">
			<highlight-row condition="level == LogLevel.Trace" foregroundColor="DarkGray" />
			<highlight-row condition="level == LogLevel.Debug" foregroundColor="Yellow" />
			<highlight-row condition="level == LogLevel.Info" foregroundColor="White" />
			<highlight-row condition="level == LogLevel.Warn" foregroundColor="Magenta" />
			<highlight-row condition="level == LogLevel.Error" foregroundColor="Red" />
			<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" />
		</target>

		<!--Json File Target-->
		<target xsi:type="File"
		        name="jsonFile"
		        fileName="${basedir}/logs/nlog-json-${shortdate}.log"
		        maxArchiveFiles="5" archiveNumbering="Sequence" archiveEvery="Day">
			<layout xsi:type="MicrosoftConsoleJsonLayout" includeScopes="true" />
		</target>

		<!-- File Target for all log messages with basic details -->
		<target xsi:type="File"
		        name="allfile"
		        fileName="${basedir}/logs/nlog-all-${shortdate}.log"
		        maxArchiveFiles="5"
		        layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}" />

		<!-- File Target for own log messages with extra web details using some ASP.NET core renderers -->
		<target xsi:type="File"
		        name="ownFile-web"
		        fileName="${basedir}/logs/nlog-webapp-${shortdate}.log"
		        maxArchiveFiles="5"
		        layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}|${callsite}" />
	</targets>

	<rules>
		<!--All logs to 'blackhole' -->
		<logger name="*" minlevel="Trace" writeTo="blackhole" final="true" enabled="false" />
		<!--All logs at minlevel+ -->
		<logger name="*" minlevel="${globalLevel}" writeTo="allfile, jsonFile" enabled="false" />

		<!--Log Hosting Liftime-->
		<logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="coloredConsole, debugger" enabled="true" />
		<logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="ownFile-web" enabled="true" />

		<!--Skip non-critical Microsoft logs-->
		<logger name="Microsoft.*" maxlevel="Info" final="true" enabled="true" />
		<logger name="System.Net.Http.*" maxlevel="Info" final="true" enabled="true" />

		<!--Application logs-->
		<logger name="*" minlevel="${globalLevel}" writeTo="coloredConsole, debugger" enabled="true" />
		<logger name="*" minlevel="${globalLevel}" writeTo="ownFile-web" enabled="true" />
	</rules>
</nlog>