
A new log4j 2.0 - javinpaul
http://www.grobmeier.de/the-new-log4j-2-0-05122012.html#.UL-Nd4M723k
======
politician
"In old days, people wrote things like this:

    
    
      if(logger.isDebugEnabled()) {
        logger.debug("Hi, " + u.getA() + “ “ + u.getB()); 
      }
    

"Many have complained about it: it is very unreadable. The log4j 2.0 team
thought about things like that and improved the API. Now you can write the
same like that:

    
    
      logger.debug("Hi, {} {}", u.getA(), u.getB());
    

~~~~

They had a good reason to write it that way! Otherwise, `u.getA()` and
`u.getB()` are evaluated and the values discarded when debugging is turned
off. Evaluating these functions may be expensive (e.g. walking the stack), or
may have debug-specific side effects.

~~~
umjames
Wouldn't u.getA() and u.getB() still be evaluated first so that their values
can be passed to the debug method? Without the if statement, how is the debug
method not being called?

~~~
politician
In the original code, the debug call is guarded by a condition:

    
    
      if (log.isDebugEnabled()) { 
        log.debug("{}", expensiveOp(), debugModeOnlyOp()); 
      }
    

But in the new code, the calls to expensiveOp and debugModeOnlyOp will be
called every time this sequence of code is run regardless of the condition:

    
    
      log.debug("{}", expensiveOp(), debugModeOnlyOp());
    

which is equivalent to the old code:

    
    
      var x = expensiveOp();
      var y = debugModeOnlyOp();
    
      if (log.isDebugEnabled()) { 
        log.debug("{} {}", x, y); 
      }
    

In most languages that do not support macros, it's impossible to correctly
state the dependency of expensiveOp & debugModeOnlyOp on the
log.isDebugEnabled() flag using log4j's new API.

------
bborud
NO!

Sorry, let me rephrase that: FUCK NO!

What Java needs is for all the fucking logging separatists to grow the fuck up
and accept that for the greater good we need a single solution for this -- and
for Oracle to grow a brain, and to give Java a proper logging API and a good
default implementation so we can stop wasting more energy on all the fucking
logging frameworks for Java that do not work.

Anyone not working towards giving J2SE a good logging API and at least one
good implementation that can be distributed with the JDK can go to hell.

~~~
koko775
SLF4J basically won, IMO. Barring extremely specialized uses, there's not
hugely compelling reasons to use anything else than slf4j-api as the logging
interface to your backend of choice, I think. So there is a good default
choice, and the "proper logging API" exists.

Flume uses it, logback uses it, log4j is compatible with it, and it's
compatible with pretty much everything, or you can write your own logger
however you like.

P.S. You sound really pissed about this. Do you have personal experience with
logging frameworks?

~~~
bborud
No, slf4j doesn't solve any problems: it just gives you different problems.
What makes it twice as infuriating is that slf4j _looks_ really promising
until you realize that it is just more pig-lipstick, albeit in a different
color than before.

PS: That is because I am really pissed. If there is one thing I fucking hate
it is all the time you have to spend trying to fit components together that
use any one of the gazillion different logging frameworks and combinations of
logging frameworks that are possible. But I'll give you that: I despise the
shitheads behind log4j more than I despise the people behind slf4j.

Logging sucks in Java.

~~~
koko775
Specifics, please. I just implemented a logging backend for slf4j on Android
in roughly ~1 hour with virtually no prior knowledge other than generally how
to use slf4j and how to use Android's Log class.

It just worked, and it was pretty darn simple, and now I have fancy log
messages. I even customized the tags so that instead of
com.example.some.path.to.Something, I can summarize that to
c.e.s.p.to.Something.

~~~
bborud
Writing a logging backend for slf4j isn't hard. Anyone unable to do that
should not be programming.

Trying to figure out how to a) get lots of components that rely on wildly
different logging frameworks and even multiple versions of the same logging
frameworks and b) try to distill that into common practices in an engineering
organization, is hard. In part because you have to spend two hours explaining
the problems we've been through every time someone thinks all these problems
have a 5 minute fix.

(And the slf4j technique of placing a bridge in the class path and hoping for
the best is just priceless. That deserves an entire hour of slow clap)

~~~
koko775
Okay, now we're getting somewhere, but as someone who has used Java more
client-side than server-side, I'm not familiar with the problems everyone's
else been through. I would love for you to enlighten me, if you could!

Also, what would you substitute in place of StaticLoggerBinder? It did strike
me as somewhat janky to rely on a class with a matching name and class just
_existing_.

~~~
bborud
The problem is not software. The problem is people.

Rather than trying to explain the problem (which most people who work on
logging struggle to see), let me outline how you determine when the problem is
either solved or absent.

The problem is solved when people like me (a hands-on system architect who
writes code and tries to make decisions on behalf of a number of developers)
do not have to think about logging APIs, facades or backends anymore. When
nobody in my organization has to spend time trying to resolve the conflicts
that arise from different logging technologies (and different versions of same
technologies) being in use in the same system.

We have an example of that in Java: the collection classes. For most bread-
and-butter uses Java has List, Map and Set types that people can just use.
They are well designed, well documented and you can count on them to be
available at no extra cost. It is unusual for a non-mad( _) Java programmer to
feel the need to introduce extra dependencies for simple lists, sets, maps
etc.

You most likely are not going to feel the pain of logging chaos if you are
writing a single application. If you try to make decisions on behalf of 50+
projects, some of which rely on an obscene number of libraries, that pain will
manifest itself every day and you will re-live the same pointless discussions
and get the same pointless advice over and over and over.

Hope this sheds some light on why I think what I think.

(_) there are idiots who depend on third party implementations where the types
in J2SE would suffice.

------
mbell
Not to be a pessimist but, I can do without more versions of log4j.

The pain and annoyance of fighting version conflicts from multiple
dependencies and the desire of some to include slf4j directly in their jar
files gives me FAR more pain than anything syntactic related to how the logger
actually works. If you want to truly improve logging, find a way to avoid this
mess.

~~~
eternalban
The standard logger in JDK is entirely serviceable.

~~~
mbell
That doesn't fix anything.

Examples:

One dep want log4j-api 1.6.4 one wants 1.4, this doesn't matter to the client
but I have to make sure to override one in maven to make sure the API version
matches the back end version. When your project has 20 dependencies all using
log4j, its a pain in the ass and makes your POM quite ugly.

Two deps stupid enough to include slf4j in their JAR files, now my build
process consists of pulling the deps from maven, then running a script to
manually strip out the slf4j files from the jar. Yes this is the authors fault
but a logger that would allow 2 versions on the classpath would be amazing,
granted it would require some trickery with the class loader to make work.

~~~
mbell
And of course I got slf4j and log4j backward in my examples.

------
ccleve
So why is this better than slf4j + logback? I'm not seeing any advantages.

log4j, slf4j, and logback were all written by the same guy, Ceki Gülcü. I'd be
interested to hear what he has to say about it.

~~~
grobmeier
Ceki is still on the Apache Logging project management committee. You might
reach him on the log4j mailing list to ask him.

slf4j and logback are a good combination. Of course there are differences,
some are highlighted in the blog post.

From the website - decide yourself.
<http://logging.apache.org/log4j/2.x/manual/index.html>

So why bother with Log4j 2? Here are a few of the reasons.

\- Log4j 2 is designed to be usable as an audit logging framework. Both Log4j
1.x and Logback will lose events while reconfiguring. Log4j 2 will not. in
Logback exceptions in Appenders are never visible to the application. In Log4j
2 Appenders can be configured to allow the exception to percolate to the
application

\- Log4j 2 uses a Plugin system that makes it extremely easy to extend the
framework by adding new Appenders, Filters, Layouts, Lookups, and Pattern
Converters without requiring any changes to Log4j.

\- The performance of Log4j 2 is similar to that of Logback. It is slightly
slower in some tests and faster in others.

\- Due to the Plugin system configuration is simpler. Entries in the
configuration do not require a class name to be specified.

\- Support for Message objects. Messages allow support for interesting and
complex constructs to be passed through the logging system and be efficiently
manipulated. Users are free to create their own Message types and write custom
Layouts, Filters and Lookups to manipulate them.

\- Log4j 1.x supports Filters on Appenders. Logback added TurboFilters to
allow filtering of events before they are processed by a Logger. Log4j 2
supports Filters that can be configured to process events before they are
handled by a Logger, as they are processed by a Logger or on an Appender.

\- Many Logback Appenders do not accept a Layout and will only send data in a
fixed format. Most Log4j 2 Appenders accept a Layout, allowing the data to be
transported in any format desired.

\- Layouts in Log4j 1.x and Logback return a String. This resulted in the
problems discussed at Logback Encoders. Log4j 2 takes the simpler approach
that Layouts always return a byte array. This has the advantage that it means
they can be used in virtually any Appender, not just the ones that write to an
OutputStream.

\- The Syslog Appender supports both TCP and UDP as well as support for the
BSD syslog and the RFC 5424 formats.

\- Log4j 2 takes advantage of Java 5 concurrency support and performs locking
at the lowest level possible. Log4j 1.x has known deadlock issues. Many of
these are fixed in Logback but many Logback classes still require
synchronization at a fairly high level.

\- It is an Apache Software Foundation project following the community and
support model used by all ASF projects. If you want to contribute or gain the
right to commit changes just follow the path outlined at Contributing

------
koevet
What about logback (<http://logback.qos.ch/>)? I thought that it was the new
log4j.

~~~
grobmeier
log4j1 was the beginning. Then one of the team left and build logback. The
log4j2 team wants a logging framework which is build in "the apache way" and
under "apache license". The project has grown fantastically and you can expect
some cool features in future.

Still logback is a great framework. The log4j2 team learned of it and I think
it is also in the other direction.

My (personal) recommendation is you use slf4j and chose a logging framework to
your taste. You might choose based on a specific feature, on issue which has
not been resolved in the other framework, on the license or how easily you can
contribute.

That said, the log4j2 project is pretty active.

------
exabrial
I really with the log4j people would just call it quits. They spent 5 years
not delivering anything. Then the tragedy of commons logging happened, which
only seems to survive because Spring Source uses it.

Please. Fucking. Stop. Just delete the damned project. End the ridiculousness
and JUST USE SLF4J.

~~~
grobmeier
slf4j is not a logging framework.

------
rauar
You guys should have tried to get back the logback author and his project back
under the Apache umbrella instead of creating yet another loging
implementation. Your "improvements" could have been labeled as logback 2.0.

Yet another implementation causes only more fragmentation (the only real pain
w.r.t to logging) and in almost all cases the existing solutions are totally
sufficient.

~~~
grobmeier
Ceki is not liking the Apache model. He left because of that. You can read
more about his reasons on his blog:
[http://ceki.blogspot.de/2010/05/committocracy-as-
alternative...](http://ceki.blogspot.de/2010/05/committocracy-as-alternative-
for.html)

But still he is a community member and PMC of Apache Logging:
[http://people.apache.org/committers-by-
project.html#logging-...](http://people.apache.org/committers-by-
project.html#logging-pmc)

On the other hand, we (the Apache guys) are not liking how the logback project
is operating. At least it is me who does not like it, but I guess the others
think similar. We want a community driven logging project which uses the
Apache License. We surely don't want a logging project which is officially run
by a company (like QOS runs logback). I have seen many cases where this does
lead into problems.

That said it will be difficult to motivate Ceki to get back to Apache Logging.
But we are open to his contributions and hope that there will be a good,
technical exchange between both projects.

Another personal note: I am really against person cult. The Apache Logging
project has some really great and experienced committers on board. One of them
is working on Java logging for around 20 years and he set a very, very high
bar for log4j. Having Ceki on-board is definitely of interest, but he is not
the only person who knows about logging.

Please have also in mind, that a new log4j2 release is just the beginning of
our journey (hopefully).

------
jvermillard
Nice to see some new ideas are explored. We can't have only one logging
framework. Keep up the good work !

