Introduction
With the release of ASP.NET 2.0 comes a powerful new diagnostics framework located under the System.Web.Management
namespace. The intention of this new framework is to eliminate the need to use external logging libraries such as log4net. This article is not meant to be an overview of the new features available in ASP.NET but as a means to use the events provided by this system in combination with log4net. However, for a great overview of the System.Web.Management
namespace, I would urge you to read the Diagnostics chapter in Essential ASP.NET 2.0 by Fritz Onion and Keith Brown.
Because the System.Web.Management
system is intertwined within the core ASP.NET framework, there are some pretty important events provided that used to require jumping through hoops to obtain in the past. For instance, logging when and why an application shutdown used to mean you had to hook into the Global.asax and use Reflection to pull the correct properties (see this overview on Scott Gu’s blog for more information). However, with the new ASP.NET infrastructure, these messages are provided automatically, and it only takes setting up the right provider to begin receiving them.
This is all great, but the question that I encountered was what if you had an existing application that already has a large log4net infrastructure in place? Or, what if you wanted to use some of the appenders that comes with the log4net framework (such as the RollingFileAppender
) which are not provided with the new ASP.NET infrastructure? These questions lead me to the point of this article: how to send messages from the ASP.NET Management framework to log4net without having to write any code.
Usage
Like most of the new features in ASP.NET 2.0, the health monitoring framework relies on the extensible Provider model. By utilizing this, we are able to essentially forward messages from ASP.NET to log4net. In other words, capturing all the internal ASP.NET web events in log4net is as simple as adding a reference to the provider included in the download.
An example configuration is shown below:
<healthMonitoring enabled="true">
<providers>
<add name="Log4NetProvider"
type="HealthMonitoring.Log4NetBufferedWebEventProvider"
bufferMode="Critical Notification"
loggerName="MyLog"
level="Debug"
/>
</providers>
<rules>
<add name="MyCustomRule"
eventName="All Events"
provider="Log4NetProvider"
minInterval="00:00:01" minInstances="1"
maxLimit="Infinite"
/>
</rules>
</healthMonitoring>
As you can see, we are simply adding a new health monitoring provider and creating a new rule to apply to that provider. With this in place, the ASP.NET web events automatically begin logging to whatever log you specify. One thing to keep in mind is, the provider assumes log4net has already been been configured and does not explicitly perform the configuration.
Below is an example message that is now logged to my log4net log when the application shuts down:
12/20/2006 11:45:49,154 DEBUG MyLog [%user name%,beyg2355kdautd55lcwkmb45] - Event code: 1002
Event message: Application is shutting down. Reason: Configuration changed.
Event time: 12/20/2006 11:45:49 AM
Event time (UTC): 12/20/2006 5:45:49 PM
Event ID: 6b81587fc7ee4a4bb78d719402456438
Event sequence: 9
Event occurrence: 1
Event detail code: 50004
Application information:
Application domain: 91d3505d-1-128111103113256826
Trust level: Full
Application Virtual Path: /
Application Path: F:\Projects\Web\HealthMonitoring\HealthMonitoring\
Machine name: %machine name%
Process information:
Process ID: 5664
Process name: WebDev.WebServer.exe
Account name: %user name%
Further Usage
Besides simply using the included provider to capture all the built-in ASP.NET web events, this provider will also allow you to create your own web events and even customize how they are logged in log4net. This is done by using the provided ILoggerEvent
interface shown below:
interface ILoggerEvent
{
Level Level
{
get;
set;
}
string LogName
{
get;
set;
}
}
By creating your event and implementing the above interface, you can specify at what level and which log the event is to be logged. An example implementation is provided in the code download called LoggerWebRequestEvent
. As shown below, this event can specify a different log and level than what was specified in the provider configuration settings.
12/20/2006 11:45:14,575 ERROR DifferntLog
[%user name%,beyg2355kdautd55lcwkmb45] - Event code: 150000
Event message: i cannot be less than zero and is currently -1
Event time: 12/20/2006 11:45:13 AM
Event time (UTC): 12/20/2006 5:45:13 PM
Event ID: 213c7c5f04084c8898324f9bff7b9808
Event sequence: 8
Event occurrence: 1
Event detail code: 0
Application information:
Application domain: 91d3505d-1-128111103113256826
Trust level: Full
Application Virtual Path: /
Application Path: F:\Projects\Web\HealthMonitoring\HealthMonitoring\
Machine name: %machine name%
Process information:
Process ID: 5664
Process name: WebDev.WebServer.exe
Account name: %user name%
Request information:
Request URL: %request url%
Request path: /Default.aspx
User host address: 127.0.0.1
User: %user name%
Is authenticated: True
Authentication Type: NTLM
Thread account name: %user name%
Custom event details:
By creating custom web events, you can begin moving in the direction of using the provided logging infrastructure without having to make the change overnight.
Conclusion
As more and more providers are created for the ASP.NET Management framework, I think the need to utilize third party frameworks will decrease. However, with existing applications and libraries, this provider bridges the gap, allowing log4net users to get the messages that are already provided internal to the ASP.NET 2.0 framework with minimal work.