The way I do it is to put the code that initializes log4j in one of my servlet's init()method and have that servlet set to initialize at startup. The main command you need to execute is: PropertyConfigurator.configureAndWatch(propFile);
I then put an instance variable in each servlet like this:
The Category class has been deprecated and has been replaced with Logger see "preparing for log4j 1.3 ". It will compile and work fine with Category right now, but Category will be removed at some point (it sounds like it will happen in 1.3 that is currently in progress).
So, you can replace this: Category logger = Logger.getInstance("myinstance");
with this: Logger logger = Logger.getLogger("com.foo");
Also, it isn't absolutely necessary to configure log4 in the code. log4j will look for log4j.xml, then log4j.properties in the classpath. You could use configure() instead of configureAndWatch() (see log4j short manual). The watch part of configureAndWatch means it is supposed to check periodically to see if the properties file changed. Some people have had some threading issues with that. Your mileage may vary.
From the log4j API documentation:
public static void configureAndWatch(String configFilename, long delay)
Read the configuration file configFilename if it exists. Moreover, a thread will be created that will periodically check if configFilename has been created or modified. The period is determined by the delay argument. If a change or file creation is detected, then configFilename is read to configure log4j.
The LogFactory usage (e.g. Log myLog = LogFactory.getLog(logName) ) is from commons logging package which can be configured to log using log4j. Log4j developer Ceki G�lc� has strong feelings about using commons logging, see Think Again - log4j vs. commons article. I've always used log4j directly.