preload
Oct 10

apacheWhen 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.

<?xml version="1.0" encoding="utf-8" ?>
<!-- .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

//Load Config.xml to setup log4net
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.

// Create a logger for use in this class
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof (Program));
1
I often use the logger to log exceptions but I also use it for information and debug.
1
//Information logging
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.

Follow me on twitter @PerOla

Share & enjoy
You can subscribe to my comments feed to keep track of new comments.

11 Comments to “Using Apache log4net in .Net Compact Framework projects”

  1. Vijay says:

    Log4Net Configuration Loading has to be corrected to

    log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(path));

  2. 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 :)

  3. anurag says:

    I have Downloaded log4net but it doesn’t have any dll for compact framework 3.5.All it has is a dll for CF 1.0.so,Could you please tell me hoe you used log4net for compact framework 3.5.Thanx.

  4. Hi anurag,
    You can use the dll for CF 1.0

  5. Axel says:

    Hi Per,

    everything works fine – thank you.
    I want also to use internal logging by

    log4net.Util.LogLog.InternalDebugging = true;

    It works, but the output go in the mobile apps to the explorer, which is visible to the user.
    Do you have any idea how to avoid that?

    Best regards
    Axel

  6. Hi Axel,
    I have not been using InternalDebugging on mobile devices, but it should be possible to send the message to an attached debugger (f.ex. a file).

    Have a look at Apache log4net FAQ: http://logging.apache.org/log4net/release/faq.html
    Look a the section: How do I enable log4net internal debugging?

    I hope that will point you in the right direction.

  7. Deepak says:

    Great work man.
    Thanks

  8. Jim says:

    Per:

    I am incorporating log4net into a project using Win CE 6.00 and .NET compact framework 3.5. I have the following code in Program.cs

    string path = Path.GetDirectoryName(
    Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);

    string configFile = path + @”\LoggingConfiguration.xml”;

    if (File.Exists(configFile)) {
    XmlConfigurator.Configure(new FileInfo(configFile));
    }

    The call to XmlConfigurator.Configure(new FileInfo(configFile)); takes about 50 seconds to return. A subsequent call to:

    log.Info(status);

    takes about 25 seconds to complete. Do you have any idea (or even a guess) as to why this would occur?

    Thanks!

    Jim

  9. Hi Jim,

    That it takes 50 seconds to return sounds quite strange… I’m afraid I have no tips for you now, it’s over 2 years since I wrote this post and I don’t have the project to test the behavior. I’m sure that it did not take that much time in the project I used it.

    You can try to post your issue to stackoverflow.com and see if you get lucky there.

    Cheers,
    Per Ola

  10. Sonali says:

    Hello,
    Thank you for this blog. I am getting following error when I tried to create a sample project with logging :

    Error 27 The type ‘System.Uri’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’.

    Error 28 The type ‘System.Xml.XmlElement’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’.

    Appreciate your inputs/comments.

  11. Do you mind if I quote a few of your posts as long as I provide credit and sources back to your website?
    My blog is in the very same niche as yours and my users would
    really benefit from some of the information you present here.
    Please let me know if this alright with you. Thank you!

1 Pingback to “Using Apache log4net in .Net Compact Framework projects”

  1. […] for 2011-04-18 Using Apache log4net in .Net Compact Framework projects (tags: .net logging log4net c# windowsmobile) Published Mon, Apr 18 2011 1:13 PM by […]

Leave a Reply

Subscribe to my comments feed

Subscribe to my feeds Follow me on Twitter
DZone MVB