none
General design for logging RRS feed

  • Question

  • This is a problem that I'm thinking about, but the problem comes up in many places, not just with logging.  Imagine you want to do log errors etc. in a log file.  You may do something like:

     

    MyLogClass.Log("Error!", "Additional Information");

     

    However, if you have lots of these scattered through you application then the classes will be tightly coupled, potentially making it very difficult to share them between applications.  What's the best way to do this, using and interface or abstract class?  My thoughts are this:

     

    Code Block

    interface ILogger

    {

    void Log(string description, sring extraInformation);

    }

     

    class MyClass

    {

    ILogger logger;

     

    public MyClass()

    {

    // Can be used without logging

    }

     

    public MyClass(ILogger logger)

    {

    this.logger = logger;

    }

     

    public ExampleFunction()

    {

    if (logger != null)

    {

    logger.Log("Example", "Description");

    }

    }

    }

     

     

    With this pattern you can use the class (MyClass) without logging, so it can be used in another application without being modified.  There is a bit more code though, checking whether the logger is null etc.

     

    I also have another question about this too.  If you used this class where would you put the interface (ILogger)?  Would it go in its own file?  The logging classes need it because they inherit from it, and the other classes need it because they use it.  Or is not a nice way of logging?

     

    What are peoples thoughts?

    Wednesday, January 2, 2008 6:59 PM

All replies

  • Hi Peter,

     

    What's the best way to do this, using and interface or abstract class? 

    To use interface or abstact class is dependent on your requirement.......either of them is fine...sometimes it also depends on your current project design..

     

    You can use either one and have one factory method which will instantiate the required class.... class information you can put in config file also.......

     

     

     If you used this class where would you put the interface (ILogger)?  Would it go in its own file? 

     

    this depends on your project....

     

    if your project is big enough then I suggest to put interfaces in different projects altogether..

    if you want to achieve mantainability then put all interfaces in different project....

     

    otherwise same project is ok..............

     

    If you are sure about you are going to use only one logger...then I would suggest you to use one class with static methods..........

     

     

    Thursday, January 3, 2008 3:49 PM
  • I'd avoid managing references to a ILogging interface across all classes that may possibly utilize it.  Client classes should not be responsibile for caring whether or not logging is implemented.  Furthermore, I cannot imagine the amount of effort it would take to pass ILogger references into every object that may need it and having to decide which ctor to use (tho a factory could hide this logic).  I'd follow the advice of just implementing a static class, or even some singleton-based approach:

     

    // Interface

    public interface ILogger

    {

      void Log(string message, string details);

    }

     

    // Sample implementations

     

    public class LoggerBase : ILogger

    {

      // Implement ILogger with NoOps 

      public void Log(string message, string details)

      {

      }

    }

     

    public class Logger : ILogger // Or inherit LoggerBase

    {

      // Implement ILogger

      public void Log(string message, string details)

      {

        // Actually log somehow

      }

    }

     

    // Singleton

    public static class TheLogger

    {

      private static ILogger m_logger;  // Initialize in static ctor or whatever, but you don't want this to be nullable so clients don't need to worry about null checking - this is why we have the noop LoggerBase...

     

      static TheLogger()

      {

        if ( enable logging )

        {

          m_logger = new Logger();

        }

        else

        {

          m_logger = new LoggerBase();

        }

      }

     

     

      public static ILogger It

      {

        get { return m_logger; }

      }

     

    }

     

    // Client Example

     

    public class Example

    {

      public void SomeMethodThatNeedsToLog()

      {

        TheLogger.It.Log("Test", "Details");

      }

    }

     

    You can always implement an ILogger that manages multiple logs (database, file, event log, etc), so this approach should scale well.  The only "trick" is figuring out how/where you configure/initialize the log...

     

     

     

     

    Friday, January 4, 2008 3:01 PM
  • Actually I don't know why you are developing this ......

     

    Microsoft Enterprise library contains a whole block classes Application logging and Exception handling that can help you with already implemented and tested components that will help you doing this

     

     

    There is also a free open source componented called Log4net that will do the job for you check these and tell me your feedback

     

    Friday, January 4, 2008 9:21 PM