Please note that this is the worst UI I've ever designed, but it's just enough for testing the functionality
<!------------------------------- STEP 3 ---------------------------><!-- Add the article text. Please use simple formatting (
The LOG4NET (or "log4net"? I don't know what casing is correct) logging framework is a set of classes for logging text messages from within a .NET application to various target locations. Usually this is done for debugging or tracing purposes.
These target locations can be locations like e.g. log files, SMTP or databases and are filled through what LOG4NET calls "Appenders". The appender architecture is configurable through configuration files and is rather extensible.
This article describes an appender that logs to a web service. The appender will be called
The download includes the actual appender class as well as the web service backend to receive the logging requests and dispatch them further.
The project introduced here makes use of my own LOG4NET wrapper which is included in my set of base libraries "ZetaLibNet".
So if you want to just use the
WebServiceAppender in you own project, simply copy the sample files to your solution and include them in your application structure.
If you want to get the maximum flexibiliy and minimum code size, I recommend that you get rid of my ZetaLibNet bindings. This is definitely possible and probably rather easy. I did not do it, simply because I'm lazy and because I do not have any requirements to do so.
The download consists of a Visual Studio .NET 2005 solution with three projects: "Runtime", "TestClient" and "Web".
- "Runtime" - This is the actual library that contains the
WebServiceAppender that logs to the web service. Since my example binds declaratively to the
WebServiceAppender (through the "app.config" file of the "TestClient" project), I included a class "ForceLoad" which must be instantiated inside the "TestClient" project to force the linker to still bind to the "Runtime" project, even there is no compile-time binding to the library.
- "TestClient" - A Windows Forms application that logs messages with the
- "Web" - A web project that contains the actual web service that receives the logging messages. It simply forwards the logged messages to the LOG4NET framework that is running on the server. Here, only the minimum functionality is implemented to give you an idea. I think there are much more advanced things you can do with the received messages. Be creative and please tell me!
Configuring the WebServiceAppender
Like every LOG4NET appender, you can configure this appender programmatically or declaratively. I've chosen the latter in my example.
Here is an example appender configuration with all available properties:
<appender name="WebServiceAppender" type="Zeta.WebServiceAppender">
<!-- LOG4NET parameters. -->
<param name="LevelMin" value="DEBUG"/>
<param name="LevelMax" value="FATAL"/>
See the "app.config" of the "TestClient" in the example downloadable project for details.
Behind the Scenes
The code, as always, is not much rocket science, but mainly some hard and/or boring work. I based much of my work on the skeleton provided by this guy (on the interesting L4N Dashboard website) and the examples in the LOG4NET SDK.
The web service call is done asynchronously in order to not block the caller when logging.
I provide a basic mechanism for ensuring that only allowed clients to log to the web service by accepting an API key. Usually an API key is a GUID (string) that you as the web service hoster supply to the clients that are allowed to log. The web service then checks whether you are allowed to log by checking the API key that must be sent with every logging request.
This short article shows you a short and hopefully practical way of enhancing the great LOG4NET logging framework to log to a web service. I wrote the classes and the article itself solely because I found no ready-to-use solutions on the web (I only found one similar article but for LOG4J only) and I think it is a great idea for applications to log to a remote location.. Hopefully I did a small step to fill this gap.
Please use and enhance the code just as you like. I'm more than glad if you write comments, suggestions, bugs and enhancements in the comment section below. Thank you!
- 2006-12-27: First version created and uploaded.