Serilog vs log4net - A battle between the old and the new
Tags: dotnet, csharp, serilog, log4net
Published: 2019-04-29 12:12:08

---
title: Serilog vs log4net - A battle between the old and the new
published: true
description: Serilog and log4net are popular choices when choosing a logging framework in .NET. Read this guide to learn all about each framework and what to pick.
cover_image: https://thepracticaldev.s3.amazonaws.com/i/sx2z66m3hrnq8j5fwdfz.png
tags: dotnet, csharp, serilog, log4net
canonical_url: https://blog.elmah.io/serilog-vs-log4net/
---

Serilog and log4net are two very popular choices for logging messages from .NET applications. In this post I'll show you how to configure and use each frameworkm as well as list the advantages and disadvantages of each framework. I even dare recommending you use one of the frameworks :)

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

## Serilog

Launched in 2013, Serilog is one of the newest logging frameworks. This definitely isn't a bad thing, since the framework uses some of the newer and more advanced features of .NET. Structured logging probably being the most noticeable, but also the concept of enrichment is what makes Serilog unique compared to a lot of other logging frameworks.

Serilog is constantly growing and new log targets are being launched every month. There is a large community around Serilog. Compared to other frameworks, the people involved are genuinely nice and want to help out.

## log4net

log4net is the old boy on the team of .NET logging frameworks. Originally launched as a port of log4j, it has evolved into a unique product run by the Apache Foundation. You will find a lot of existing projects out there that use log4net for their logging needs. With the latest release back in 2017, development of the main framework pretty much stood still during the last years. New appenders are being developed though, and log4net actually has pretty decent support for modern NoSQL databases as well.

## Configuration

Both log4net and Serilog need configuration to start logging. Let's dive into each framework to see how easy configuration is.

### Serilog

Serilog supports both XML and C# based configuration. I've never actually heard of anyone using the XML approach, so that's why the rest of this section will show configuration code written in C#. Being able to configure Serilog in a strongly typed language is a great benefit.

To configure simple logging to a file we write configuration code like this:

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

The `LoggerConfiguration` class is the key part of configuring and creating the Serilog `ILogger` object. In Serilog, log destinations are called Sinks and are added using extension methods on the `WriteTo` property. In the example above, I tell Serilog to log messages to a rolling file. Finally, I call the `CreateLogger` method and set the output on the static `Logger` property on the `Log` class. This ensures easy access to the `ILogger` object from your program.

### log4net

Like Serilog, log4net can be configured in both XML and C#. The C# approach is clearly something that was added later and is not really intuitive (IMO). Since most of the examples you will find online are in XML, I will use that for the rest of the examples in this post.

log4net configuration is added through either `app.config` or a dedicated `log4net.config` file:

```xml
<log4net>
  <appender name="FileAppender" type="log4net.Appender.FileAppender">
    <file value="log-file.txt" />
    <appendToFile value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date %level %message%newline" />
    </layout>
  </appender>
 
  <root>
    <level value="ALL" />
    <appender-ref ref="FileAppender" />
  </root>
</log4net>
```

Notice how the file appender has its own named `appender` element, which is then referenced inside the `root` element in the `appender-ref` sub-element.

To make the configuration visible for the rest of your program, add a bit of code somewhere (like in `AssemblyInfo.cs`):

```csharp
[assembly: log4net.Config.XmlConfigurator(Watch=false)]
```

As mentioned earlier, configuration isn't really log4net's strong side. Luckily, there is some pretty good documentation and because of its long history, a lot of examples and blog posts online.

## Sinks and Appenders

Unless you want to store everything in /dev/zero, you need some way of storing your log messages. Both examples above, showed how to store log messages to a file. Serilog has the concept of Sinks and log4net has appenders. They both cover the same need, just with different naming.

Sinks and appenders are available for a lot of different destinations like files, databases, and remote services. As an example, elmah.io provides both a sink for Serilog and an appender for log4net. They both do the same, store all messages logged through each framework to elmah.io. Both logging frameworks have sinks and appenders for the most common storage options. The quality of each implementation highly varies, which is why I would recommend you try out each sink/appender and see if it covers your needs.

## Logging Messages

Why configure a logging framework if you don't want to log any messages? Let's do something about that.

### Serilog

Logging in Serilog is dead simple:

```csharp
Log.Information("Hello World");
```

Remember how we initialized the `Log` class in a previous section? Well, here we really see the benefit. The `Log` class has overloads for all available log levels through Serilog. In this example, I log an information message.

A great benefit of Serilog is the feature of structured logging:

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

Rather than using a normal string concatenation, I tell Serilog to replace `{FirstName}` with `Thomas`. This produces a nice log messages, as well as tells Serilog to remember the `FirstName` key and its value. This can be used to log structured data in a service like elmah.io or in NoSQL databases like MongoDB or Elasticsearch.

This isn't a guide to structured logging with Serilog. If you don't know the concept, check out [Structured Data](https://github.com/serilog/serilog/wiki/Structured-Data) on the Serilog wiki. You are in for a treat!

### log4net

Logging through log4net is a bit more complex than Serilog, but it still does the job:

```csharp
var log = LogManager.GetLogger(typeof(Bar));
log.Info("Hello World");
```

The main difference is the need for the `LogManager`. You typically get a reference to the logger one time per class and re-use the same log instance.

log4net doesn't support the concept of structured logging. Like shown in the `conversionPattern` element in the XML configuration, you have some variables to play with when writing to the storage. But including properties like `FirstName` in the Serilog example isn't available.

## Conclusion

I don't really like to pick on log4net since it has served as a great (and default) logging choice for me for the past decade. But in the end, Serilog is superior in most ways. Structured logging, enrichments (I didn't even show you those, but check out the Serilog documentation for examples) and C# based configuration are all winners.

In most cases I wouldn't recommend you to replace the logging framework on legacy systems, but in this case, I definitely see some benefits of jumping from log4net to Serilog.

### Serilog

*Advantages*

* Structured logging and enrichment
* Great documentation and community
* C# based configuration

*Disadvantages*

* More features to learn

### log4net

*Advantages*

* A lot of documentation and blog posts
* Easy to understand when coming from logging frameworks from other languages

*Disadvantages*

* No structured logging
* Hard to configure
* Project seems dead

## Would your users appreciate fewer errors?

elmah.io 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](https://elmah.io/?utm_source=devto&utm_medium=social&utm_campaign=devtoposts) ⬅️

This article first appeared on the elmah.io blog at https://blog.elmah.io/serilog-vs-log4net/