Implementing Open Source Library: How to handle logging?
I am in the process of implementing logging support in an open source library I am working on. Most 3rd party libraries seem to explicitly choose a "preferred" logging library such as Log4Net or NLog etc and then require that the consumer of their library "deal with it". Thankfully, we have a library like Common.Logging to address this issue in our consuming application(s) that unifies these 3rd party library logging implementations.
I was going to try and avoid referencing another 3rd party library from my own open source library to avoid bringing in yet another assembly reference in to someone else's application. Perhaps this is not a concern, and I should just stop there?
Assuming that some people agree开发者_StackOverflow that excessive assembly references are annoying (and since someone will mention it), I personally, I don't like using ILMerge for this type of situation, as you may easily have several libraries that use Log4Net and if they each ILMerged in the assembly it is just bloating the size of an application in my opinion.
To that end, I was thinking of implementing and exposing a LogBridge to allow the consumer of my library to hook in to my logging calls if so desired (would be off by default). Also let me stress that I am not talking about implementing my own logging framework, just ensuring that I expose logging if someone is concerned with comsuming it. I was thinking the consuming implementation would appear something like:
public class SomeSetupClass
{
private void SomeSetupMethod()
{
var log = LogManager.GetLogger("LogSourceName");
var logBridge = new LogBridge()
{
DebugEnabled = log.IsDebugEnabled,
InformationEnabled = log.IsInfoEnabled,
WarningEnabled = log.IsWarnEnabled,
ErrorEnabled = log.IsErrorEnabled,
CriticalEnabled = log.IsFatalEnabled
};
logBridge.DebugMessageReceived += (sender, e) => log.Debug(e.Message);
logBridge.InformationMessageReceived += (sender, e) => log.Info(e.Message);
logBridge.WarningMessageReceived += (sender, e) => log.Warn(e.Message);
logBridge.ErrorMessageReceived += (sender, e) => log.Error(e.Message);
logBridge.CrticalMessageReceived += (sender, e) => log.Fatal(e.Message); }
}
}
Does this approach make sense? Am I over thinking this after being on vacation for too long and I should just reference Log4Net or NLog etc and be done with it? Am I missing any major cons of this approach? Does the rough API make sense?
As always, curious what everyone thinks...
Update
Curious if people think that jgauffin solution is the better way to go? I had given it some thought prior to this post; my thought was that the LogBridge would be easier to hook up for consumers rather than requiring a custom interface to be implemented in a consuming project? Thoughts?
Look in System.Diagnostics and just use the Trace or Debug classes. Products like Log4Net can pick those up when needed.
I usually do this:
- Provide a interface for logging:
ILogger
- Create a logger factory used to fetch a logger:
ILogger _logger = LogManager.GetLogger(typeof(ClassBeingLogged));
- Provide a basic implementation such as ConsoleLogger.
You can also provide examples in your project wiki showing how to implement nlog or log4net. That's usually enough.
the LogManager takes a ILogFactory
which is responsible of creating the actual implementation:
public class LogManager
{
ILogFactory _factory;
public static void Assign(ILogFactory factory);
public static ILogger GetLogger(Type typeBeingLogged);
}
public interface ILogFactory
{
ILogger GetLogger(Type typeBeingLogged);
}
This makes it quite easy to implement an adapter for any logging framework.
精彩评论