Slf4j custom provider implementation not being picked up

2.9k Views Asked by At

Slf4j provides libraries to "fool" backend specific codebase into thinking specific backend exists while redirecting all the logging to one slf4j api compatible backend.

In short log4j-over-sl4j will redirect anything from log4j specific logging into slf4j.

So my classpath now has

slf4j-api *-over-slf4j slf4j-simple (to be removed)

I'm trying to provide custom logging backend for slf4j 1.8+ (please don't ask why). In order to get started with this i've copied over slf4j-simple into my project.

When slf4j-simple is added as a dependency logging happens as expected, but when i remove the dependency and simply keep the exact same content in my own codebase it will not pick it up (different package though)...

How can i make sl4j see my custom provider?

enter image description here

UPDATE

I can see that the jar has some extra information possibly what is being used by slf4j to choose the provider...

However in my case my logging backend is in my own codebase (i dont want to separate it into a library), so is there an api to set your provider to SLF4J?

enter image description here

2

There are 2 best solutions below

1
On BEST ANSWER

SLF4J 1.8+ (which is in beta as of 12.06.2018) abandoned notion of StaticLoggerBinder and instead is using something better called ServiceLoader.

Once you have a copy of the slf4j-simple source in your own codebase with your own package you only need to create a file at ${projectRoot}/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider and put full classname to your own class that shall be picked up your.package.YourLoggingServiceProvider

Make sure you remove any actual binding to another provider, slf4j will give a clear error message that there are multiple bindings on your classpath.

Now try LoggerFactory.getLogger("something").info("something") it shall pick up your classes for logging...

3
On

Refer to the SLF4J FAQ, "How do I make my logging framework SLF4J compatible?" and surrounding area:

  1. start with a copy of an existing module,
  2. create an adapter between your logging system and org.slf4j.Logger interface
  3. create a factory for the adapter created in the previous step,
  4. modify StaticLoggerBinder class to use the factory you created in the previous step

It doesn't look like your question mentions the StaticLoggerBinder, which is the class that there needs to be exactly one of in order for SLF4J to work. It's how SLF4J finds your specific implementation of the logging interface.