Logging best practice?

Topics: Prism v1, Prism v2 - Silverlight 2, Prism v2 - Silverlight 3, Prism v2 - WPF 3.5
Nov 18, 2009 at 3:58 PM

Hi-- I am learning Prism, and I am writing a demo app as part of the process. The demo app will include logging, using the Log4Net library. 

At first glance, I can see two ways to set up the logging:

  • Let the Shell project do all of the actual logging. It gets the reference to Log4Net, and other projects fire composite events to let the Shell know that it needs to log something. Those projects fire the events only for levels where logging is turned on in the Shell's app.config file (DEBUG, ERROR, etc), so as not to degrade performance.
  • Give each project, including modules, a Log4Net reference, and let the project do its own logging to a common log file, instead of sending messages to the Shell for logging.

Which is the better approach? Or, is there another approach that I should consider? Thanks for your help.

Nov 19, 2009 at 12:13 AM
Edited Nov 20, 2009 at 6:07 PM

Michaelsync's suggestion (see below) seems like a good one, and that's the approach I am going to use. The only thing that I might add is that the CAL does its own logging, which can be interfaced to a third-party logger like Log4Net by providing a custom logger.

I am still open to suggestions on this question, so if you have a better approach, or an improvement to Michaelsync's approach, please feel free to join the conversation.

Nov 19, 2009 at 8:11 AM

I think you should have a separated project for logging. And put the interface (e.g. ILoggingService )  in Infrastructure or Common and put the implementation in that separated project.

So, project structure will be like that.

  • YourProject.Shell
  • YourProject.Infrastructure
  • --------ILogService
  • YourProject.Logging
  • --------Log4netLogService

Then, Register ILogService to Log4netLogService in Shell configuration or code.

From all modules, you don't need to reference any logging dll (e.g. log4net)

You can get the instance of logging service from IoC container (e.g.  var logger = container.Resolve<ILogService>() )


Nov 19, 2009 at 8:49 AM
Edited Nov 19, 2009 at 8:51 AM

I am also new to prism and also wanted to use Log4net so I decided to replace the standard logger in Prim with the Log4net logger.   Here is what I did if it is of any use.

I created a class as below in the Infrastructure project.

public class Log4NetLogger : ILoggerFacade
        private static ILog logger = LogManager.GetLogger("WPF Application");
        static Log4NetLogger()

        public void Log(string message, Category category, Priority priority)
                case Category.Debug:
                case Category.Exception:
                case Category.Warn:
                case Category.Info:
Then in the Bootstrapper I override the Logger Facade with 
  protected override ILoggerFacade LoggerFacade
                return new Log4NetLogger();
I am currently just using a basic logging config for log4net which I have in an App.config file located 
within the main shell project e.g.

<!--l version="1.0" encoding="utf-8"-->

<?xml version="1.0" encoding="utf-8" ?>
      <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>

        <level value="ALL" />
        <appender-ref ref="Console" />
        <appender-ref ref="RollingFile" />

      <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
        <file value="logs/Application.log" />
        <appendToFile value="false" />
        <maximumFileSize value="1MB" />
        <maxSizeRollBackups value="5" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="[%d][%-5p] %m%n" />

      <appender name="Console" type="log4net.Appender.ConsoleAppender">
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="[%d][%-5p] %m%n" />

To gain access to the logger  you can use the Container or what I also do is I have an abstract base class for each of my 
presenters which gives access to a logger.  I try to limit my logging to the Presenters where possible and lower level service classes.  
But I also noticed that a library class that I wrote a while back that also uses log4net for logging also worked in this configuration 
without any change to the code, guess it just picks up the main app app.config.    The library class just instanciates their own static 
loggers as usual for .net e.g. with 


public abstract class BasePresenterModel<T> : BindableObject { protected readonly IEventAggregator eventAgg; protected readonly IUnityContainer container; protected readonly ILoggerFacade logger; public BasePresenterModel(IEventAggregator eventAggregator, IUnityContainer cont,ILoggerFacade logging ) { eventAgg = eventAggregator; container = cont; logger = logging; IView = cont.Resolve<T>(); } public T IView { get; set; } } }

Hope these ramblings help

Nov 19, 2009 at 3:38 PM

michaelsync and SwissSteve-- Both very helpful. Thanks.

Nov 20, 2009 at 5:53 PM

Sorry to kind of steal this post, but how would you go about logging when using Silverlight?  You cannot add a reference to the log4net assembly as it's not supported in Silverlight.


Nov 20, 2009 at 6:02 PM

No steal at all, and I think I can help you. Use the Model-View-ViewModel pattern to connect your Silverlight UI to a server back-end, and locate all business logic in the back-end. Your logging will be done from there. If you have a complex Silverlight app, use Composite Application Library (Prism) v. 2.x to structure your app. Again, your logging will be in the app back-end, which supports logging.

Nov 20, 2009 at 6:26 PM

Thanks for the quick response.  I'm not sure if I understand exactly as I'm quite new to Silverlight development.  We are using MVVM and it is a very complex application (at least it will be when finished).  A bit of background, we are taking a large (200 form, 230 table, 300 stored procedure) VB6 Enterprise application and rebuilding it in Silverlight / RIA Services / Prism.

As we have it right now the ViewModels (or PresenterModels) are in Silverlight Class Modules.  I don't see any way to move those ViewModels out of the Silverlight projects and put them somewhere else.  Do you mean the business logic in the ViewModels, or am I even more confused now.

Sorry, I am fairly new to Silverlight and its certain limitations.

Nov 20, 2009 at 10:14 PM

Sounds like a job for Prism. You can get up to speed by reading the Composite Application Guidance for WPF, which is quite good.

Bad news on the view models, though. Most architects would agree that view model classes shouldn't be Silverlight classes--they should be POCOs (plain old CLR classes). There are several ways of implementing MVVM, but they are all designed to get business logic out of the View; i.e., your Silverlight classes. A view model serves up the data your view needs, and it acts as a data binding target for the commands (menu items and buttons) in your view. Silverlight classes are used only for the View. The approach resembles the Model-View-Controller or Model-View-Presenter patterns (depending on which flavor of MVVM you implement), and it gets around a lot of Silverlight's limitations.

I can understand your confusion over MVVM--we all started there. One good place to start is with a presentation that Jason Dolinger did about a year ago. If you google his name, the presentation should come out top of the list. Then if you go to CodeProject, you will find a number of articles on MVVM, including a couple that I have written. My articles are strongly oriented toward a domain-driven-design flavor of MVVM, so they may not be directly applicable to your architecture. But there are lots of other articles that should belp.

Definitely dig into Prism. It does a good job of modularizing complex apps (whether WPF or Silverlight), so that you can "eat the elephant one bite at a time". Particularly if you are working with ADO.NET datasets, it will make your app much easier to develop and maintain.

Nov 24, 2009 at 7:40 AM
why wrote:

Sorry to kind of steal this post, but how would you go about logging when using Silverlight?  You cannot add a reference to the log4net assembly as it's not supported in Silverlight.


As other suggested, you can do server-side logging. But if you really want to do the logging from Silverlight, you may want to check out Daniel's open source called CLog. I haven't tried using it but I know he is great developer and the feature list of Clog is quite interesting. 

>>Most architects would agree that view model classes shouldn't be Silverlight classes

If we are talking about SOA, we used to put the domain model (probably POCO), business logic, complex calculation, algorithm in server-side. And we used to have UI models, ViewModels in Silverlight. Of course, those are Silverlight classes since those are created under Silverlight project. UI Model which is a SIlverlight Class can be POCO. 


Nov 26, 2010 at 12:40 PM

You can also use http://silverlightlogging.codeplex.com/ which has client side buffering of error messages to support working offline.