Logging in ASP.NET

· Read in about 2 min · (349 words) ·

I’ve been trying to get decent logs on web application/web service. Its critical in cases where you dont have remote debugging access on the server.

I’ve been using Log4Net for over an year now and it’s saved me more than once. It’s the first time that I’ve tried to use it in a web scenario. There’s just a couple of things to keep in mind:

Usually the worker process runs under the ASPNET account - this doesnt have rights to logon and doesnt have an associated console. Meaning console appender is out of the reckoning.

You could use FileAppender (the usual choice on single user applications), however, as multiple requests are served simultaneously, the logs will most probably quite unreadable.

The best choice is the ADONetAppender - you log everything in the DB and then use SQL to get a trace. Here we come across the next problem - how do you get the user information for each log entry?

The solution lies in using log4net’s Mapped Diagnostic Context - MDC. Its basically a set of name value pairs that you can render using a pattern layout %X{name} in the log4net config file.

Note the lines where the insert statement has an the username parameter and the additional param tag is added to the parameter list. You’ll need to create a matching column definition in your table.

The next issue to be tackled is the log4net initialization and setting the username for the request.

The log4net system can be initialized the Application_onStart event and you can set the username in the PreRequestHandlerExecute event - this event is called just before the request is handed off for processing to the HttpModule and hence the best place to set the username. Relevant portions of Global.asax are shown below.

protected void Application_Start(Object sender, EventArgs e)
{
    ConfigureLog4Net();
    Debug.WriteLine("In Application Start");
}

private void ConfigureLog4Net()
{
    string filepath = Server.MapPath("log4net.config");
    Debug.WriteLine(filepath);
    FileInfo fs = new FileInfo(filepath);
    log4net.Config.DOMConfigurator.ConfigureAndWatch(fs);
    Debug.WriteLine("Finished Log4net configuration");
}

protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
    Debug.WriteLine("In PreRequestHandlerExecute");
    if (!LogManager.GetLoggerRepository().Configured)
    {
        Debug.WriteLine("Log4net not configured, calling configure");
        ConfigureLog4Net();
    }
    Debug.WriteLine(Context.User.Identity.Name);
    log4net.MDC.Set("user",Context.User.Identity.Name);
}