Category Archives: Logging

Logging with NLog

Logging is an absolute must-have feature, which is too convenient and easy to not do it. When I start a new project it is something I will pretty much do on the first days because it brings immediate advantages:

  • for debugging
  • for commenting / understanding code
  • you have an actual document to discuss over with other departments


NLog is a flexible and free logging platform for various .NET platforms, including .NET standard. NLog makes it easy to write to several targets. (database, file, console) and change the logging configuration on-the-fly.

And also very important NLog is licensed under the BSD 3-Clause, which means you can use it for free for private and commercial use on the condition that you write its copyright notice in your documentation. See

In order to log with NLog you will need the following:

  1. NLog binaries
  2. Configuration file
  3. Call to the dll in source Code


NLog Binaries

You can either add NLog over Nugget in your Visual Studio project or add a specific version of the nlog.dll in your binaries.


Configuration file

I like to have an external dedicated file for it, I usually call it nlog.config and store it with the binaries. Remember to configure File Properties: Copy If newer

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns=""

    <target name="logfile"
            layout="${longdate} ${uppercase:${level}} ${message}" />
    <target name="logconsole"
            layout="${longdate} ${uppercase:${level}} ${message}" />
    <target name="logfileNamespace"
            layout="${longdate} ${uppercase:${level}} ${message}" />

    <logger name="*" minlevel="Info" writeTo="logconsole" />
    <logger name="*" minlevel="Info" writeTo="logfile" />
    <logger name="Company.Department.Product.Namespace" minlevel="Trace" writeTo="logfileNamespace" />


In order to use NLog you will need to define a Log object first, this should be done in every class where you want to log. and is done with

private static readonly NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger();

Then you will be able to call the following functions:

  • Trace() very high volume of detailed Information, used for developping
  • Debug() more than the default level of Information, used for debugging
  • Info() default level of information, typically used in the field, used for retracing program activity
  • Warn() warnings, these are expected problems that are handled by the program
  • Error() errors, these are somehow expected but the described function/feature cannot continue/fulfill its normal operation
  • Fatal() fatal error, unexpected serious error, it makes no sense to continue program execution
namespace ConsoleApp1
    public class Program
        private static readonly NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger();

        public static void Main(string[] args)
            Log.Info("### Starting Program ###");
            Log.Info($"Version: {System.Reflection.Assembly.GetExecutingAssembly().GetName().Version}");
            Log.Info($"Date: {System.DateTime.Now}");
            Log.Info($"OS Description: {System.Runtime.InteropServices.RuntimeInformation.OSDescription}");
            Log.Info($"OS Architecture: {System.Runtime.InteropServices.RuntimeInformation.OSArchitecture}");
2020-04-07 22:25:10.8128 INFO ### Starting Program ###
2020-04-07 22:25:10.8592 INFO Version:
2020-04-07 22:25:10.8592 INFO Date: 07.04.2020 22:25:10
2020-04-07 22:25:10.8592 INFO OS Description: Microsoft Windows 10.0.18363
2020-04-07 22:25:10.8592 INFO OS Architecture: X64