Reputation: 11617
I am learning the java.util.Logging API and I cannot understand why it produces redundant output, as the sample code below demonstrates:
Logger logger = Logger.getLogger("");
Logger logger1 = Logger.getLogger("1");
Logger logger1_2 = Logger.getLogger("1.2");
logger1 .addHandler(new ConsoleHandler());
logger1_2 .addHandler(new ConsoleHandler());
logger .info("msg:");
logger1 .info("msg: 1");
logger1_2 .info("msg: 1.2");
The output to the console:
14-01-2012 10:32:41 java.util.logging.LogManager$RootLogger log
INFO: msg:
14-01-2012 10:32:42 logging.LoggingExamples main
INFO: msg: 1
14-01-2012 10:32:42 logging.LoggingExamples main
INFO: msg: 1
14-01-2012 10:32:42 logging.LoggingExamples main
INFO: msg: 1.2
14-01-2012 10:32:42 logging.LoggingExamples main
INFO: msg: 1.2
14-01-2012 10:32:42 logging.LoggingExamples main
INFO: msg: 1.2
Why were the log messages passed up to the parent and the same message displayed so many times!? This is totally not efficient, and the log file will increase too fast for duplicated information. Anyone know why? Is this the nature that Logging should have?
Note: The sample code was copied from http://tutorials.jenkov.com/java-logging/logger-hierarchy.html
Upvotes: 4
Views: 2094
Reputation: 4057
I think the problem is that you are adding a handler to each of you Log instances when you should only be adding it to the top level instance.
Here is how I used java.util.Loggin in practice:
In my main class, I create a global logger from my package name:
globalLog = Logger.getLogger("thornworks");
In my main class I then add a handler to this global log (logging messages get captured by Netbeans and end up in my console window anyway, so I wanted to write the messages to a file that I can inspect later):
Date now = new Date();
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("D_hh_mm");
String logName = "[baseFilename]" + df.format(now);
File logFolder = new File(someDirectory, "logs");
try {
if(!logFolder.exists())
logFolder.mkdir();
File logFile = new File(logFolder,logName+".log");
Handler logFileHandler = new FileHandler(logFile.getAbsolutePath());
logFileHandler.setFormatter(new SimpleFormatter());
globalLog.addHandler(logFileHandler);
}
catch(java.io.IOException ioe) { /* Log file could not be created. */ }
globalLog.setLevel(Level.INFO);
Then other classes that need to do some logging create loggers off of this global logger:
For instance, fileLogger = GUI.globalLog.getLogger(FileFunction.class.getName());
The name for this logger is now thornworks.FileFunction
. Since it is a child of the parent logger, globalLog, all of the messages generated by fileLogger get passed up to globalLog. Messages generated by fileLog will indicate which class they came from because of the way I obtained the fileLogger.
Now if I change my mind about how and where I wish to store all of these logging messages, I only need to change a few lines of code in the main class and all of the logging messages in my entire application will get directed to this new location. I can also change the level of the main logger so that less messages get generated, but then increase the level of some class level logger to get more information about that portion of my code.
Upvotes: 4