DEV Community

Cover image for Serilog vs NLog

Serilog vs NLog

thomasardal profile image Thomas Ardal Originally published at ・5 min read

Serilog is often referred to as the new logging framework on the .NET platform, while NLog is considered "the old one" (together with log4net). With Serilog introduced back in 2013 and NLog in 2006, they both have a long history and a great community around them. I have worked with both logging frameworks and in this post, I will try to give you an overview of each framework, the differences, and some recommendations to look for when choosing a logging framework.

Let's start with a bit of information about each framework.


Serilog was initially created by Nicholas Blumhardt back in 2013. When it came out, it sort of revolutionized the .NET logging space by introducing structured logging. All previous frameworks more or less treated log messages as concatenated strings. With more NoSQL databases like MongoDB and Elasticsearch beginning to pop up, the community was in need of something able to utilize the new features and ways of structure data that came a long the NoSQL-movement.

Over the years, Serilog is, without a doubt, the .NET logging framework that has grown the fastest. New commits are happening daily and there is a large community around the framework.


NLog has a similar story to Serilog. Back in 2006, log4net was the dominant framework and no real alternatives existed. NLog changed that with a cleaner API and better ways of configuring what to log where. I remember back in 2007 when I first heard about NLog. I have a background in Java (feels so dirty, I know!) and was using the log4j framework, which log4net was heavily inspired by. NLog was the first framework that really started using .NET features and not just another Java to .NET migration.

Over the years, NLog also developed a lot. I must admit that I gave up following and using the framework a few years back and I expected the project to die. But, as it turns out, I was wrong and the framework is as strong as ever with recent additions like support for structured logging.


To start looking into similarities and differences, let us dive into the first part you will need to start logging: configuration.


One of the nice features about Serilog is its strongly typed (written in C#) configuration language. While XML configuration is also supported, I don't see much benefit in using it. This is a very simple example of how to configure Serilog to write log messages to a file:

Log.Logger = new LoggerConfiguration()
    .WriteTo.File("log-.txt", rollingInterval: RollingInterval.Day)

The configuration is built using the LoggerConfiguration class and by calling one or more WriteTo.* methods. Most logging frameworks refer to logging destinations as appenders or targets. In Serilog, this is simply named "Sink". Finally, I call CreateLogger and set the output on the static property Log.Logger. This enables easy access to logging as we will see in a following section of this post.


Like Serilog, NLog can use both XML and C# based configuration. Here is an example of writing log messages to a file:

    <target xsi:type="File" name="file" fileName="log-file.log"
            layout="${longdate} ${level} ${message}" />

    <logger name="*" minlevel="Trace" writeTo="file" />

And a similar example in C#:

var config = new NLog.Config.LoggingConfiguration();
var logfile = new NLog.Targets.FileTarget("logfile") { FileName = "log-file.log" };
config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile);
NLog.LogManager.Configuration = config;

It's my impression that most people still use XML, but it wouldn't be a fair comparison to Serilog without an example in C# as well.

Logging Messages

The next step is to start logging some messages. Let's look at how it is done in each framework.


Remember the static property from above? Logging from Serilog is dead easy:

Log.Information("Hello World");

Using the static Log class, you will always have easy access to logging. If you don't like static calls, you can use dependency injection to inject Serilog's ILogger as well. The great thing about using the static class is that it will never fail with internal null reference exceptions. Other logging frameworks require you to set up logging in your unit tests.

Logging structured log messages is using a special syntax:

Log.Information("Hello World from {FirstName}", "Thomas");

Notice how the string includes the {FirstName} variable. Serilog will automatically replace this with the value Thomas when writing the log message to the configured store. When logging to a file, you may not see the benefit of including variable names inside the log message. But when logging messages to a database, each sink typically both write the generated log messages as well as individual variable keys and values. For example, when logging to Elasticsearch, you can search log messages like this:


This queries all log messages with the FirstName of Thomas. Pretty clever.


NLog logging works pretty much like Serilog:

var logger = NLog.LogManager.GetCurrentClassLogger();
logger.Info("Hello World");

Since version NLog 4.5, structured logging is supported as well:

logger.Info("Hello World from {FirstName}", "Thomas");

The output is identical to that of Serilog. The FirstName variable is replaced with the value Thomas. Depending on which target you have configured, NLog will store at least the generated message, but in most cases, also individual variable keys and names.

Sinks and Targets

The days where you would write log messages to the console or a file are pretty much over. In order to store, query, and create notifications on your log messages, you need some kind of store. This can be a cloud-based store like (we support both Serilog and NLog) or a local store like SQL Server or Elasticsearch. Both logging frameworks have support for a lot of different data stores.

As of the writing of this post, Serilog has 81 available sinks and NLog has 82. When comparing the two, the number of sinks isn't really important, but it's a good indicator of a popular and well-supported framework.

When evaluating logging frameworks, pick a framework that supports the logging destination you are looking into using. In the cases of Serilog and NLog which both support a lot of stores, try out each framework and evaluate what works best. In my experience, there is a huge difference in the way sinks and targets are implemented.


Picking between Serilog and NLog is hard since both have a lot of features like structured logging and C# based configuration. We are using Serilog on since we are logging to both and Elasticsearch. Both sinks work great and are actively maintained. While NLog also offers structured logging, it's easy to see that Serilog has had this feature longer. If I were to choose a logging framework today, I would go with Serilog.

With that said, I don't have anything bad to say about NLog. If you are already using NLog, I'm not sure that there would be enough benefits of switching to Serilog. Most of the features in Serilog are available in some form or another in NLog. As always, I recommend that you try both and pick the one you like the most. Serilog has some new concepts that may be harder to understand if you are migrating from log4net.



  • Widely adopted
  • A lot of documentation
  • Great community


  • A bit harder to learn when coming from log4net



  • A lot of documentation
  • Having been around a long time, there are lots of blog posts
  • Easy to get started when coming from other logging frameworks


  • Structured logging is still a bit behind Serilog
  • C#-based API is harder to use than Serilog's fluent API

Would your users appreciate fewer errors? is the easy error logging and uptime monitoring service for .NET. Take back control of your errors with support for all .NET web and logging frameworks.

➡️ Error Monitoring for .NET Web Applications ⬅️

This article first appeared on the blog at


Editor guide
joro550 profile image
Mark Davies

I remember first hearing about Serilog back in 2016 (i think) it sounded like an amazing idea, at the time I was using Log4Net which let's face it was a .Net implementation of a Java library, and as you say it treated logs as just a concatonated string which made it almost impossible to parse, I have no experience of NLog, but I'll check it out, thanks for thie blog post!