Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Log4j delivers control over logging

The open source log4j API for Java offers fast, efficient log services

  • Print
  • Feedback

Page 5 of 5

Nevertheless, the user should be aware of the following performance issues:

  1. Logging performance when logging is turned off.

    When logging is turned off entirely or for a set of priorities, the cost of a log request is a method invocation plus an integer comparison. The method invocation involves the hidden cost of parameter construction.

    For some category cat, writing

       cat.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
    


    incurs the cost of constructing the message parameter that is converting both integer i and entry[i] to a String and concatenating intermediate strings, regardless of whether the message will be logged or not.

    If one is worried about speed, then write:

       if(cat.isDebugEnabled() {
          cat.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
       }
    


    That will not incur the cost of parameter construction if debugging is disabled. On the other hand, if the category is debug enabled, it will twice incur the cost of evaluating whether the category is enabled or not: once in debugEnabled() and once in debug(). That represents an insignificant overhead because evaluating a category takes about 1 percent of the time it takes to actually log.

    In log4j, logging requests are made to instances of the Category class. Because Category is a class and not an interface, the cost of method invocation is arguably lower but at the cost of some flexibility.

    On a 233 MHz Pentium II machine, the typical cost of logging when logging is turned off is in the range of 5 to 50 nanoseconds.

  2. The performance of deciding whether to log or not to log when logging is turned on.

    Under that scenario, the question centers on the performance cost of walking the category hierarchy. When logging is turned on, log4j still needs to compare the priority of the log request with the priority of the request category. However, categories may not have an assigned priority; they can inherit them from the category hierarchy. Thus, to discover its priority, the category may need to search its ancestors.

    A serious effort has been made to make that hierarchy walk as fast as possible. For example, child categories link only to their existing ancestors. In the BasicConfigurator example shown earlier, the category named com.foo.Bar links directly to the root category, thereby circumventing the nonexistent com or com.foo categories, significantly improving the speed of the walk, especially in sparse hierarchies.

    The typical cost of walking the hierarchy is in the range of 5 to 15 microseconds, again on a 233 MHz Pentium II machine.

  3. Actual logging.

    Another performance issue stems from the cost of formatting the log output and sending it to its target destination. Here again, a serious effort was made to make layouts (formatters) perform as quickly as possible. The same is true for appenders. The typical cost of actually logging ranges from about 100 to 300 microseconds.



Although log4j has a many features, its first design goal was speed. Some log4j components have been rewritten many times to improve performance. Nevertheless, contributors frequently come up with new optimizations.

Sun's upcoming logging API

Sun has initiated JSR47 in the Java Community Process (JCP) to define a logging API for Java. The resulting API will require JDK version 1.4 and should soon become ready for public review.

The JSR47 API and log4j are quite similar at the architectural level. The JSR47 API will support a hierarchical namespace, one of the central features of log4j. On the other hand, log4j possesses many useful features missing in JSR47. Given the momentum behind log4j, in my partisan opinion, JSR47 is likely to be obsolete by the time it launches. Log4j is written by the people who use it, not by a closed committee.

By the way, log4j already provides support for bridging into the JSR47 API when the latter becomes available.

Let me also mention JLog, another logging API available from IBM's alphaWorks. JLog was previously named the RAS Toolkit until IBM renamed it. On the alphaWorks site JLog has the label "Logging Toolkit for Java," almost the same label that log4j had on alphaWorks before it migrated to http://log4j.org. JLog, while a good logging package, should not be confused with log4j.

Conclusion

Log4j is a popular logging package written in Java. One of its distinctive features includes the notion of inheritance in categories. Using a category hierarchy, it is possible to control which log statements are output at arbitrary granularity, thus reducing the volume of logged output and minimizing the cost of logging.

One of the advantages of the log4j API is its manageability. Once the log statements have been inserted into the code, they can be controlled with configuration files. Moreover, they can be selectively enabled or disabled, and sent to different and multiple output targets in user-chosen formats. Further, the log4j package is designed so that log statements can remain in shipped code without incurring a heavy performance cost.

Log4j is the result of a collective effort. My special thanks go to all the authors who have contributed to the project. Without exception, the best features in the package have all originated in the user community.

  • Print
  • Feedback

Resources