I am developing a java application for which i have to use a logging mechanism. And now i am confused to choose either java libraries logger or to go for Log4j logger.
So i want to know when i can go for java logger
and when i can go for log4j logger.
I'd suggest you go with SLF4J instead to decouple your application from specific logging frameworks. It has adapters for various popular logging frameworks such as Jakarta Logging, JDK1.4 logging, log4j etc. making it a good abstraction for logging needs.
Logger class was not part of jdk earlier on, so several library implementations sprung up. The Log4j library has one of the most comprehensive set of logging utilities (Formatters, Appenders etc). However, for most developers this would be an overkill and the simple java.util.Logger would suffice.
I personally use a custom wrapper over my logger implementation. This enables me to define custom calls to carry out functional logging/auditing.
There are the Apache Commoms Logging project and SLF4J, either of which abstracts the underlying logging library.
In practice I tend to use Log4J over the built in logging classes. Mainly because Log4J can be configured per web-app in an application server, whereas JDK logging is configured per JVM.
The approach I would currently recommend is to use SLF4J as the logging API. You can then pick your logging framework depending on your needs as you discover them.
I did a writeup on what I consider to be best practice in getting started with SLF4J and a simple "log to System.out" which is currently placed at. http://runjva.appspot.com/logging101/index.html
Hopefully it is helpful.
I find Log4j more flexible when it comes to tweaking the logging cfg without re-compiling code in production environment.
Related
I have written a small java application. The application uses some external packages as cling, javax and weld.
In my code I used java.util.logging but the other packages uses other loggers as sl4j.
Question. Is there a way to take control over the logging environment so all packages logging in a simular way. I would like to have a simple way to change loglevel and log output.
//lg
slf4j is a logging facade behind which different logging frameworks can be used. For example log4j. You just have to throw it in the path. Log4j can then be configured as usual. There should also be a jul bridge if you want to stick with java.util.logging.
I am reading about logging using java and came across this: enter link description here
It talks about an advantage of slf4j here that:
One can select his logging framework at deployment time ==> The desired logging framework can be plugged in at deployment time by inserting the appropriate jar file (binding) on your class path.
Can someone explain to me why and where we would need this?
You're writing a generic-pupose library, which generates logs using SLF4J.
Company A uses it, and has already configured all its IT infrastructure to use log4J. They're happy that your API can also use log4J to log.
Company B uses it as well, and has already configured all its IT infrastructure to use java util logging. They're happy that your API can also use java util logging to log.
Company C uses it as well, and has already configured all its IT infrastructure to use logback. They're happy that your API can also use logback to log.
I can think of the following scenario:
Websphere uses JCL logging, if also using JCL, then you can set/modify log levels and filters at runtime.
Appserver X is more geared towards Log4J, so might be better to use that...
With SLF4J you don't need to refactor the code for the underlying logging framework to use...
I've using SLF4j as my logging framework, backed by log4j. My problem is that I am looking for a way to change the logging level for my logger at runtime.
I understand that slf4j does not permit this directly through its own API, and hence, I have to access the logging provider directly. Personally, I find this to be a huge deficiency in slf4j. So now my question is how can I determine programatically through slf4j which provider I am using? The biggest purpose of using slf4j is that you become provider agnostic - you can easily switch between your favourite logging system without having to recode anything. But now, if I have to make direct calls to log4j, I am losing that ability.
At the very least, I would like to be able to determine if I am using log4j as the provider and if so, then allow the user to switch log levels.
If I do LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME), the result is an instance of org.slf4j.impl.Log4jLoggerAdapter and not even org.apache.log4j.Logger (as I would have hoped/expected).
Is there any way to find this out?
Thanks,
Eric
SLF4J is designed as an abstraction for libraries, not applications (of course, you can and should still use SLF4J in your own app's logging calls, for consistency). In your own app, you choose the underlying logger framework, so it's fine to access the log4j API in the logging-config-specific parts.
No way should a library be mucking about with changing the logging config, IMHO, so it's not appropriate for it to be on the SLF4J API.
I have gone through the following article regarding the logging frameworks available for Java:
http://michaelandrews.typepad.com/the_technical_times/2011/04/java-logging-reconsidered.html
The author has mentioned using SLF4J with Logback. How is that different from using Logback directly. Wouldn't it be better if one uses Logback directly rather than going for SLF4J, since Logback is built on top of SLF4J.
SLF4J is adding zero overhead to Logback since it is simply the interface that is implemented by Logback without any additional layer.
You should use SLF4J simply because...
It enables you to switch away from Logback if you ever need to
It does not cost you anything, even the imports are smaller ;)
Other people will love you for using SLF4J and hate you for using a specific logging framework directly if you ever release your code into the wild.
The only place where you'd access Logback directly would be while (re)configuring your logging manually in an application. The need for this arises occasionally but even in that case, working with Logback would be restricted to a single class or even method.
As a rule of thumb: libraries should always use a logging abstraction while applications define the logging they are using, optionally accessing it directly.
SLF4J adds almost no overhead and Logback has a native bindings to it.
If you know by 100% that you will not need to switch to other logging framework in the future, go with logback native. But SLF4J allows you some abstraction and you can switch logging backends in a blink.
Logback is not build on top of SLF4J. SLF4J is an abstraction framework for logging. It doesn't do any logging itself. It just provides unified interface for logging.
I have some questions about logging, more specifically about setting it up and making sure it works.
The project I'm doing will use Wicket, Spring and Hibernate. I know that Wicket and Hibernate uses Simple Logging Facade for Java (SL4J) and that Spring is using the logging component from Apache Commons.
Will they co-exist happily?
I thought I would use log4j together with both SL4J and the logging component from Apache commons, do you think that's a good idea?
Can I set up them all to output logging data into a common file?
Or should I use separate files?
Or should I store the logging messages in the database? (I'd rather not, as I find grepping etc on text files quite convenient.)
For Spring I guess I need some kind of configuration file for the Apache Commons logging component as well where I direct it to use log4j?
When I've set these up I guess to see that everything works I set the logging level to INFO as it's fairly certain that all three of the frameworks output some information in that mode? Or is there an even better way to make sure?
And my last question. In the project I'm starting, do you recommend that I use SL4J for my own logging purposes? (I thought I would use log4j directly, but that was before I learned a little bit more about logging and a lot of respectable libraries seem to choose the path of a bridge/facade for their logging needs. And if it gets us flexibility without added cost there's no reason not to do it that way.)
I'm looking forward to hearing more from you about how you are doing your logging. It's a new area for me which I'm eager to improve myself in.
Well SLF4J is just a facade, like commons logging, which means they still need something else to work. They permit library authors to not force users into having multiple logging library and configuration. Log4j and logback are regular logging libs.
See here for more info.
SLF4J has a commons logging bridge that you can use to replace the commons logging library. I think the schema there explain the situation very well.
Now, you just need to use slf4j-logj12.jar to have commons logging and slf4j use log4j (or anything else you chose; btw, logback doesn't need an additional library to be used with slf4j) as a backing engine.
You application will thus have
jcl104-over-slf4j.jar (to bridge jakarta commons logging to slf4j)
slf4j.jar (for hibernate and others to use slf4j)
slf4j-logj12.jar (for slf4j to use log4j as a backend)
log4j.jar (for your application to use. all config will also be done here)
Here is how to redirect everything to SLF4J:
remove commons-logging.jar from your classpath. If you are using Maven and have trouble getting rid of commons-logging, see this.
put jcl-over-slf4j.jar in your classpath (it comes in the SLF4J distribution). This is a drop-in replacement that mimics JCL's classes, but calls SLF4J internally. This will take care of Spring, and any other framework that uses JCL.
Connect SLF4J to your favorite backend (Log4J, Logback...) by putting slf4j-xxx.jar in the classpath. Configure the backend to log all categories to one file, and you're done.
As for using SLF4J in your application, it is not strictly necessary. Libraries like JCL and SLF4J were originally designed for people who write libraries and do no want to lock their clients into a particular logging framework.
PS: by the way, JCL = Jakarta Commons Logging