Anyone familiar with Log4j?

Posted on 2004-10-15
Medium Priority
Last Modified: 2010-05-18

I'm trying to learn to use log4j but I'm wondering about something.

Here's an excerpt from the manual:

For example, in

   Logger x = Logger.getLogger("wombat");
   Logger y = Logger.getLogger("wombat");

x and y refer to exactly the same logger object.

Do you think this kind of thing is safe to use in web applications? I don't quite understand how this works. I mean is it creating this "wombat" object unique to the application or to the VM?

If to the VM then won't this cause problems? Or at least performance problems?
Question by:ycomp
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
  • +2
LVL 92

Expert Comment

ID: 12317103
neither I think. its unique to the class loader from memory.

Author Comment

ID: 12317159
where can I find a description on how class loaders work?

I mean if I have a servlet and the servlet has 10 requests being handled will they all use the same logger "wombat" object? Or 10 of them?

If the same then don't they have to be synchronized or something? Wouldn't that affect performance?

But I guess if it is a web application you want it all logging to the same file or console, right?

So my question really is just how it affects performance if the requests are syncrhonized or something.

Author Comment

ID: 12317167
I hope some of that made sense... I'm way to tired now.
Get real performance insights from real users

Key features:
- Total Pages Views and Load times
- Top Pages Viewed and Load Times
- Real Time Site Page Build Performance
- Users’ Browser and Platform Performance
- Geographic User Breakdown
- And more

LVL 11

Expert Comment

ID: 12317190
we use JBoss, which uses log4j for logging, so we have used this for our application logging also. Our "application" is split into several logical components, each represented by an EAR file, so logically each component is a seperate "application". This said, there is common code between these components, some of which generate logging. Since we use the same log4j configuration that JBoss uses, i.e. a single configuration XML file for the entire JVM, all the configuration is in a single place - we have never seen any problems with performance, or Class Loader problems with this configuration.

I'd say its safe to trust the "magic" of log4j, or at least until you feel you have to consider it for performance reasons....

Take care however, you can actually setup your log4j configuration in such a way so as to kill an application (or at least, the part that does logging) - log output can be formatted using a PatternLayout class, that can be configured to output the full class/method information for each log call (it calculates it using Stack Trace at the log time!) - using this can be great for debugging (especially if you use something other than the class as the "name" for the logger (I mean not : public class MyClass { static Logger log = Logger.getLogger( MyClass.class ); })) but it could have a performance impact (we use DEBUG level for very fine debugging type logging, but have it turned off by default, turning it on for certain classes can generate many megs of log in a minute or so!!! If we used the Class/Method identification formatting for this it would kill the application (actually, turning on DEBUG with very plain formatting still has a degredation effect, since a lot of log is being outputted, but as I said, its turned off by default...

LVL 92

Expert Comment

ID: 12317225

Expert Comment

ID: 12335229
Well, Here goes, some quick overview of Log4J:
First of all, Im no expert, I used it twice a week ago, but got the basic hang of it....

Log4J uses 3 main modules: A logger, an appender and a style (or layout).

The logger is the container, this is where the messages will get "stored" and its
the controller of it all.

The appender defines how you want to "print" the messages, there are appenders
to put the messages in a Database, an appender to put the msg in files, print in console, etc..

The layout defines how the appender will format the data (data like sys time, thread, logger
that triggered the log, the message itself, etc..)

For example, if you want a Logger that prints and created an HTML table, you will need a logger
with a FileAppender and the HTMLLayout. (Messages goes into file with HTML format)

By standard (I think)  the String that goes into this method:
Logger x = Logger.getLogger("wombat");
Should be the class's package where the Logger is instantiated.
Like this:

package com.here.there;

public class thisClass (xxx)
Logger x = Logger.getLogger("com.here.there.thisClass");

Im not ay work right now, if you want, I can give you the links I used to learn Log4J
tomorrow, if you think objects' links are enough, dont worry about it
(I havent looked at them, IMHO) but I guess they are good enough.

About safety, I dont know how secure your databases are, but you could make a JDBCAppender
and store logs there, if you want some more security (Im not 100% sure about this, Im
starting to study JMS this week), you can add extra security to your messages by logging
the logs in a JMS server instead of using Log4J...*shrug*

Hope this helped.

Expert Comment

ID: 12336523
if u r developing any application and want to use the log4j across yr applicaition then i can suggest u to do this

1) define the settings in log4j.properties file...
2) develop a common class for the logging ( i suggest to make it as static )
3) import the class and use it in all yr classes.

I already gave a clear example about the config file and the logger class also...

i think the quesion no is Q_21165751.html

Check it out...

LVL 11

Accepted Solution

cjjclifford earned 2000 total points
ID: 12337312
Do not use a single class to dispatch logging as nadhuvi suggests - the power of Log4J really comes into play when there are many Loggers, as the output can display the logger's name, and also the logging can be controlled for each Logger seperately.
Generally, the way to do it is to create a single class attribute (static) for logging, giving the class itself as the name for the Logger:

class MyClass {
    static Logger log = Logger.getLogger( MyClass.class );
    public MyClass() {
        log.info( "Constructed" );

in this way, the output for this log can be formatted to identify the class, and logging can be turned on/off at different levels for different classes (and even packages - Log4J manages Logger instances in a hierarchical manner, so turning on DEBUG for package "com.exchange.programming" will also turn on for the subpackage "com.exchange.programming.java"

Note, you might be tempted to wrap Log4J with a single static class, which takes a name, and the log information:

// this looks tempting, doesn't it!
class Log {
    public static void info( Object name, Object log ) {
        Logger( name ).info( log );

which could be used like:

class MyClass {
    public MyClass() {
        Log.info( MyClass.class, "Constructed" );

this counter-example will generate the equivalent output as the suggested one above - HOWEVER, this is BAD, BAD, BAD, as each time a log is generated with this wrapper, a relateively expensive lookup within Log4J to find the correct Logger is performed... Obviously expensive operations that can be avoided with a simple static attribute are definitely desirable...

See the articles posted by "objects" regarding wrapping Log4J, etc.

Hope this is clear (probably as clear as mud....)

LVL 11

Expert Comment

ID: 12546653
thanks :-)

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
Suggested Courses
Course of the Month13 days, 2 hours left to enroll

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question