Monday, November 28, 2011

LINQ To LDAP: Logging

I've been working on logging in LINQ to LDAP recently. I added logging support for all requests as well as any errors that occur. I created an interface so that you can integrate your own logging providers.
public interface ILinqToLdapLogger
{
    bool TraceEnabled { get; }

    void Trace(string message);

    void Error(Exception ex, string message = null);
}
Trace is meant for logging query information. I check TraceEnabled before writing information via Trace. Error is always called when exception is encountered. I wasn't sure if I should add logging hooks for error since most projects will handle errors within their own applications, but I figured you could simply ignore calls to Error in your own implementations.

Out of the box I included a basic implementation:
public class SimpleTextLogger : ILinqToLdapLogger
{
    private readonly TextWriter _textWriter;

    public SimpleTextLogger(TextWriter textWriter)
    {
        _textWriter = textWriter;
        TraceEnabled = true;
    }

    public bool TraceEnabled { get; set; }

    public void Trace(string message)
    {
        _textWriter.WriteLine(message);
    }

    public void Error(Exception ex, string message = null)
    {
        if (message != null) _textWriter.WriteLine(message);
        ObjectDumper.Write(ex, 0, _textWriter);
    }
}
This is mainly used for debugging support, but it also serves as an example implementation. Here's another example using Common.Logging .Net which offers a lot more support for different logging frameworks:
public class CommonLogger : ILinqToLdapLogger
{
    private ILog _errorLog;
    private ILog _traceLog;

    public CommonLogger()
    {
        _traceLog = LogManager.GetLogger("trace");
        _errorLog = LogManager.GetLogger("error");
    }

    public void Trace(string message)
    {
        _traceLog.Trace(message);
    }

    public void Error(Exception ex, string message = null)
    {
        _errorLog.Error(message, ex);
    }

    public bool TraceEnabled
    {
        get { return _traceLog.IsTraceEnabled; }
    }
}
You can attach a log directly to a DirectoryContext or through the LdapConfiguration so it can be used with the ConncectionFactory as well. I'll go into more detail in my next post about the LdapConfiguration changes.
var context = new DirectoryContext() 
{
     Logger = new SimpleTextLogger(Console.Out)
};

var config = new LdapConfiguration()
     .LogTo(new SimpleTextLogger(Console.Out));

//will inject the logger for you
context = config.CreateContext();