Build status NuGet Samples

Logging to from Log4net

In this tutorial we’ll add logging to from an ASP.NET MVC project through log4net. The process is identical with other project types. Create a new MVC project and install the appender:


Add the following to your AssemblyInfo.cs file:

[assembly: log4net.Config.XmlConfigurator(Watch = true)]

Add the following config section to your web.config file:

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />

Finally, add the log4net configuration element to web.config:

  <appender name="ElmahIoAppender" type=",">
    <logId value="LOG_ID" />
    <apiKey value="API_KEY" />
    <level value="Info" />
    <appender-ref ref="ElmahIoAppender" />

That’s it! log4net is now configured and log messages to Remember to replace API_KEY(Where is my API key?) and LOG_ID (Where is my log ID?) with your actual log Id. To start logging, write your usual log4net log statements:

var log = log4net.LogManager.GetLogger(typeof(HomeController));
    log.Info("Trying something");
    throw new ApplicationException();
catch (ApplicationException ex)
    log.Error("Error happening", ex);

Context Properties

log4net offers a feature called context properties. With context properties, you can log additional key/value pairs with every log message. The appender for log4net, supports context properties as well. Context properties are handled like custom properties in the UI.

Let's utilize two different hooks in log4net, to add context properties to

log4net.GlobalContext.Properties["ApplicationIdentifier"] = "MyCoolApp";
log4net.ThreadContext.Properties["ThreadId"] = Thread.CurrentThread.ManagedThreadId;

log.Info("This is a message with custom properties");

Basically, we set two custom properties on contextual classes provided by log4net. To read more about the choices in log4net, check out the log4net manual.

When looking up the log message in, we see the context properties in the Data tab. Besides the two custom variables that we set through GlobalContext and ThreadContext, we see a couple of build-in properties in log4net, both prefixed with log4net:.

Override Properties

In case you want to set one or more core properties on each message logged, you will need to add a bit of log4net magic. Examples could be, setting the User property on all log messages or setting a version number in the Version property. In the following code, we set the currently logged in username on all log messages:

Hierarchy hier = log4net.LogManager.GetRepository() as Hierarchy;
var elmahIoAppender = (ElmahIoAppender)(hier?.GetAppenders())
    .FirstOrDefault(appender => appender.Name
        .Equals("ElmahIoAppender", StringComparison.InvariantCultureIgnoreCase));

elmahIoAppender.Client.Messages.OnMessage += (sender, a) =>
    a.Message.User = Thread.CurrentPrincipal?.Identity?.Name;

This rather ugly piece of code would go into an initalization block, depending on the project type. The code starts by getting the configured appender (typically set up in web.config or log4net.config). With the appender, you can access the underlying client and subscribe to the OnMessage event. This let you trigger a small piece of code, just before sending log messages to In this case, we set the User property to the currently logged in user. Remember to call the ActiveOptions method, to make sure that the Client property is initialized.

Elmah.Io.Log4Net provides a range of reserved property names, that can be used to fill in data in the correct fields on the UI. Let's say you want to fill the User field without overriding the OnMessage event as illustrated above:

var properties = new PropertiesDictionary();
properties["user"] = "Arnold Schwarzenegger";
log.Logger.Log(new LoggingEvent(new LoggingEventData
    Level = Level.Error,
    TimeStampUtc = DateTime.UtcNow,
    Properties = properties,
    Message = "Hasta la vista, baby",

This will fill in the value Arnold Schwarzenegger in the User field, as well as add a key/value pair to the Data tab on For a reference of all possible property names, check out the property names on CreateMessage.

Specify API key and log ID in appSettings

You may prefer storing the API key and log ID in the appSettings element over having the values embedded into the appender element. This can be the case for easy config transformation, overwriting values on Azure, or similar. log4net provides a feature named pattern strings to address just that:

<?xml version="1.0" encoding="utf-8"?>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
    <add key="logId" value="LOG_ID"/>
    <add key="apiKey" value="API_KEY"/>
      <level value="ALL" />
      <appender-ref ref="ElmahIoAppender" />
    <appender name="ElmahIoAppender" type=",">
      <logId type="log4net.Util.PatternString" value="%appSetting{logId}" />
      <apiKey type="log4net.Util.PatternString" value="%appSetting{apiKey}" />

The logId and apiKey elements underneath the appender have been extended to include type="log4net.Util.PatternString". This allows for complex patterns in the value attribute. In this example, I reference an app setting from its name, by adding a value of %appSetting{logId} where logId is a reference to the app setting key specified above.

This article was brought to you by the team. is the best error management system for .NET web applications. We monitor your website, alert you when errors start happening and help you fix errors fast.

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