Logging abstraction (slf4j)

I would like to suggest idea of switching logging layer in jme3 to use slf4j

It is very thin wrapper around multiple logging frameworks (most notably jdk logging, log4j and logback). Performance cost (if any) is absolutely negligible, but it has one big benefit - it allows moving the decision about which logging framework to use to the final application level, rather then library.

Switching logging backend is as trivial as it can get - you just drop the correct slf4j connector jar and everything works as previously. Jme3 can be migrated part by part - everything will work as expected as long as jdk slf4j connector is plugged in.

1 Like

No we wont do that, jME3 uses the default java logging system. The reason is that every other logging system allows plugging in the default java logger while its not possible vice versa. So by using only the default logger we make sure the user can use any logging system he wants.

That’s the idea with slf4j - user plugs in any adapter he wants. If he wants to use any specific logger directly in his app, he does it and then just plugs in slf4j-to-his-logger adapter.

How do you configure default java logging so it is redirected to logback?

abies said:
How do you configure default java logging so it is redirected to logback?

you plug something that does, like log4j.

You mean with something like JULLog4jBridge? And how then it will go to logback?

uh No… I mean lo4g Apache log4j 1.2 -

Maybe I misunderstood, by “logback” you mean writing logs in a file on a file system right?

Nope, by logback I meant http://logback.qos.ch/

Please note that I’m not advocating logback (or log4j) over JUL here, but rather using thin abstract api (slf4j) in library/framework rather any of those logging backends.

ohhh ok!

well if logback is log4j successor, it might be the same to use it with JUL…

In log4j, putting the log4.xml in the classpath was enough…(and of course the lib)

Just to avoid confusion… logback says “Logback is intended as a successor to the popular log4j project”… note “a” successor and not “the” successor.

If it was “the” successor then I think it would be an apache project.

Not that it matters much… I’m just in a pedantic mood. :slight_smile:

I’m very sorry Mr Speed, I won’t do it again :wink:

Sorry for reviving a super-old thread, but there were a couple of points that were missed that I want to make sure get made. (and yes, I’ve read the http://hub.jmonkeyengine.org/forum/topic/loggingsystem-or-exchange-logging-facility-on-deploy-time/ thread)

If jME were using something like log4j directly, then yes, it’d be perfectly possible to “make this work” with an application/developer that wanted to use slf4j – they simply replace log4j with log4j-over-slf4j on the classpath (as well as the main sl4fj API jar and a particular implementation, e.g. logback). Note that this replaces the entire log4j jar with an API-compatible jar that comes from slf4j – it’s not plugging into the log4j API or anything like that. Seems that this is done for performance reasons:

The overhead of using log4j-over-slf4j instead of log4j directly is relatively small. Given that log4j-over-slf4j immediately delegates all work to SLF4J, the CPU overhead should be negligible, in the order of a few nanoseconds. -- http://www.slf4j.org/legacy.html#losOverhead

However, this approach does not work for java.util.logging because you can’t replace the java.util.logging classes with an slf4j JAR. Instead:

Instead, jul-to-slf4j translates LogRecord objects into their SLF4J equivalent. Please note this translation process incurs the cost of constructing a LogRecord instance regardless of whether the SLF4J logger is disabled for the given level or nor. Consequently, j.u.l. to SLF4J translation can seriously increase the cost of disabled logging statements (60 fold or 6000%) and measurably impact the performance of enabled log statements (20% overall increase). -- http://www.slf4j.org/legacy.html#jul-to-slf4j

There is one thing that mitigates this situation, though, mentioned at the end of that last link: if using logback (one of the backends for sl4fj), it’s possible to install a module called LevelChangePropagator that turns that 60 fold overhead for disabled log statements into a 0. Regular log statements still have that 20% overhead, though.

In the end, while I’d still believe that end developers would benefit in a variety of ways if jME were to interface directly with a facade like SLF4J, I think if the end developer wants to use SLF4J with Logback, there’s an acceptable workaround – use LevelChangePropagator. Hopefully this includes most users of SLF4J. If something other than Logback is desired, the developer is out of luck – either endure the huge overhead of disabled log statements, deal with two independent logging implementations (jul + slf4j backend), or don’t use SLF4J. Might it make sense to capture this on the Logging wiki page?

(Example benefit: @lazlohf mentions markers here, which could be used to turn on or off logging by jME subsystem instead of by class. Imagine how nice it would be to turn up or down all logging by subsystems like physics, animations, and textures!)