When developing all kind of projects a good strategy for logging can save you a lot of time and frustration. Personally I am very found of using Apache log4net and this post will describe the most important features in log4net and how to implement and use this in a .Net Compact Framework project.
log4net can be configured with different appenders that logs to different sources (file, output window, smtp, server ++). You can also configure what kind of log levels will be written to the different appenders (info, debug, warn, error and fatal).
Most of the time I use two different appenders: I use the DebugAppender to log to my output window in Visual Studio, I like to set this appender to log all levels. I also like to use a LogFileAppender to log to a file on the device, I usually set this appender to only log error and fatal.
You can read documentation and download Apache log4net at http://logging.apache.org/log4net/index.html
I will show you a simple example on how to use log4net in a .Net Compact Framework project:
First you create a new Smart Device project and chose Device application. I am using Visual Studio 2008, Windows Mobile 6 professional SDK as target platform and .Net Compact Framework 3.5
The first thing you need to do after creating the project is to add the log4net.dll as a reference (log4net.dll can be downloaded from the link above).
Then you need to add a xml configuration file for log4net in your project, I added a file called Config.xml in my project and set the property to content/copy always. In this configuration file you add and setup all the different appenders and what level they will log on. You can also defined a layout pattern for the log text.
Below you can see my very simple Config.xml file containing a LogFileAppender and a DebugAppender and they are both set to log all levels.
-
<!– .NET application configuration file –>
-
<configuration>
-
<!– This section contains the log4net configuration settings –>
-
<log4net>
-
<!– Define some output appenders –>
-
<appender name="LogFileAppender" type="log4net.Appender.FileAppender" >
-
<file value="log-file.txt" />
-
<appendToFile value="true" />
-
<layout type="log4net.Layout.PatternLayout">
-
<conversionPattern value="%date [%-5level] – %message%newline" />
-
</layout>
-
</appender>
-
<appender name="DebugAppender" type="log4net.Appender.DebugAppender">
-
<layout type="log4net.Layout.PatternLayout">
-
<conversionPattern value="%date [%-5level] – %message%newline" />
-
</layout>
-
</appender>
-
<!– Setup the root category, add the appenders
-
and set the default level –>
-
<root>
-
<level value="ALL" />
-
<appender-ref ref="DebugAppender" />
-
<appender-ref ref="LogFileAppender" />
-
</root>
-
</log4net>
-
</configuration>
In your Main method (by default found in Program.cs) you need to configure log4net based on the Config.xml file
-
string path = System.IO.Path.GetDirectoryName(
-
System.Reflection.Assembly.GetExecutingAssembly()
-
.GetModules()[0].FullyQualifiedName)
-
+ "\\Config.xml";
-
if (System.IO.File.Exists(path))
-
{
-
XmlConfigurator.Configure(new System.IO.FileInfo(path));
-
}
log4net are now ready to be used in all classes throughout your project. For each class you want to use log4net create a static logger object in top of your class. Remember that the typeof () must be set to the class you create this logger in.
-
private static readonly log4net.ILog Log =
-
log4net.LogManager.GetLogger(typeof (Program));
I often use the logger to log exceptions but I also use it for information and debug.
-
Log.Info("Application startup");
-
//Debug logging
-
Log.Debug("Debug statement");
-
//Warning logging
-
Log.Warn("Could not find all images");
-
-
//Exception logging
-
catch(Exception ex)
-
{
-
Log.Error("Custom exception message", ex);
-
}
The log file on the device can be found under program files\yourProjectName\log-file.txt. This text file on the device is a very good place to for example log your global exception handling.












Log4Net Configuration Loading has to be corrected to
log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(path));
I have added “using log4net.Config;” at the top of my class so I can access XmlConfigurator directly without prefixing it with the namespace.
I forgot to mention that in the code example.
Thanx