ASP.NET Error Logging Best Practices

Adding error logging to an ASP.NET application can be quite the challenge. A lot of different tools and frameworks are available. Everyone probably know log4net, but a lot happened since the first .NET logging frameworks where conceived. This post will show you the best practices which will provide you with vital information about errors happening on your website.


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.

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.

Would your users appreciate fewer errors?

➡️ Reduce errors by 90% with error logging and uptime monitoring ⬅️


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, 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 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's a lot of outdated tutorials on custom error pages out there. For the ultimate guides, read Web.config customErrors element with ASP.NET explained and Demystifying ASP.NET MVC 5 Error Pages and Error Logging.

Use cloud-logging

The days where you would store error logs in files, spread across servers, are long gone. With a cloud-based logging service, you will get every single error from all web apps and services logged to a central service. Every exception is enriched with detailed information about the HTTP context at the time of logging the error. This will improve your productivity to a level you didn't think was possible, back when you were searching through gigabytes of text files with Notepad (we've all been there). is a good choice when looking for a cloud-based error monitoring service for .NET. We have integration for all .NET logging- and web-frameworks. All of your errors are indexed and made searchable using powerful full-text search. Integrations with popular tools like Slack and Microsoft Teams, ensure notifications to your team as soon as errors start happening. Stop relying on your customers to report errors and sign up for a free trial at Overview Error logging and Uptime Monitoring for your web apps

This blog post is brought to you by is error logging, uptime monitoring, deployment tracking, and service heartbeats for your .NET and JavaScript applications. Stop relying on your users to notify you when something is wrong or dig through hundreds of megabytes of log files spread across servers. With, we store all of your log messages, notify you through popular channels like email, Slack, and Microsoft Teams, and help you fix errors fast.

See how we can help you monitor your website for crashes Monitor your website