How to set up a common logging framework - java

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.

Related

Embedded Jetty and Complex Logging

Jetty 9 is used for the embedded server and everything works well. One thing that remains is the logging issue.
Prior to that mvn:jetty-run brings his own logging setup with it and logs to the console. That is good for development. In the production environment we need something more special.
Currently on start-up the SLF4J complains about, that there is no binding available, so we can chose freely.
That is what we want to archive:
We need to log to the console if we are starting in a non-production environment.
In the production environment the logging should be done in a single log-file but on a daily rotation with the naming schema: logs/logname-date.log (e.g. logs/application-20130926.log)
We distinguish between the production and non-production mode using a command line argument '-production'.
Since the jetty server is embedded I would love to have a solution which we can fully configure the logger without the need to manage xml or properties-files taking the logging configuration aspect out of the deployment process.
So what options do we have and how can we do this in the best possible way?
Update: It seems that logback is the way to go. It has support for the logfile rotation and also makes it possible to use a console output. The difficult question remaining is how to do this programatically and without additional files.
You have hundreds of configuration options here.
You will need to know a few things about your application before you can pick an appropriate configuration here.
How are logging events emitted from your code? the jetty server? and all 3rd party libraries?
Then you want to answer, what logging framework do you want to handle output (to disk, and to console) portions of the logging architecture?
This is documented at Jetty:
http://www.eclipse.org/jetty/documentation/current/example-logging-logback-centralized.html
Yes, that documentation isn't for embedded mode, but it is still relevant.
Your required logging jar files:
The basic api jar:
slf4j-api.jar (required, no matter what you choose below)
The log capturing jars:
(pick [0..n] jars here)
log4j-over-slf4j.jar (slf4j handling of log4j events)
jul-to-slf4j.jar (slf4j handling of java.util.logging events)
jcl-over-slf4j.jar (slf4j handling of jakarta commons-logging events)
The log output jars:
Pick only 1 of the following output jars:
slf4j-simple.jar (this is a super simple logging implementation, not suitable for production)
logback-classic.jar (slf4j's own output logging framework)
also requires logback-core.jar
slf4j-log4j12.jar (route slf4j events to log4j for processing)
also requires log4j.jar
do not use if using log4j-over-slf4j.jar from above
slf4j-jdk14.jar (route slf4j events to java.util.logging for processing)
do not use if using jul-to-slf4j.jar from above
slf4j-nop.jar (route slf4j events to nowhere, silently discard them)
slf4j-jcl.jar (route slf4j events to jakarta commons-logging)
also requires commons-logging.jar and your choice of commons-logging implementation.
do not use if using jcl-over-slf4j.jar from above
Configure it all:
Be sure you read the slf4j manual on each of these jars, as there is sometimes some extra setup details you might need to know about.
For your described situation, the most appropriate output jars would be logback-classic.jar or slf4j-log4j12.jar. As for configuring the output, you would need to rely on the documentation that those libraries provide.
Logback Documentation
Log4j Wiki
So finally here is the complete picture.
After all the logging configuration in a programmatic way is just described here: http://logback.qos.ch/manual/configuration.html#joranDirectly
I use the logback API just as stated by Joakim. Once you learn how to program it programmatically using the JoranConfigurator object everything is quite easy. Play with it and you get the picture.
I managed to accomplished all tasks at hand.
Thanks for the help Joakim. I was missing the JoranConfigurator thingy. Thanks!
Update:
I used a StringReader and embedded the xml configuration file directly in the Logging configuration class. This way I dont have to manage additional files and logging works as expected.

Why would someone select/change a specific logging framework at deployment time?

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...

Logback native VS Logback via SLF4J

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.

Difference in using java.util.logging and Log4j Loggers

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.

Logging using SL4J, Jakarta Commons logging, log4j for third party libraries and my own code

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

Categories