views:

49

answers:

2

I'm new to Servlet containers and have created a web application using Tomcat 6.0.26. I have 'TODO: log' scattered throughout my code. I see there exists:

myServlet.getServletContext().log()

which appears to write to a file prefixed with 'localhost' in the Tomcat '/logs' directory. I don't need any advanced logging capability, but I'd like a date, time, message and stack trace at minimum. In addition, I've created some classes used by my various servlets that need logging capabilities as well. Do I need to inject a SevletContext into these classes so they can log?

It appears that log4j from Apache is a popular logging package, but I'm not sure if it worth the trouble of setting it up.

What would be the recommended way of logging for my needs?

+2  A: 

You don't want to tie up all your business and data access code with the ServletContext (I of course assume that your business and DB code is not tight coupled inside a servlet class, but just live in their own layer of classes, without any javax.servlet references). So I wouldn't recommend to use ServletContext#log(). It's also very seldom used in real world.

You're right that log4j is popular, even though it's been succeeded by logback. Setting up log4j doesn't need to be that troublesome. I suggest to start with a properties file which is less hard to understand than a XML file. You can always upgrade to a XML file once you understand what's going on in log4j configuration.

Create a file named log4j.properties, put it somewhere in the root of the classpath, e.g. /WEB-INF/classes (or if you're using an IDE, the root of the src folder, it will eventually land in the right place). You can also keep it outside the webapp and add its path to the server's runtime classpath by specifying its path in shared.loader property of Tomcat/conf/catalina.properties. Finally fill it as follows:

# Set root logger level and appender name.
log4j.rootLogger = TRACE, console

# Specify appenders.
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.file = org.apache.log4j.DailyRollingFileAppender

# Configure console appender.
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = %d{ABSOLUTE} [%t] %-5p %m%n

# Configure file appender.
log4j.appender.file.File = /webapp/logs/web.log
log4j.appender.file.DatePattern = '.'yyyy-MM-dd
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %d{ABSOLUTE} [%t] %-5p %m%n

This kickoff example by default logs at a level of TRACE. You can change it to DEBUG or INFO like so:

# Set root logger level and appender name.
log4j.rootLogger = INFO, console

This example also by default uses the console appender. It will log to the standard output as it is configured by Tomcat which by default lands in the /logs/localhost.yyyy-MM-dd.log file.

You can however change it to use the file appender like so:

# Set root logger level and appender name.
log4j.rootLogger = INFO, file

The ConversionPattern settings can be found in detail in the PatternLayout javadoc.

Hope this helps to get you started.

BalusC
Thanks for the info. The main disconnect I have in understanding how to use Log4j is how to use it from code. How do I use it in a Servlet, in beans, in POJOs? Do I need to create a Log4j instance, then find and parse the properties or XML file?
Wilson
Just use `Logger#getLogger()` and then `debug()`, `info()`, etc methods. You don't need to find and parse it everytime. If it's in the classpath, log4j will do it itselves. It's indeed a common problem among starters because they don't understand "classpath".
BalusC
+2  A: 

In addition to all the stuff BalusC has mentioned above, in your java code (servlets/beans/whatever) just import and initialize the Logger

package my.app;

import org.apache.log4j.Logger;

private static Logger logger = Logger.getLogger("classname");
// use any string you want 

Then at any logging point you can log at various levels like

if (logger.isDebugEnabled()) {
            logger.debug("Some log at this point");
        }

...

logger.info("Some info message here");

These will appear in the logs depending on whether you set DEBUG or INFO in the log4j.propeties

Take a look at the examples on http://www.java2s.com/Code/Java/Language-Basics/Examplelog4jConfigurationFile.htm and all the Related examples in the same article

JoseK
Thanks for the help. I couldn't seem to find this connecting piece of the puzzle.As an aside, is there a reason the logging facility built into the JDK isn't used more frequently?
Wilson
@Wilson - more on that debate http://stackoverflow.com/questions/31840/java-logging-vs-log4j and http://stackoverflow.com/questions/582428/java-util-logging-logger-and-log4j
JoseK