Download (direct link):
39 m_log.fine("This is a test for fine");
40 m_log.info("This is a test for info");
41 m_log.warning("This is a warning test");
42 m_log.severe("This is a severe test");
46 * A very simple example, where we will optionally
47 * pass in the level of granularity to our application
48 * /
49 public static void main(String args)
51 Level loglevel = Level.INFO;
53 if ( args.length !=0 )
55 if ( args.equals("ALL") )
57 loglevel = Level.ALL;
59 else if ( args.equals("FINE") )
61 loglevel = Level.FINE;
63 else if ( args.equals("FINEST") )
65 loglevel = Level.FINEST;
67 else if ( args.equals("WARNING") )
69 loglevel = Level.WARNING;
71 else if ( args.equals("SEVERE") )
73 loglevel = Level.SEVERE;
77 BadLoggerExample2 logex = new BadLoggerExample2(loglevel);
Listing 5.2 (continued)
50 Item 5
This time, we see the same output as before when we pass in the FINE argument, but a log file is generated, showing the XML output, shown in Listing 5.3! Now, standard error prints out the same seemingly incorrect thing as before, not showing the FINE test, and the FileHandler seems to write the correct output. What is going on? Why does the file output not match the output written to standard error?
<?xml version="1.0" encoding="windows-1252" standalone="no"?> <!DOCTYPE log SYSTEM "logger.dtd">
<message>This is a test for fine</message>
... <logger> <class>, <method> and <thread> elements same as above ...
<message>This is a test for info</message>
<message>This is a warning test</message>
<message>This is a severe test</message>
Listing 5.3 XML-formatted output from FileHandler
Avoiding Granularity Pitfalls in java.util.logging 51
Parent Logger Log Messages higher than and equal to Handler
Granularity A Granularity A are sent to Handlers Granularity C
Log Messages higher than and equal to Granularity B are sent to Logger Parent
Log Messages higher than and equal to Granularity C are logged
Log Messages higher than and equal to
Granularity B are sent to Handlers
Log Messages higher than and equal to Granularity D are logged
Level.SEVERE / ë
Level.CONFIG RI 5 D N RAN G
Figure 5.2 Logger/handler relationship diagram.
This behavior is quite strange. What happened? There are actually three things that we need to understand in order to understand this strange behavior:
Default Configurations of Loggers and Handlers. Loggers and handlers have default configurations, read from a preference file in your JRE's lib directory. A key thing to understand is that granularities may be set for each, using the setLevel() method.
Inheritance of Loggers. Another key thing to understand about the logging API is that each logger has a parent, and all data sent to a logger will go to its parent as well. The top parent is always the Root Logger, and you can create an inheritance tree descending from the Root Logger. In our initial example in Listing 5.1, we did not set a handler, but we still had output. Why? The reason is the Root Logger had a ConsoleHandler, whose default content level is Level.INFO. You can disable sending log messages to your parent's handler by calling the setUseParentHandlers(false) on the Logger class.
The Relationship between Handlers and Loggers. As we mentioned before, there are default levels of handlers. By default, all ConsoleHandlers log at the Level.INFO level, and all FileHandlers log at the Level.ALL level. The logger itself can set its level, and you can also set the level of the handlers. The key is that the level of the handler can never show a lower level of granularity than the logger itself. For example, if the logger's level is set to Level.INFO, the attached handlers will only see Level.INFO levels and above (from our diagram in Figure 5.1). In our example in Listing 5.2, we set our logger level to Level.FINE, and because the FileHandler's level was the default level (Level.ALL), it only saw what the logger was able to pass through (FINE and below).