8

When I'm writing an API assembly for someone else to use, it would be useful to have some logging capability to help diagnose the clients' problems using it.

However, if I reference, for example, log4net in my assembly, this might clash with the version of log4net being used by the client's application.

I don't want to reinvent the wheel by writing my own logging framework.

What's the best way to solve my dilemma?

Edit: I suppose I could demand that the particular version of log4net I am using be installed into the GAC to avoid the version clash with the client, but that would make the API a fat thing that requires installation instead of a drop-in assembly.

1
  • this API isn't going to be rolled in to its own library? Commented Jul 9, 2009 at 15:57

6 Answers 6

4

Look at how SpringFramework solves this problem. It uses Common.Logging which can then be mapped to log4net or to any other custom logging framework via the config file. You can find more details on the Common.Logging website but basically you do the following:

  • reference Common.Logging in your class in use it just like log4net
  • the consumer of your framework will configure Common.Logging to use log4net like so:

  <configSections>
    <sectionGroup name="common">
      <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
    </sectionGroup>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>

  <common>
    <logging>
      <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net">
        <arg key="configType" value="INLINE" />
      </factoryAdapter>
    </logging>
  </common>

  <log4net>
.... normal log4net configuration goes here...
  </log4net>

If the client is also using SpringFramework or the Common.Logging directly, the conflict is still possible but its odds are greatly decreased for the following reasons:

  • Common.Logging team is thinking hard to ensure backward compatibility of future versions with past versions. For example 2.0 is fully binary compatible with 1.2.
  • Common.Logging changes less frequently than log4net, at least in theory
Sign up to request clarification or add additional context in comments.

3 Comments

What if the client is using Common.Logging as well, or they are using NHibernate or Spring.Net. Couldn't that introduce a possibility of a clash in the Common.Logging.dll version?
Normal apps should never use Common.Logging, only frameworks should. If they use NH or SF the conflict is possible although Common.Logging changes less frequently than log4net. Even then if you run into this issue you do some app.config magic to allow the app to load two different version of the same DLL. Or you can build your custom build of Common.Logging under a different name I suppose.
Actually, my bad, looks like NH still uses log4net directly, so your chances of clash have just lowered!
2

Use the Enterprise Library. It's flexible enough, and uses both built-in loggers and its own. It has been fairly verison-compatible as well. It's configurable enough that if there were a conflict with a particular component, you could easily swap it out, with just configuration changes.

Comments

2

Use System.Diagnostics.Trace. No chance of version clashes then!

Comments

1

This is where dependency injection is your friend--you probably don't need to use all of log4net but rather some small bits of it. So write an ILogger class in your app that exposes your functionality, then write an implementation for whatever logger(s) you want to use. For example, a Debug.Trace() logger is great for development or debugging work, while you might need a log4net driver for production. Then use dependency injection, such as StructureMap, to insert the instances of your logger in the production code.

Comments

0

use dependency injection (Unity, Castle Windsor, etc) to specify what the log4net dll to use that way if the client is using an older version, you can just plug in there version of log4net, if they don't have it then provide your own.

Comments

0

If you want to share the log information back externally to the people using it could be worth using a service like 3scale (disclaimer, I work there) - it lets you write logs and traffic info out and give developers an interface to see stats, errors, api-keys, rate limits they may be hitting etc. It also aggregates that stuff for you so you have it one place.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.