.NET Logging Tools and Libraries

Welcome to the definitive guide to .NET logging. Here you will find updated information about how to add logging to your .NET applications. This guide is brought to you by the nice people at elmah.io.

Introduction

Before we dig into the large number of logging frameworks, let's spend a bit of time discussing the terms related to logging. Logging as a single term, means storing messages from your application somewhere. These messages are often used for debugging errors, but I've seen log data used for multiple other purposes like creating a dashboard, monitoring updates, audit trails etc. The nice thing about logging is, that you're in control if a message should go into the log or not.

As mentioned, most people use logging frameworks for logging exceptions and other messages making it possible to debug errors in production. All of the frameworks mentioned in this post support error logging, while few actually build error management features on top of the log. Error management actually helps you monitor and deal with your errors in a more intelligent way than having to look through log files. More on that subject later.

Frameworks

We've compiled a list of logging frameworks for .NET. There's a great deal of options out there, but a lot of them are no longer maintained. The list provided in this section contains the popular choices.

log4net

Probably the oldest logging framework on the block, log4net have existed pretty much since .NET was introduced. log4net was originally an internal Apache log4j port developed by Neoworks Limited back in 2001. The project quickly moved to Sourceforge (the GitHub of 2001) and was released under the Apache license. Since that time, log4net has been one of the most popular choices in the .NET world for adding logging to applications.

log4net works with the concept of appenders, where log messages can be routed to different data stores. A lot of appenders have been implemented during the years, like logging to the file system, SQL Server, HTTP endpoints and even NoSQL databases. Being unstructured text messages, log4net and NoSQL don’t exactly go hand in hand.

NLog

While log4net quickly became the default choice, alternatives began to show up. Probably the first real competitor to log4net's dominance were NLog. Originally developed by Jarek Kowalski and with pull requests from almost 100 people, NLog is a great alternative. While log4net pretty much stood still from 2006, NLog just kept going. While Jarek seemed to pull the plug when starting at Google, the community seemed to step up and new releases are still flowing. Like log4net, NLog contains multiple log targets, and is able to log messages to various data stores.

For a comparison between log4net and NLog, check out NLog vs log4net.

Serilog

In 2013, the .NET logging framework were taken by storm once again. When everyone else were logging text messages, Nicholas Blumhardt did something new: structured logging. Unlike existing logging frameworks, Serilog introduced .NET developers to structured event data rather than dumb text messages. Serilog quickly became one of the fastest moving projects in the .NET community and still is. We really recommend you to look into Serilog for logging messages from your .NET apps.

If you are looking for a comparison between logging frameworks, check out nlog vs log4net vs Serilog

Microsoft.Extensions.Logging

As part of ASP.NET Core, Microsoft released a new logging framework called Microsoft.Extensions.Logging. This new logging framework is available for not only web applications, but everything running on the .NET framework basically. Microsoft.Extensions.Logging collects a lot of experiences from both open source logging frameworks as well as Microsofts previous attemts (like Logging Application Block). In fact Microsoft.Extensions.Logging is open source and available on GitHub beneath the aspnet organization.

Best Practices

In this chapter we have collected a range of best practices. For now, details about .NET web applications are available only. If people show interest in listing best practices for other types of applications, we'll consider writing it.

Web Applications

Implementing web applications is one of the most commenly seen use cases for .NET. Here's a list of best practices to bear in mind when creating your next .NET website or API.

Use ELMAH

Error logging module and handlers for ASP.NET (ELMAH), the de-facto standard error component for .NET. ELMAH has existed for almost a decade but still works as wonderful as when it was initially released. The idea behind ELMAH is to log all uncaught exceptions including a lot of contextual information about the current HTTP context. ELMAH comes with a simple UI which shows you a list of errors happening and when, as well as some additional information like the type of error, the user causing the error and more.

Since the ELMAH UI is available on /elmah.axd, make sure to either disallow remote access to this URL or configure ASP.NET authorization rules to only let people inside the circle of trust to access your error logs. Check out ELMAH security and allowRemoteAccess explained for details.

You can click each error and check out information about the server variables, cookies and other pieces of information, important to debug each error. ELMAH may not be the most hyped logging framework out there, but it works and it works great. We wouldn't implement a website without it.

An important note about ELMAH is to use the contrib package, matching the web framework you're using. If you develop an ASP.NET MVC application, use the Elmah.Mvc package. If you develop a Nancy application, use the Nancy.Elmah package etc.

To start using ELMAH, check out our ELMAH Tutorial. If you are unsure about the difference between ELMAH and a logging framework, check out this ELMAH vs log4net post.

Use structured logging

ELMAH only logs errors, why you probably need another logging framework to log other types of log messages like debug, information and warning messages. In theory, you could use ELMAH for other types of messages, but other logging frameworks are better suited for that need. Everyone knows log4net and NLog, but the logging framework we would like to highlight is Serilog. Serilog is a newer framework and therefore uses some of the more recent ideas behind logging as well as new libraries in .NET.

The idea behind Serilog is that your log messages are semantic/structured, which means that Serilog actually understands pieces of information inside your log message. Where a typical log message in log4net or NLog would look like this:

Executed /getuser in 15 ms

an equivalent log message in Serilog would look like this:

Executed {Url} in {Elapsed} ms

You would then append the actual values of Url and Elapsed when logging the message to Serilog. What looks to be a simple string replace, is actually as very strong feature, where log messages suddently embeds vital and searchable information.

Serilog implement the idea of destructoring by allowing you to log complex types to your log destinations. In theory, having the flexibility to log every .NET object seems like an awesome option. In the real world you should be very careful when logging complex objects with deep graph of references.

Using Serilog with a text file or relational database can be fine for testing purposes. If you want the full potential from Serilog, you need to log into a schemaless datastore like Elasticsearch, elmah.io or similar.

When logging very complex objects to schemaless data stores like Elasticsearch, your mapping quickly becomes cluttered and performs poorly.

To start using Serilog, browse through the Serilog wiki. Also make sure to check out our Serilog sink for logging to elmah.io from Serilog.

Custom error pages

Depending on how you setup your custom error pages, ELMAH and other logging frameworks may stop working. If your custom error pages actually catches the error and continues like no error happened, logging frameworks may never get notified about something bad happening.

A good rule of thumb is to configure custom error pages as close to the IIS as possible. The closer you get to the actual ASP.NET pipeline, the more likely your error logging falls apart.

There are a lot of outdated tutorials on custom error pages out there. Read through Web.config customErrors element with ASP.NET explained and Demystifying ASP.NET MVC 5 Error Pages and Error Logging to learn everything about how to configure custom errors.

Error Management

We wanted to put some words on the terms Error Management. We often talk to people that don't realize, that there's a big difference between Error Logging and Error Management. While log4net, NLog and Serilog are great choices for logging text-based or structured log messages to a text file or a database, this is simply not enough to monitor your websites and act on errors. Having a log file is one thing. Even with cool storage choices like Seq and Elasticsearch, having a system for monitoring and handling errors is an essential part of web application development today.

A lot of choices showed up during the last few years. elmah.io, New Relic, Raygun and Stackify are all examples of popular choices for implementing error management. All run in the Cloud and provides easy integration with your .NET websites. When looking through the different solutions, some basic features work pretty much the same way, while others vary by product. Some focus on supporting a lot of different programming languages, others on integrating with logging frameworks and some on integrating with third party systems like Slack and GitHub.

At elmah.io, we are working hard to create the best error management system for .NET web applications. We support all the major logging frameworks and tools for .NET like ELMAH, log4net, NLog and Serilog. We also provide some unique features for .NET developers like Visual Studio integration and one-click installation through NuGet. We definitely want you to try out elmah.io for your error management needs in .NET.

Visit our sponsor: