- Overview
-
Table of Contents
- J2SE: Standard Java
- Java Windows NT Services
- Apache Velocity
- Advanced J2SE
- Bytecode Instrumentation
- Dynamic Languages and the JVM
- J2SE 1.5.0: "Tiger"
- Java SE 6
- Java 7
- Core Computer Science Principles in Java (Data Structures)
- Annotations
- Java Generics
- Java New I/O
- Java Sound
- Java Applets
- JavaFX
- Java SE Threading
- Resource Management Using Semaphores
- Java Atomic Operations
- JavaTemplate Pages
- Executing Templates with the JtpExecutor
- Java Cryptography Extensions (JCE)
- Java Database Connectivity (JDBC) API
- Jakarta Commons - Net Class Library
- Jakarta Commons HttpClient
- Apache POI
- Regular Expressions
- JavaMail
- Cool Tools
- Building an Really Simple Syndication (RSS) Java App
- Embedding JavaScript in Java with Rhino
-
Logging with Log4J
- Installing and Setting up Log4J
- Hierarchical Logging
- Appenders
- Chainsaw
- Summary
- Inside Swing
- Swing Components
- SwingX
- Swing Styled Documents
- Web Rendering in Java Swing Applications
- Java Look-and-Feel Graphics Repository
- Java Media Framework
- Quicktime for Java
- Media in Java Review 2008
- External Multimedia in Java
- Graphs and Charts
- Holiday Special: Electronic Greeting Card
- Media Framework: Presenter Application
- Standard Widget Toolkit
- JFace
- Java Performance Tuning
- J2EE Performance Tuning
- Caches and Pools
- Java Caching System
- EHCache
- Java Compression and Decompression
- Obfuscating Java Applications
- Continuous Integration
- Load Testing
- Tomcat Clustering
- High Scalability with Terracotta
- Troubleshooting Production Performance Issues
- Enterprise Java Testing
- Automated Unit Testing with JUnit and Ant
- Unit Testing: Tips From The Trenches
- Custom Ant Tasks
- Extensible Markup Language (XML)
- Java Web Technologies
- Web Frameworks
- Struts 2
- Wicket
- JavaServer Faces
- Distributed Programming / RMI
- Behavior Tracking Servlet Filter
- Servlet Filters
- Building a Robust Java Server
- J2EE: Enterprise Java
- Spring
- Spring 3
- Java Design Patterns
- Model-Driven Architecture
- Enterprise Messaging with ActiveMQ
- Event-Driven Architecture
- XDoclet
- Hibernate
- Developing Standalone Database Applications with Hypersonic DB
- Project Backup
- J2EE Project: Hands-On
- Enterprise Java Beans (EJB) 3.0
- Disaster Recovery
- Java Management Extensions (JMX)
- Service-Oriented Architecture
- Web Services
- RESTful Web Services
- Web Services with Apache CXF
- Atom Syndication
- Project: Building a Web Photo Gallery
- J2ME: Micro Java
- Specialized J2ME
- Optional Packages
- Other Java Technologies
- Derivatives and Competitors
- Java, Engineered for Integration
-
Additional Resources
- The World of Java Tools
- Building Java Applications with Ant
- Managing Java Build Lifecycles with Maven
- Acceptance Testing with FitNesse
- Source Control with Subversion
- Inversion of Control and Dependency Injection
- Certification
- Roadmap: Becoming an Enterprise Java Developer
- Roadmap: Becoming an Enterprise Java Developer in 2007
- The Business of Enterprise Software
- JavaOne 2006
- JavaOne 2007
- JavaOne 2008 Wrap-Up
- JavaOne 2009 Wrap-Up
- JavaOne 2010
- JavaOne 2011
- How to Survive in a Turbulent Job Market
- How to Hire the Best Talent
- Unified Modeling Language (UML)
- Cloud Computing
- Amazon EC2 and Java
- MongoDB
- Enterprise Java in 2008 and Beyond
- Predictions for 2018
Hierarchical Logging
Last updated Mar 14, 2003.
An important distinction between manual logging and adopting a logging system is that a logging system can enable or disable logging statements external to the application itself. A powerful feature of Log4j specifically is that logging can be enabled and disabled in a hierarchical manner. Log4j defines a named hierarchy of loggers as follows (extracted from the Log4j manual):
“A logger is said to be an ancestor of another logger if its name followed by a dot is a prefix of the descendant logger name. A logger is said to be a parent of a child logger if there are no ancestors between itself and the descendant logger.”
In other words, there is a parent/child relationship defined for loggers by their names. Traditionally we name loggers based upon the class name that is generating log messages. For example, the class com.geekcap.app1.MyApplication would have a logger defined with the name “com.geekcap.app1.MyApplication” and the class com.geekcap.app2.MyOtherApplication would have a logger defined with the name “com.geekcap.app2.MyOtherApplication.” Log4j allows the configuration of logging levels based upon a dot-based named hierarchy. This means that you can configure debug statements to be logged for the following loggers:
com.geekcap=DEBUG
The com.geekcap.app1.MyApplication and com.geekcap.app2.MyOtherApplication loggers would both inherit the “DEBUG” level because they are children of the com.geekcap logger. Furthermore, if you were to define a different configuration for app1, such as:
com.geekcap.app1=TRACE
Then all classes in the com.geekcap.app1 package, and its sub packages, would instead log trace messages. The point is that you can control what is logged and where it is logged to at a very fine granularity.
Additionally there is a root logger, named rootLogger, from which all other loggers inherit. The rootLogger defines the logging granularity and the various appenders (see the next section) for the application as a whole. So you can configure your root logger with a default configuration and then add additional logging as needed. For example, if your application is logging errors in the com.geekcap.app1.ComplicatedStuff logger, then instead of logging at an information level, you can log trace messages for just that logger. The following log4j snippet illustrates this:
log4j.rootLogger=INFO, A1 log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n log4j.logger.com.geekcap.app1.ComplicatedStuff=TRACE
I discuss appenders and layouts below, but the important thing to notice here is that the root logger, from which all loggers inherit, is defined to log INFO messages, but the ComplicatedStuff logger is defined to log TRACE messages. This enables you to diagnose problematic code without negatively affecting the performance of the entire application.
