Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #12750

Question about loggers

From Novice <novice@example..com>
Newsgroups comp.lang.java.programmer
Subject Question about loggers
Date 2012-03-07 21:52 +0000
Organization Your Company
Message-ID <XnsA00FACCA4B5E9jpnasty@94.75.214.39> (permalink)

Show all headers | View raw


I'm working my way through Stephen Stelting's book Robust Java and have 
some questions about the use of the Logging API (java.util.logging) in 
Chapter 5. 

My impression from the "Aspect Questions" thread was that the "best 
practices" approach to logging was to use named loggers, where, in essence, 
each method that needs to write to the log creates a named logger via 

Logger logger = Logger.getLogger(getClass().getName());

and then writes to the log.

Did I get that right? Stelting mentions anonymous loggers and the global 
logger starting on page 71.I see from the API (and by actually trying it in 
the sample program below) that the global logger is no longer a recommended 
technique but are there any common circumstances where a professional 
program would use anonymous loggers? Or are they more a case of something 
that might be used in a "sandbox" type program to try something out?

Also, Stelting mentions that you can use the LogManager to "cache Logger 
objects for repeat use". What circumstances would justify using LogManager? 
I was under the impression that simply doing Logger.getLogger() was 
perfectly adequate for a professional quality program. Why would LogManager 
be any better than simply making the logger a class variable?

I tried a little sample program that combined LogManager, an anonymous 
logger and the global logger and came up with this:

================================================================
package sandbox;

import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class LoggingTest {

public static void main(String[] args) {
    LoggingTest test = new LoggingTest();
}
    
public LoggingTest() {
        
  Logger logger = Logger.getLogger(getClass().getName());        
  logger.log(Level.INFO, "Starting the constructor");        
  System.out.println("1+1=" + (1+1));        
  calculation2();
  calculation3();      
  LogManager logManager = LogManager.getLogManager();
  Logger logger2 = Logger.getLogger(getClass().getName() + ".foo");
  logManager.addLogger(logger2);        
  calculation4();
}
    
private static void calculation2() {
        
   Logger anonymousLogger = Logger.getAnonymousLogger();        
   anonymousLogger.log(Level.INFO, "Starting the calculation2() method"); 
   System.out.println("2+2=" + (2+2));    
}
    
private static void calculation3() {
        
   @SuppressWarnings("deprecation")
   Logger globalLogger = Logger.global;        
   globalLogger.log(Level.INFO, "Starting the calculation3() method");         
   System.out.println("3+3=" + (3+3));       
}
    
private void calculation4() {
        
   LogManager logManager = LogManager.getLogManager();
   Logger logger = logManager.getLogger(getClass().getName() + ".foo"); 
   logger.log(Level.INFO, "Starting the calculation4() method"); 
   System.out.println("4+4=" + (4+4)); 
}
}

================================================================

The log records looked like this:

Date/Time
(YYYY-MM-DD-HH:MM:SS)	Sequence	Logger	Level	Class	Method	Thread
	Programmer Message	Exception Message	Exception Class	Exception 
Method	Exception Line
2012-03-07-16:27:52	0	sandbox.LoggingTest	INFO	sandbox.LoggingTest
	<init>	10	Starting the constructor	N/A	
2012-03-07-16:27:52	1		INFO	sandbox.LoggingTest	calculation2
	10	Starting the calculation2() method	N/A	
2012-03-07-16:27:52	2	global	INFO	sandbox.LoggingTest
	calculation3	10	Starting the calculation3() method	N/A	
2012-03-07-16:27:52	3	sandbox.LoggingTest.foo	INFO
	sandbox.LoggingTest	calculation4	10	Starting the calculation4() 
method	N/A	


Then, I wrote a version using a named logger and a single class variable 
and the whole thing looks a lot simpler and cleaner:

====================================================================
package sandbox;

import java.util.logging.Level;
import java.util.logging.Logger;

public class LoggingTest2 {

  Logger logger = null;
    
public static void main(String[] args) {
        
   LoggingTest2 test = new LoggingTest2();
}
    
public LoggingTest2() {
        
  this.logger = Logger.getLogger(getClass().getName());
  this.logger.log(Level.INFO, "Starting the constructor");        
  System.out.println("1+1=" + (1+1));
  calculation2();
  calculation3();        
  calculation4();
}
    
private void calculation2() {
                
  this.logger.log(Level.INFO, "Starting the calculation2() method");
  System.out.println("2+2=" + (2+2)); 
}
    
private void calculation3() {
                
   this.logger.log(Level.INFO, "Starting the calculation3() method");
   System.out.println("3+3=" + (3+3)); 
}
    
private void calculation4() {
        
  this.logger.log(Level.INFO, "Starting the calculation4() method");  
   System.out.println("4+4=" + (4+4));     
}

}
====================================================================

The log records from that look very similar except that the logger name is 
always "sandbox.LoggingTest2":

Date/Time
(YYYY-MM-DD-HH:MM:SS)	Sequence	Logger	Level	Class	Method	Thread
	Programmer Message	Exception Message	Exception Class	Exception 
Method	Exception Line
2012-03-07-16:31:13	0	sandbox.LoggingTest2	INFO	sandbox.LoggingTest2
	<init>	10	Starting the constructor	N/A	
2012-03-07-16:31:13	1	sandbox.LoggingTest2	INFO	sandbox.LoggingTest2
	calculation2	10	Starting the calculation2() method	N/A	
2012-03-07-16:31:13	2	sandbox.LoggingTest2	INFO	sandbox.LoggingTest2
	calculation3	10	Starting the calculation3() method	N/A	
2012-03-07-16:31:13	3	sandbox.LoggingTest2	INFO	sandbox.LoggingTest2
	calculation4	10	Starting the calculation4() method	N/A	

For my money, my way is at least as good as Stelting's way and considerably 
more concise. The only obvious negative to my approach was the class 
variable named 'logger'. I know that class variables are something we want 
to avoid whenever we can. But just how bad is it for me to create a single 
logger as a class variable? Wouldn't I even be helping my performance to 
have the logger be a class variable, especially as the number of methods 
that were logging increased? After all, I'd only be creating one logger per 
class rather than one for each method that was logging.

I'm worried that I'm fooling myself here and missing some big objection to 
doing logging the way LoggingTest2 does it. After all, Stelting has 
presumably been writing error handling code correctly for years while I 
have only been doing it for days. But I'm not seeing any obvious problems 
to my approach, which is essentially the same as what everyone recommended 
in the other thread except that I've made the logger a class variable. 

Can someone enlighten me? I'm leaning towards implementing either the 
technique shown in LoggingTest2 or, if the class variable really is a very 
bad idea, using Logger.getLogger() locally in each method to get the 
logger.

-- 
Novice

Back to comp.lang.java.programmer | Previous | NextNext in thread | Find similar


Thread

Question about loggers Novice <novice@example..com> - 2012-03-07 21:52 +0000
  Re: Question about loggers Arne Vajhøj <arne@vajhoej.dk> - 2012-03-07 17:16 -0500
    Re: Question about loggers Novice <novice@example..com> - 2012-03-07 23:57 +0000
      Re: Question about loggers Arne Vajhøj <arne@vajhoej.dk> - 2012-03-07 19:24 -0500
        Re: Question about loggers Lew <noone@lewscanon.com> - 2012-03-08 07:22 -0800
          Re: Question about loggers Arne Vajhøj <arne@vajhoej.dk> - 2012-03-08 10:27 -0500
            Re: Question about loggers Lew <lewbloch@gmail.com> - 2012-03-08 11:58 -0800
              Re: Question about loggers Arne Vajhøj <arne@vajhoej.dk> - 2012-03-08 15:49 -0500
          Re: Question about loggers Robert Klemme <shortcutter@googlemail.com> - 2012-03-08 08:15 -0800
            Re: Question about loggers markspace <-@.> - 2012-03-08 10:05 -0800
              Re: Question about loggers Arne Vajhøj <arne@vajhoej.dk> - 2012-03-08 13:50 -0500
              Re: Question about loggers Robert Klemme <shortcutter@googlemail.com> - 2012-03-09 07:11 -0800
                Re: Question about loggers Lew <noone@lewscanon.com> - 2012-03-09 07:45 -0800
                Re: Question about loggers markspace <-@.> - 2012-03-09 07:54 -0800
                Re: Question about loggers Arne Vajhøj <arne@vajhoej.dk> - 2012-03-09 11:03 -0500
                Re: Question about loggers markspace <-@.> - 2012-03-09 09:10 -0800
                Re: Question about loggers Arne Vajhøj <arne@vajhoej.dk> - 2012-03-09 12:27 -0500
                Re: Question about loggers Lew <lewbloch@gmail.com> - 2012-03-09 10:56 -0800
                Re: Question about loggers Robert Klemme <shortcutter@googlemail.com> - 2012-03-09 20:29 +0100
                Re: Question about loggers Arne Vajhøj <arne@vajhoej.dk> - 2012-03-09 11:04 -0500
                Re: Question about loggers markspace <-@.> - 2012-03-09 09:14 -0800
                Re: Question about loggers Arne Vajhøj <arne@vajhoej.dk> - 2012-03-09 12:22 -0500
                Re: Question about loggers Lew <lewbloch@gmail.com> - 2012-03-09 10:58 -0800
  Re: Question about loggers markspace <-@.> - 2012-03-07 15:21 -0800
    Re: Question about loggers Novice <novice@example..com> - 2012-03-08 00:01 +0000
    Re: Question about loggers Arne Vajhøj <arne@vajhoej.dk> - 2012-03-07 19:21 -0500
      Re: Question about loggers Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-03-08 06:18 -0400

csiph-web