LoggingThe Ultimate Guide

your open-source resource for understanding, analyzing, and troubleshooting system logs

curated byloggly


.NET Logging Libraries

Microsoft provides you with an excellent source for logging errors into the Event Viewer, but it’s sometimes too difficult to analyze issues when using the default library source. Let’s say you have 10 web servers hosting a web application. If you write errors to each server’s Event Viewer, it can be extremely time-consuming to find out which server is having issues. In many cases, one server could have a hardware issue or synchronization between software versions isn’t executed properly.

If you write to the Event Viewer, administrators need to go back into each web server and review individual Event Viewer information. This can get tedious for large web farm administrators. The option is to log errors to files. If you wanted to write logs to files, you’d need to create your own layer that logs errors to a specific repository. Instead of relying on file I/O classes, you can incorporate a free logging library. These logging libraries support multiple outputs like syslog and HTTP, and can show you the time the event happened, the type of error (DEBUG vs. ERROR vs. WARNING), the exception message, and the location of the error. You can even log to a central location off the production server to reduce overhead, improve security, and aggregate all your logs in one place (or feeding them to a dedicated log management solution) to allow for cohesive analytics and central archiving. There are several available on the market, but only a few are considered reliable and truly convenient for the coder.

In this section, we’ll cover three common logging libraries that make logging .NET information much more convenient. You could write your own library, but this would take up hours of your time for something that is already created for you. The only reason you would need a custom logging layer would be if you have some very specific business requirements that need it.

We mention some of the common libraries excluding the Microsoft Enterprise Library that you can download from NuGet. We benchmarked the Enterprise Library along with others and found that Enterprise was much slower and more difficult to use than the libraries we mention here. You can decide for yourself which logging libraries to use, but the following ones we discuss are the most convenient to get started.


Log4net is one of the most common external logging services available to .NET coders. The developers for log4net promise that you can have logging integrated with your application within minutes, and it’s true—setup is easy.

Log4net is available in NuGet, so it’s just as easy to install as it is to code. Open NuGet Packages in Visual Studio, type “log4net” in the search bar and select the package. Click “Install” and NuGet installs the appropriate DLLs into your project.

The following code is an example of logging an error in log4net.

In the code above, we declare the log4net variable as a static private variable that the entire class can access. We could declare it in the Index method, but then it would be local and we’d have to declare a variable in every method. You want to perform logging in every method to ensure that each part of your code traps errors.

The above code logs to a log4net file, but it doesn’t do you any good to just log an error without an actual error triggering. We can incorporate the log4net code with the error trapping that we discussed in the .NET Logging Basics section.

If you recall from the Event Viewer code, the above example greatly reduces the amount of code you need to create compared to using the Event Viewer. Of course, you’d want to get more detailed in your logged error. The above code just adds “Event Test” to the log file. You can get as detailed as needed. For instance, you could write the server name, application name, time of the event, and the error message. By identifying the server in your log files, administrators and developers know exactly which server is causing the error. Typically, you would define these variables in your web.config or app.config file.

Each exception class has its own properties that you can use to print direct errors triggered from your code. When you print full reports of your errors, just remember that it can be more difficult to parse and read especially when you have several servers to review. You want to log the right amount of information, but too much can make the logs too difficult to use when analyzing for root cause issues.


NLog is just as easy–if not easier–as log4net. In most .NET teams, the two main choices for external libraries are NLog and log4net. This section will cover getting started with NLog. NLog is also available from NuGet. From the NuGet console, type the following to install the package to your solution:

Install-Package NLog.Config

Just like log4net, you can create a static global class variable for the NLog logger. This means you don’t need to create a new variable for each of your class methods if you choose to create your log variables at the class level.

With the logger NLog class variable defined, you can now write content to the log. As discussed in the log4net section, you probably will want to put NLog logging events in a try-catch block. The following code moves the event into a try-catch block:



The final logging framework we’ll cover is NSpring. While not as popular as log4net and NLog, NSpring is just as easy to use and works with the same style of code—you create a class variable and then log errors to a file.

Let’s take a look at the basic code for NSpring.

With NSpring, you need a bit more to get the logging started. First, you need to specify the log file location and format. You then need to use the Open method to open the file and prepare it for logging. After you’re finished logging, you then close the file using the Close method. The steps are not unlike opening and closing a file on the user’s hard drive.

Notice that the Log method takes the error level as an argument. This is also different than the previous two frameworks that offered specific methods for each exception level.

Of course, you can add an event using try-catch to trap the errors.

As you can see, third-party logging apps are much more convenient than working with custom frameworks. Note that in this example, we assume that instantiation of the class is performed in the method. However, the best way to declare the logger variable would be through dependency injection by passing it to the constructor of the class. They are even more convenient than working with the Event Viewer. What makes these logs even more useful is that you can aggregate them in one location to provide better analysis for your administrators.

Written & Contributed by


This guide will help software developers and system administrators become experts at using logs to better run their systems. This is a vendor-neutral, community effort featuring examples from a variety of solutions

Meet Our Contributors Become a contributor