A new log4j 2.0
grobmeier.de
grobmeier.de
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.
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.Often it is the conversion to string that is an expensive operation.
Incidentally with lots of lazy loading (Hibernate I'm looking at you...) this can lead to errors only appearing when debug is turned off - not a nice situation to be in.
I have always preferred the NLog style, where the default .Debug, .Warn, etc., functions use good old .NET format strings and a params argument. logger.Debug("Thing {0} happened at {1:R}", thing, thing.CompletionDate);
log.Debug("Thing {0} happened", o.expensive_call())
could end up calling some method that took a very long time to run, only to be thrown away in the end. String construction isn't that big of a deal and their new API could avoiding doing it if the message won't be used.
logger.debug(String.format("Hi, %s %s", u.getA(), u.getB()));
If they wanted to have format capabilities in the logger, why didn't they just use pre-existing standards?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.
However, I do realise that the Java ecosystem is often complex for a reason (or, "simpler" languages and frameworks are often too simple). Is there a reason there are so many logging frameworks? What different needs do they solve?
BTW "architecture astronautism" great term. I <3 Java, it has a culture of overengineering, in which I do not participate.
logback / log4j2 are 2 implementations of the slf4j facade. log4j2 is a community driven project and it is maintained with Apache License 2.0. It addresses some issues of logback. If you run into this issues in production, you can switch to log4j2, given that you are using slf4j (which is the recommendation).
commons-logging is pretty dead, and nobody makes a deal about it. It has not been updated for around 5 yrs.
You clearly need to understand the difference between slf4j and logback/log4j2. And you should learn more about what the Apache Software Foundation is doing. I consider it better not to trust a single company when it comes to important things. It has often proven in the past.
Apache fucked up and Sun fucked up. And we all lose.
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?
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.
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.
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)
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.
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.
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.
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.
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.
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
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.
Please. Fucking. Stop. Just delete the damned project. End the ridiculousness and JUST USE SLF4J.
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.
But still he is a community member and PMC of Apache Logging: http://people.apache.org/committers-by-project.html#logging-...
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).