Java Logging vs Log4J [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Is it still worth to add the log4j library to a Java 5 project just to log
let's say some exceptions to a file with some nice rollover settings.
Or will the standard util.logging facility do the job as well?
What do you think?

I'd say you're probably fine with util.logging for the needs you describe.
For a good decision tree, have a look at Log4j vs java.util.logging
Question One :
Do you anticipate a need for any of the clever handlers that Log4j has that JUL does not have, such as the SMTPHandler, NTEventLogHandler, or any of the very convenient FileHandlers?
Question Two :
Do you see yourself wanting to frequently switch the format of your logging output? Will you need an easy, flexible way to do so? In other words, do you need Log4j's PatternLayout?
Question Three :
Do you anticipate a definite need for the ability to change complex logging configurations in your applications, after they are compiled and deployed in a production environment? Does your configuration sound something like, "Severe messages from this class get sent via e-mail to the support guy; severe messages from a subset of classes get logged to a syslog deamon on our server; warning messages from another subset of classes get logged to a file on network drive A; and then all messages from everywhere get logged to a file on network drive B"? And do you see yourself tweaking it every couple of days?
If you can answer yes to any of the above questions, go with Log4j. If you answer a definite no to all of them, JUL will be more than adequate and it's conveniently already included in the SDK.
That said, pretty much every project these days seems to wind up including log4j, if only because some other library uses it.

I recommend that you use the Simple Logging Facade for Java (SLF4J). It supports different providers that include Log4J and can be used as a replacement for Apache Commons Logging.

Log4j has been around for a long time, and it works very well. I have no scientific study to back it, but based on what I've seen at a large number of clients, it is easily the logging framework that I see used more than any other. It has been around for a long time, and not been replaced by the Next Big Logging Framework, which says something.
It is dead simple to set up, and easy to learn the basic appenders (outputs). There are a whole host appenders that are available, including:
ConsoleAppender
DailyRollingFileAppender
ExternallyRolledFileAppender
FileAppender
JDBCAppender
JMSAppender
NTEventLogAppender
RollingFileAppender
SMTPAppender
SocketAppender
SyslogAppender
TelnetAppender
WriterAppender
Plus others. It isn't difficult to write your own appender either. Additionally there is a great deal of flexibility in each of the appenders that allow you to control specifically what is output in your log.
One note, I had a series of classloader problems when I used apache commons logging in addition to log4j. It was only for one specific application, but I found it simpler to use log4j alone, rather than to have the flexibility offered when using an abstraction layer like commons logging.
See this article for
more details:
Good luck!

java.util.logging offers a comprehensive logging package without the excess baggage some of the others provide..

log4j is a much nicer package overall, and doesn't have some of the hiccups that java.util.logging contains. I'd second that using log4j directly is easier than using the commons logging.

I recommend using Apache Commmons Logging as your logging interface. That way you have the flexibility to switch logging implementations anytime you want without requiring any code changes on your end.

I would go with log4j. The possibilites with log4j is not obsolete at all!

Related

How to avoid Log4J exploit? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
There is a serious security flaw in Log4J that has apparently been patched. But I have not found an intelligible explanation as to how there could even be a security flaw in a logging framework.
It seems to have something to do with "Lookups".
https://logging.apache.org/log4j/2.x/manual/lookups.html
But that is in a config file, not a log file that could be injected into?
Question. How do I kill all clever stuff once and for all to prevent any future exploits? I just want logging.
It smells like I need to remove any "$" signs but that is just a guess. (One should also remove any \ns to avoid log file spoofing. I always write a very simple wrapper for the logging to be able to do this sort of thing.)
(I have a very simple shim that all log messages go through, so it is easy for me to remove all "$"s that are not in format strings.)
The only way to prevent vulnaribilites caused by lookups is to disable them completely.
According to log4j2 team, the way to do that is by appending Java parameter
-Dlog4j2.formatMsgNoLookups=true
This definitely fixes the ability to call lookups by putting ${...} sequence s in the user input (like in URLs that are logged).
Unfortunately, the lookups are applied to the logged sequence, even if you use parameters or log exception stack traces. The lookups sequeces in your code are not dangerous, because they are controllable. But those that come from user are not predictable. If you log 'wrong username: xxx', you have no idea, what the user can type to exploit another vulnaribility.
However, you can't be sure there are no other grave errors in the framework, so switching to other logging framework is reasonable.
A good candidate is Logback, which is started by the original author of the Log4j. The developer states clearly, his framework has nothing to do with the security issues introduced in Log4j2:
Unless specified otherwise, when we say log4j we mean log4j 1.x. We
should also like to emphasize that logback is unrelated to log4j 2.x.
It does not share code nor vulnerabilities with log4j 2.x.
The bug is apparently fixed in the version 2.16.0, however it addresses only that particular vulnaribility, and the dangerous lookup feature was not removed.
According to the Sophos Report,
The updated version of Log4j still supports the potentially dangerous
what-you-see-is-not-what-you-get system of string “lookups”, but
network-based JNDI connections, whether on the same machine or
reaching out to somewhere else, are no longer enabled by default.
In other words, log4j2 still remains unsecure, but not as ridiculously insecure as previously.
For security issues like this one it makes sense to keep the up to date information in a single place.
Please refer to the official Log4j information about this vulnerability here: https://logging.apache.org/log4j/2.x/security.html
The document states several mitigation measures applicable for different versions of Log4j.
I realize that in general the StackOverflow convention is to have explicit steps and examples in the answer here on StackOverflow, rather than link to external documentation, but I believe that sensitive security flaws should be an exception.

Are there any alternatives to ESAPI

We are splitting our logging functionality as a separate logging library which will be used as a logging jar for all web application. Currently we are using ESAPI 2.1 to prevent log forging, we have also upgraded our logging framework to log4j 2 to support async logging.
From this post https://security.stackexchange.com/questions/170523/is-owasp-esapi-still-the-recommended-way-to-secure-jsp-pages , I came to know that ESAPI seems to be outdated and not used anymore, is there any better alternative to create a secure logging library?
Dead you say? Oh Really?
At any rate, if you just want our logging capabilities just git clone https://github.com/ESAPI/esapi-java-legacy and copy the code you like while respecting our FreeBSD license.
Also, if its log injection that you're worried about, also come to an agreement on a log format message that always encloses user input in symbols you control. Makes it easier to detect mischief.

Are logging tools like log4j useful only during development phase? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I need to log the activity of the users connected to my server, should I use log4j? Or is log4j beneficial only during development phase?
They are actually not particularly useful during development, System.out.println is pretty good for most dev debug logging, but once you deploy the following abilities become really useful:
roll logfiles so they don't get too big allowing for continuous maintenance-free operation
add times/dates so you can look at the logs for a certain time period
Change verbosity on the fly (You don't always want trace or debug info, but being able to flip it on when he system isn't running well can be a lifesaver)
Re-route logfiles to a more accessible place... Log4j can send your logs to various databases or other locations for when you can't actually reach your server directly.
Some of our code has trace statements on every significant line. If we run into problems when we are developing we leave the debugging/trace statements in and are able to turn them on when we need to in production--almost equivalent to single-stepping through your deployed code. In addition most methods have trace or debug statements at the top showing the parameters being passed in and program flow--again only really useful for a deployed system where a debugger is unavailable.
So in short, yes it's useful after development.
edit (in response to comment question)--
Just as an example. The app I'm working on now has 20ish logs. One is "Performance", it logs data coming in including timings--sometimes more than one line a second. This logfile "Rolls" at 10mb (about hourly) but we use it to find lags in our data delivery. We even use other software to analyze this log sometimes to look for patterns in data timing.
We have a separate "Error" log that logs all error-level activity. This log doesn't roll so fast that we lose data when we are getting a bunch of other log information.
There is another log to put problems related to Hibernate/SQL and one for problems related to our message queue and one for our inter-app cache....
These are all also combined into a "main" log through the log4j config file. We can reconfigure any one log to a different level (for instance, we were having authentication problems with a data source so we turned up it's debugging level on that source to find out what had changed in our server's environment to cause that)
Even though some of the logs scroll 10mb in an hour (our max file size). Log4j will roll them into .1 and .2 files so we can keep 10-50 of them depending on need.
All of this is done through config files and can be changed after deployment without rebuilding the system.
Edit 2--another thought
Another useful point about using log4j and the java logging interface is that libraries like hibernate using it can be configured through xml files without rebuilding.
Without Log4j/java's logging APIs you would either A) have a custom API to control the logs, B) only have default logging or C) have no logging from that subsystem. Since Hibernate uses java's APIs however, you can set the log level for "Hibernate" log info in a standard, documented xml config file and even re-route it's logs to a database or other logging device.
Logging is especially useful to locate errors that occur in productive code. During development you can use more powerful tools like debuggers.
Of course you have to be aware that logging potentially affects performance and can create huge files. That's why tools like log4j can be configured to turn on and off logging or to control its verbosity.
It's ok to use log4j because it is the most common library for Java. However I personally find its configuration a bit unitntuitive.
Another reason for using loggers such as Log4j is to allow for different logging levels for different components. Logs can get pretty large and messy if you turn DEBUG on for everything. If you know what area of code you want to "magnify" in your logs you can ratchet up the logging for that area alone.
yes (or any other logging framework / SLF4J)
no

Is Log4j being abandoned in favor of Slf4j? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
It seems that log4j has some class loading issues (among others) and it seems to me the trend is to move out of log4j toward slf4j. (Hibernate stopped using the first in favor of the latter)
Is it true?
What are the main issues in log4j that slf4j solves?
Is slf4j the final word or is there even a better "the next next log4j" industry standard?
Update:
So this answer by delfuego confuses me, can you accept / object it?:
You appear to have stumbled upon the
major problem with log4j (and the
Apache Commons Logging library),
namely that they have a ridiculously
hard time discovering and interacting
with the right classloaders as they're
being used. There's a very dense
explanation, complete with examples,
here; the take-home message is that
one of the primary driving forces for
the new logging framework SLF4J was to
eliminate these issues entirely. You
might want to swap it in and see if
your life is made any easier.
More classloading issues by log4j: http://articles.qos.ch/classloader.html
Slf4j is indeed just a logging facade. However, Log4j is intended to be succeeded by Logback, from the very same authors.
Update: if you'd like to know about another benefit of Slf4j, it's the fact that following (ugly) constructs aren't needed anymore to avoid the toString() unnecessarily been called:
if (logger.isDebugEnabled()) {
logger.debug("Message: " + bigObject + ", " + anotherBigObject);
}
You can instead make use of parameterized messages:
logger.debug("Message: {}, {}", bigObject, anotherBigObject);
Also see What is the fastest way of (not) logging?
Slf4J is not an alternative for Log4j, but rather provides a Façade for logging, so one can you can plug in your own logging framework. It's mainly useful for libraries.
from slf4j.org:
The Simple Logging Facade for Java or
(SLF4J) serves as a simple facade or
abstraction for various logging
frameworks, e.g. java.util.logging,
log4j and logback, allowing the end
user to plug in the desired logging
framework at deployment time.
To answer your question: Slf4j is being adopted by frameworks now, but in your projects, you can keep on using Log4J (or any other)
First: an important point: Slf4j is the frontend logging (the API), which can use below most of the main loggin systems: log4j or java.util.logging for instance. So it is better to compared sfl4j to commons-logging.
About the state of Log4j, quotes from The state of java logging (one year ago)
One thing that I hadn't realized is that log4j development is essentially dead. It's currently at version 1.2, and plans for version 1.3 were abandoned in favour of developing log4j 2.0. However, it doesn't appear that 2.0 is in active development. It is worth noting that Ceki Gülcü, the original founder of the log4j project, has moved on to slf4j (see below).
Looking at the slf4j page it doesn't look like it would replace log4j - it would just allow you to use the same underlying logging framework (e.g. log4j) for your whole application, allowing libraries to hook into that automatically.
It looks more like a replacement for Apache Commons Logging than log4j.
SLF4J has, in my opinion, the huge advantage that you can unify the logging of all the libraries that you use through the bridges that it provides. Neither of the other logging frameworks allows this. This allows projects to smoothly move to SLF4J and ignore the logging framework choices that dependencies have made.
Slf4j is not a real logging facade.
Slf4j does not support many features of its implementors.
For short, I mention log4j examples below.
Slf4j cannot specify a user selected configuration file, but forces user to use default (log4j.properties or log4j.xml) at one of so many Java roots (each Jar has one root plus JVM root and classes or bin). If two JAR files have it, it is hard to control which one to use safely.
Slf4j cannot support all Log4j levels, such as 'fatal'. When switch big code from Log4j to Slf4j, huge code change effort is needed (e.g. deciding how to rearrange levels).
Two key Jar files (log4j-over-slf4j.jar or slf4j-log4j12.jar) must be chosen. If classpath both, won't work. If choose one randomly, lose unexpected features (e.g. log4j-over-slf4j.jar does not support multiple log files for same classes; e.g. one for events log and one for raw data log).

Are there technical reasons to prefer using logback instead of log4j?

Should new projects use logback instead of log4j as a logging framework ?
Or with other words :'Is logback better than log4j (leaving the SLF4J-'feature' of logback beside)?'
You should use SLF4J+Logback for logging.
It provides neat features like parametrized messages and (in contrast to commons-logging) a Mapped Diagnostic Context (MDC, javadoc, documentation).
Using SLF4J makes the logging backend exchangeable in a quite elegant way.
Additionally, SLF4J supports bridging of other logging frameworks to the actual SLF4J implementation you'll be using so logging events from third party software will show up in your unified logs - with the exception of java.util.logging that can't be bridged the same way that other logging frameworks are.
Bridging jul is explained in the javadocs of SLF4JBridgeHandler.
I've had a very good experience using the SLF4J+Logback combination in several projects and LOG4J development has pretty much stalled.
SLF4J has the following remaining downsides:
It does not support varargs to stay compatible with Java < 1.5
It does not support using both parametrized message and an exception at the same time.
It does not contain support for a Nested Diagnostic Context (NDC, javadoc) which LOG4J has.
The author (of both Logback and Log4j) has a list of reasons to change at http://logback.qos.ch/reasonsToSwitch.html.
Here are a few that stuck out at me;
Faster implementation
Based on our previous work on log4j,
logback internals have been
re-written to perform about ten times
faster on certain critical execution
paths. Not only are logback
components faster, they have a
smaller memory footprint as well.
Automatic reloading of configuration
files
Logback-classic can automatically
reload its configuration file upon
modification. The scanning process is
both fast and safe as it does not
involve the creation of a separate
thread for scanning. This technical
subtlety ensures that logback plays
well within application servers and
more generally within the JEE
environment.
Stack traces with packaging data
When logback prints an exception, the
stack trace will include packaging
data. Here is a sample stack trace
generated by the logback-demo
web-application.
14:28:48.835 [btpool0-7] INFO
c.q.l.demo.prime.PrimeAction - 99 is
not a valid value
java.lang.Exception: 99 is invalid
at
ch.qos.logback.demo.prime.PrimeAction.execute(PrimeAction.java:28)
[classes/:na] at
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
[struts-1.2.9.jar:1.2.9] at
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
[struts-1.2.9.jar:1.2.9] at
org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
[struts-1.2.9.jar:1.2.9] at
javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
[servlet-api-2.5-6.1.12.jar:6.1.12]
at
org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:502)
[jetty-6.1.12.jar:6.1.12] at
ch.qos.logback.demo.UserServletFilter.doFilter(UserServletFilter.java:44)
[classes/:na] at
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1115)
[jetty-6.1.12.jar:6.1.12] at
org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:361)
[jetty-6.1.12.jar:6.1.12] at
org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417)
[jetty-6.1.12.jar:6.1.12] at
org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
[jetty-6.1.12.jar:6.1.12]
From the above, you can recognize
that the application is using Struts
version 1.2.9 and was deployed under
jetty version 6.1.12. Thus, stack
traces will quickly inform the reader
about the classes invervening in the
exception but also the package and
package versions they belong to. When
your customers send you a stack
trace, as a developer you will no
longer need to ask them to send you
information about the versions of
packages they are using. The
information will be part of the stack
trace. See "%xThrowable" conversion
word for details.
This feature can be quite helpful to
the point that some users mistakenly
consider it a feature of their IDE.
Automatic removal of old log archives
By setting the maxHistory property of
TimeBasedRollingPolicy or
SizeAndTimeBasedFNATP, you can
control the maximum number of
archived files. If your rolling
policy calls for monthly rollover and
you wish to keep one year's worth of
logs, simply set the maxHistory
property to 12. Archived log files
older than 12 months will be
automatically removed.
There may be a bias there, but the same guy did write both frameworks and if he is saying use Logback over Log4j he's probably worth listening to.
I would use slf4j for logging in all cases. This allow you to choose which actual logging backend you want to use, at deploy time instead of code time.
This has proven to be very valuable to me. It allows me to use log4j in old JVM's, and logback in 1.5+ JVM's, and also java.util.logging if needed.
Logback more Java EE aware:
in general (from code to documentation) it’s keeping in mind containers – how multiple apps coexist, how class loaders implemented etc. Contexts for loggers, JNDI, JMX configuration included etc.
from developer prospective almost same, Logback adds
Parameterized logging (no need to use if(logger.isDebugEnabled()) to avoid string concatenation overhead )
Log4j – only giant plus is old JVM support, small (IMO)
NDC (Logback only MDC), some extensions. For example I wrote extension for configureAndWatch for Log4j, no such thing for Logback
the original log4j and logback were designed and implemented by the same guy.
several open source tools have used SLF4J. I don't see any significant deficiencies in this tool. So unless you have a lot extensions to log4j in your codebase, I would go ahead with logback.
I would think that your decision should come down to the same one it would if you were deciding between using log4j or Jakarta Commons Logging - are you developing a library which will be included in other applications? If so, then it doesn't seem fair to force users of your library to also use your logging library of choice.
If the answer is no, I would just go with what is simpler to add and what you are more comfortable with. Sounds like logback is just as extensible and reliable as log4j, so if you're comfortable using it, go ahead.
I'm not familiar with SLF4J, and I've only taken a brief look at logback, but two things come to mind.
First, why are you excluding a tool from examination? I think it's important to keep an open mind and examine all possibilities to choose the best one.
Second, I think that in some projects one tool is a better than another tool, and the opposite might be true in a different project. I don't think that one tool is always better than another tool. There is, after all, no silver bullet.
To answer your question - Yes and no. It depends on the project, and how familiar the team is with one tool. I wouldn't say "don't use log4j" if the entire team is very comfortable with it, it meets all the needs, and logback doesn't offer anything that we need to complete the task.

Categories