diff --git a/xdocs/guide.xml b/xdocs/guide.xml index 7fd4a21..c5b8ca9 100644 --- a/xdocs/guide.xml +++ b/xdocs/guide.xml @@ -26,21 +26,65 @@ - +
+

+

    +
  1. Introduction
  2. +
  3. Quick Start +
      +
    1. Configuration
    2. +
    3. +Configuring The Underlying Logging System +
    4. +
    5. +Configuring Log4J +
    6. +
    +
  4. +
  5. Developing With JCL
  6. +
  7. JCL Best Practices
  8. +
  9. Best Practices (General) +
      +
    1. Code Guards
    2. +
    3. Message Priorities/Levels
    4. +
    5. Default Message Priority/Level
    6. +
    +
  10. +
  11. Best Practices (Enterprise) +
      +
    1. Logging Exceptions
    2. +
    3. When Info Level Instead of Debug?
    4. +
    5. More Control of Enterprise Exception Logging
    6. +
    7. National Language Support And Internationalization
    8. +
    +
  12. +
  13. Extending Commons Logging +
      +
    1. Contract
    2. +
    3. Creating a Log Implementation
    4. +
    5. Creating A LogFactory Implementation
    6. +
    +
  14. +
  15. Frequently Asked Questions +
      +
    1. Is JCL Thread Safe?
    2. +
    3. Why "xxxLogger does not implement Log"?
    4. +
    5. How Can I Switch Logging Levels On And Off?
    6. +
    7. How Can I Change The Logging System Configuration?
    8. +
    +
  16. +
+

+

-The Jakarta Commons Logging (JCL) provides a Log interface that -is intended to be both light-weight and independent of numerous logging toolkits. +The Jakarta Commons Logging (JCL) provides a Log interface that +is intended to be both light-weight and an independent abstraction of other logging toolkits. It provides the middleware/tooling developer with a simple logging abstraction, that allows the user (application developer) to plug in a specific logging implementation.

- -

-Familiarity with high-level details of various Logging implementations is presumed. -

- -

The Jakarta Commons Logging provides a Log interface with thin-wrapper implementations for +

JCL provides thin-wrapper Log implementations for other logging tools, including Log4J, Avalon LogKit, @@ -49,19 +93,21 @@ JDK 1.4, and an implementation of JDK 1.4 logging APIs (JSR-47) for pre-1.4 systems. The interface maps closely to Log4J and LogKit.

- -
-

-As far as possible, Commons-Logging tries to be as unobtrusive as possible. +Familiarity with high-level details of the relevant Logging implementations is presumed. +

+
+
+

+As far as possible, JCL tries to be as unobtrusive as possible. In most cases, including the (full) commons-logging.jar in the classpath -should result in Commons-Logging configuring itself in a reasonable manner. +should result in JCL configuring itself in a reasonable manner. There's a good chance that it'll guess your preferred logging system and you won't need to do any configuration at all!

-There are two base abstractions used by Commons-Logging: Log +There are two base abstractions used by JCL: Log (the basic logger) and LogFactory (which knows how to create Log instances). Using LogFactory implementations other than the default is a subject for advanced users only, so let's concentrate on configuring the default @@ -102,13 +148,85 @@ Fall back to the default simple logging wrapper

-Consult the Commons-Logging javadocs for details of the various Log +Consult the JCL javadocs for details of the various Log implementations that ship with the component. (The discovery process is also covered in more detail there.)

+ +

+The JCL SPI +can be configured to use different logging toolkits (see above). +JCL provides only a bridge for writing log messages. It does not (and will not) support any +sort of configuration API for the underlying logging system. +

+

+Configuration of the behavior of the JCL ultimately depends upon the +logging toolkit being used. Please consult the documentation for the chosen logging system. +

+ +

+Log4J is a very commonly used logging implementation (as well as being the JCL primary default), +so a few details are presented herein to get the developer/integrator going. +Please see the Log4J Home for more details +on Log4J and it's configuration. +

+

+Configure Log4J using system properties and/or a properties file: +

+
    +
  • +log4j.configuration=log4j.properties +Use this system property to specify the name of a Log4J configuration file. +If not specified, the default configuration file is log4j.properties. +
  • +
  • +log4j.rootCategory=priority [, appender]* +
  • +Set the default (root) logger priority. +
  • +log4j.logger.logger.name=priority +Set the priority for the named logger +and all loggers hierarchically lower than, or below, the +named logger. +logger.name corresponds to the parameter of +LogFactory.getLog(logger.name), +used to create the logger instance. Priorities are: +DEBUG, +INFO, +WARN, +ERROR, +or FATAL. +
    +Log4J understands hierarchical names, +enabling control by package or high-level qualifiers: +log4j.logger.org.apache.component=DEBUG +will enable debug messages for all classes in both +org.apache.component +and +org.apache.component.sub. +Likewise, setting +log4j.logger.org.apache.component=DEBUG +will enable debug message for all 'component' classes, +but not for other Jakarta projects. +
  • +
  • +log4j.appender.appender.Threshold=priority +
  • +Log4J appenders correspond to different output devices: +console, files, sockets, and others. +If appender's threshold +is less than or equal to the message priority then +the message is written by that appender. +This allows different levels of detail to be appear +at different log destinations. +For example: one can capture DEBUG (and higher) level information in a logfile, +while limiting console output to INFO (and higher). +
+
+
-
+

To use the JCL SPI from a Java class, include the following import statements: @@ -122,7 +240,7 @@ import org.apache.commons.logging.LogFactory;

-Note that some components using commons-logging may +Note that some components using JCL may either extend Log, or provide a component-specific LogFactory implementation. Review the component documentation for guidelines @@ -182,11 +300,11 @@ In addition to the logging methods, the following are provided for code guards:

-
+

-Best practices for programming/planning are presented in two categories: +Best practices for JCL are presented in two categories: General and Enterprise. -The general principles are fairly clear. Enterprise practices are a bit more involved +The general principles are fairly clear.Enterprise practices are a bit more involved and it is not always as clear as to why they are important.

@@ -199,9 +317,10 @@ Enterprise requires more effort and planning, but are strongly encouraged (if no in production level systems. Different corporate enterprises/environments have different requirements, so being flexible always helps.

- - -

+

+
+ +

Code guards are typically used to guard code that only needs to execute in support of logging, that otherwise introduces undesirable runtime overhead @@ -210,62 +329,62 @@ Examples are multiple parameters, or expressions (i.e. string + " more") for par Use the guard methods of the form log.is<Priority>() to verify that logging should be performed, before incurring the overhead of the logging method call. Yes, the logging methods will perform the same check, but only after resolving parameters. -

-
- -

+

+
+ +

It is important to ensure that log message are appropriate in content and severity. The following guidelines are suggested: -

-
    -
  • +

    +
      +
    • fatal - Severe errors that cause premature termination. Expect these to be immediately visible on a status console. See also Internationalization. -
    • -
    • +
    • +
    • error - Other runtime errors or unexpected conditions. Expect these to be immediately visible on a status console. See also Internationalization. -
    • -
    • +
    • +
    • warn - Use of deprecated APIs, poor use of API, 'almost' errors, other runtime situations that are undesirable or unexpected, but not necessarily "wrong". Expect these to be immediately visible on a status console. See also Internationalization. -
    • -
    • +
    • +
    • info - Interesting runtime events (startup/shutdown). Expect these to be immediately visible on a console, so be conservative and keep to a minimum. See also Internationalization. -
    • -
    • +
    • +
    • debug - detailed information on the flow through the system. Expect these to be written to logs only. -
    • -
    • +
    • +
    • trace - more detailed information. Expect these to be written to logs only. -
    • -
    - - -

    +

  • +
+
+ +

By default the message priority should be no lower than info. That is, by default debug message should not be seen in the logs. -

-
+

- - -

+

+
+ +

The general rule in dealing with exceptions is to assume that the user (developer using a tooling/middleware API) isn't going to follow the rules. @@ -275,9 +394,9 @@ tools necessary to demonstrate that your component works correctly, or at worst that the problem can be analyzed from your logs. For this discussion, we must make a distinction between different types of exceptions based on what kind of boundaries they cross: -

-
    -
  • +

    +
      +
    • External Boundaries - Expected Exceptions. This classification includes exceptions such as FileNotFoundException that cross API/SPI boundaries, and are exposed to the user of a component/toolkit. @@ -297,8 +416,8 @@ The assures that the log contains a record of the root cause for future analysis in the event that the exception is not caught and resolved as expected by the user's code.
      -
    • -
    • +
    • +
    • External Boundaries - Unexpected Exceptions. This classification includes exceptions such as NullPointerException that cross API/SPI boundaries, and are exposed to the user of a component/toolkit. @@ -318,14 +437,14 @@ and rethrown/wrapped as ComponentInternalError. The assures that the log contains a record of the root cause for future analysis in the event that the exception is not caught and logged/reported as expected by the user's code. -
    • -
    • +
    • +
    • Internal Boundaries. Exceptions that occur internally and are resolved internally. These should be logged when caught as debug or info messages, at the programmer's discretion. -
    • -
    • +
    • +
    • Significant Internal Boundaries. This typically only applies to middleware components that span networks or runtime processes. @@ -334,8 +453,8 @@ These should be logged when caught as info messages. Do not assume that such a (process/network) boundary will deliver exceptions to the 'other side'.
    - - + +

    You want to have exception/problem information available for first-pass problem determination in a production level @@ -382,9 +501,48 @@ Perhaps more direct support for internationalizing log messages can be introduced in a future or alternate version of the Log interface.

    +
+
+

+JCL is designed to encourage extensions to be created that add functionality. +Typically, extensions to JCL fall into two categories: +

+
    +
  • new Log implementations that provide new bridges to logging systems
  • +
  • +new LogFactory implementations that provide alternative discovery strategies +
  • +
+ +

+When creating new implementations for Log and LogFactory, +it is important to understand the implied contract between the factory +and the log implementations: +

    +
  • Life cycle +
    +The JCL LogFactory implementation must assume responsibility for +either connecting/disconnecting to a logging toolkit, +or instantiating/initializing/destroying a logging toolkit. +
    +
  • +
  • Exception handling +
    +The JCL Log interface doesn't specify any exceptions to be handled, +the implementation must catch any exceptions. +
    +
  • +
  • Multiple threads +
    +The JCL Log and LogFactory implementations must ensure +that any synchronization required by the logging toolkit +is met. +
    +
  • +
+

-
-
+

The minimum requirement to integrate with another logger is to provide an implementation of the @@ -394,7 +552,6 @@ In addition, an implementation of the can be provided to meet specific requirements for connecting to, or instantiating, a logger.

-

The default LogFactory provided by JCL can be configured to instantiate a specific implementation of the @@ -404,30 +561,8 @@ This property can be specified as a system property, or in the commons-logging.properties file, which must exist in the CLASSPATH.

-
- -

-The Jakarta Commons Logging SPI uses the -implementation of the org.apache.commons.logging.Log -interface specified by the system property -org.apache.commons.logging.Log. -If the property is not specified or the class is not available then the JCL -provides access to a default logging toolkit by searching the CLASSPATH -for the following toolkits, in order of preference: -

-
    -
  • -Log4J -
  • -
  • -JDK 1.4 -
  • -
  • -JCL SimpleLog -
  • -
-
- + +

If desired, the default implementation of the org.apache.commons.logging.LogFactory @@ -438,101 +573,6 @@ Review the Javadoc for the LogFactoryImpl.java for details.

- - -

-The JCL LogFactory implementation must assume responsibility for -either connecting/disconnecting to a logging toolkit, -or instantiating/initializing/destroying a logging toolkit. -

-
- -

-The JCL Log interface doesn't specify any exceptions to be handled, -the implementation must catch any exceptions. -

-
- -

-The JCL Log and LogFactory implementations must ensure -that any synchronization required by the logging toolkit -is met. -

-
-
- -

-The Jakarta Commons Logging (JCL) SPI -can be configured to use different logging toolkits. -

-

-Configuration of the behavior of the JCL ultimately depends upon the -logging toolkit being used. -The JCL SPI uses -Log4J -by default if it is available (in the CLASSPATH). -

- -

-As -Log4J -is the default logger, -a few details are presented herein to get the developer/integrator going. -

-

-Configure Log4J using system properties and/or a properties file: -

-
    -
  • -log4j.configuration=log4j.properties -Use this system property to specify the name of a Log4J configuration file. -If not specified, the default configuration file is log4j.properties. -
  • -
  • -log4j.rootCategory=priority [, appender]* -
  • -Set the default (root) logger priority. -
  • -log4j.logger.logger.name=priority -Set the priority for the named logger -and all loggers hierarchically lower than, or below, the -named logger. -logger.name corresponds to the parameter of -LogFactory.getLog(logger.name), -used to create the logger instance. Priorities are: -DEBUG, -INFO, -WARN, -ERROR, -or FATAL. -
    -Log4J understands hierarchical names, -enabling control by package or high-level qualifiers: -log4j.logger.org.apache.component=DEBUG -will enable debug messages for all classes in both -org.apache.component -and -org.apache.component.sub. -Likewise, setting -log4j.logger.org.apache.component=DEBUG -will enable debug message for all 'component' classes, -but not for other Jakarta projects. -
  • -
  • -log4j.appender.appender.Threshold=priority -
  • -Log4J appenders correspond to different output devices: -console, files, sockets, and others. -If appender's threshold -is less than or equal to the message priority then -the message is written by that appender. -This allows different levels of detail to be appear -at different log destinations. -For example: one can capture DEBUG (and higher) level information in a logfile, -while limiting console output to INFO (and higher). -
-
-
@@ -547,6 +587,46 @@ It would be very unusual for a logging system to be thread unsafe. Certainly, JCL is thread safe when used with the distributed Log implementations.

+ +

+Upon application startup (especially in a container environment), an exception is thrown +with message 'xxxLogger does not implement Log'! What's the cause and how can +I fix this problem? +

+

+This almost always a classloader issue. Log has been loaded by a different +classloader from the logging implementation. Please ensure that: +

+
    +
  • +all the logging classes (both Log and the logging implementations) +are deployed by the same classloader +
  • +
+
    +
  • +there is only copy of the classes to be found within the classloader hierarchy. +In application container environments this means ensuring that if the classes +are found in a parent classloader, they are not also present in the leaf classloader +associated with the application. +So, if the jar is deployed within the root classloader of the container then it +should be removed from the application's library. +
  • +
+
+ +

+See +How Can I Change The Logging System Configuration? +

+
+ +

+The configuration supported by JCL is limited to choosing the underlying logging system. +JCL does not (and will never) support changing the configuration of the wrapped logging system. +Please use the mechanisms provided by the underlying logging system. +

+