Author: rgoers
Date: Sat Jan 7 09:57:06 2012
New Revision: 1228586
URL: http://svn.apache.org/viewvc?rev=1228586&view=rev
Log:
Document plugins and ThreadContext
Modified:
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/plugins.xml
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/thread-context.xml
Modified:
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/plugins.xml
URL:
http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/plugins.xml?rev=1228586&r1=1228585&r2=1228586&view=diff
==============================================================================
---
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/plugins.xml
(original)
+++
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/plugins.xml
Sat Jan 7 09:57:06 2012
@@ -24,17 +24,81 @@
<body>
<section name="Plugins">
+ <a name="Introduction"/>
+ <subsection name="Introduction">
+ <p>
+ Log4j 1.x allowed for extension by requiring class attributes on
most of the configuration
+ declarations. In the case of some elements, notably the
PatternLayout, the only way to add
+ new pattern converters was to extend the PatternLayout class and
add them via code. One of
+ goals of Log4j 2 is to make extending it extremely easy through
the use of plugins.
+ </p>
+ <p>
+ In Log4j 2 a plugin is declared by adding a Plugin annotation to
the class declaration. During
+ initialization the Configuration will invoke the PluginManager to
locate all the Log4j plugins
+ that are located in the declared <a
href="./configuration.html#ConfigurationSyntax">packages</a>.
+ As the configuration is processed the appropriate plugins will be
automatically configured and
+ initialized. Log4j 2 utilizes a few different types of plugins
which are described in the follownig
+ sections.
+ </p>
+ </subsection>
<a name="Core"/>
<subsection name="Core">
-
+ <p>
+ Core plugins are those that are directly represented by an element
in a configuration file, such as an
+ Appender, Logger or Filter. Custom plugins that conform to the
rules laid out in the next paragraph
+ may simply be referenced in the configuration, provided they are
appropriate configured to be
+ loaded by the PluginManager.
+ </p>
+ <p>
+ Every Core plugin must declare a static method that is marked with
a PluginFactory annotation. To
+ allow the Configuration to pass the correct parameters to the
method, every
+ parameter to the method must be annotated as one of the following
attribute types. Each
+ attribute or element annotation must include the name that must be
present in the configuration
+ in order to match the configuration item to its respective
parameter.
+ </p>
+ <h4>Attribute Types</h4>
+ <dl>
+ <dt>PluginAttr</dt>
+ <dd>The parameter must resolve to a String, although it can be
the String representation of a
+ boolean. numeric value, or any other Object that can be created
from a String value.</dd>
+ <dt>PluginElement</dt>
+ <dd>The parameter may represent a complex object that itself has
parameters that can be configured.</dd>
+ <dt>PluginConfiguration</dt>
+ <dd>The current Configuration object will be passed to the
plugin as a parameter.</dd>
+ </dl>
</subsection>
<a name="Converters"/>
<subsection name="Converters">
-
+ <p>
+ Converters are used by
+ <a
href="../log4j2-core/apidocs/org/apache/logging/log4j/core/layout/PatternLayout.html">PatternLayout</a>
+ to render the elements identified by the conversion pattern. Every
converter must specify its type as
+ "Converter" on the Plugin attribute, have a static newInstance
method that accepts an array of Strings as
+ its only parameter and returns an instance of the Converter, and
must have a ConverterKeys annotation
+ present that contains the array of converter patterns that will
cause the Converter to be selected.
+ Converters that are meant to handle LogEvents must extend the
LogEventPatternConverter class and
+ must implement a format method that accepts a LogEvent and a
StringBuilder as arguments. The Converter
+ should append the result of its operation to the StringBuilder.
+ </p>
+ <p>
+ A second type of Converter is the FileConverter - which must have
"FileConverter" specified in the
+ type attribute of the Plugin annotation. While similar to a
LogEventPatternConverter, instead
+ of a single format method these Converters will have two
variations; one that takes an Object and
+ one that takes an array of Objects instead of the LogEvent. Both
append to the provided StringBuilder
+ in the same fashion as a LogEventPatternConverter. These
Converters are typically used by the
+ RollingFileAppender to construct the name of the file to log to.
+ </p>
</subsection>
<a name="Lookups"/>
<subsection name="Lookups">
-
+ <p>
+ Lookups are perhaps the simplest plugins of all. They must declare
their type as "Lookup" on the
+ plugin annotation and must implement the StrLookup interface. They
will have two methods; a
+ lookup method that accepts a String key and returns a String value
and a second lookup method that
+ accepts both a LogEvent and a String key and returns a String.
Lookups may be referenced by
+ specifying ${<i>name</i>:key} where <i>name</i> is the name
specified in the Plugin annotation and
+ key is the name of the item to locate.
+ </p>
</subsection>
</section>
</body>
Modified:
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/thread-context.xml
URL:
http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/thread-context.xml?rev=1228586&r1=1228585&r2=1228586&view=diff
==============================================================================
---
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/thread-context.xml
(original)
+++
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/src/site/xdoc/manual/thread-context.xml
Sat Jan 7 09:57:06 2012
@@ -24,7 +24,99 @@
<body>
<section name="Thread Context">
+ <subsection name="Introduction">
+ <p>Log4j introduced the concept of the Mapped Diagnostic Context or
MDC. It has been documented and
+ discussed in numerous places including
+ <a
href="http://veerasundar.com/blog/2009/10/log4j-mdc-mapped-diagnostic-context-what-and-why/">Log4j
MDC: What and Why</a> and
+ <a
href="http://blog.f12.no/wp/2004/12/09/log4j-and-the-mapped-diagnostic-context/">Log4j
and the Mappend Diagnostic Context</a>.
+ In addition, Log4j 1.x provides support for a Nested Diagnostic
Context or NDC. It too has been documented
+ and discussed in various places such as
+ <a
href="http://lstierneyltd.com/blog/development/log4j-nested-diagnostic-contexts-ndc/">Log4j
NDC</a>.
+ SLF4J/Logback followed with its own implementation of the MDC,
which is documented very well at
+ <a href="http://logback.qos.ch/manual/mdc.html">Mapped Diagnostic
Context</a>.
+ </p>
+ <p>Log4j 2 continues with the idea of the MDC and the NDC but merges
them into a single Thread Context.
+ The Thread Context Map is the equivalent of the MDC and the Thread
Context Stack is the equivalent of the
+ NDC. Although these are frequently used for purposes other than
diagnosing problems, they are still
+ frequently referred to as the MDC and NDC in Log4j 2 since they
are already well known by those acronyms.
+ </p>
+ </subsection>
+ <subsection name="Fish Tagging">
+ <p>Most real-world systems have to deal with multiple clients
simultaneously. In a typical multithreaded
+ implementation of such asystem, different threads will handle
different clients. Logging is
+ especially well suited to trace and debug complex distributed
applications. A common approach to
+ differentiate the logging output of one client from another is to
instantiate a new separate logger for
+ each client. This promotes the proliferation of loggers and
increases the management overhead of logging.
+ </p>
+ <p>A lighter technique is to uniquely stamp each log request
initiated from the same client interaction.
+ Neil Harrison described this method in the book "Patterns for
Logging Diagnostic Messages," in <em>Pattern
+ Languages of Program Design 3</em>, edited by R. Martin, D.
Riehle, and F. Buschmann
+ (Addison-Wesley, 1997). Just as a fish can be tagged and have its
movement tracked, stamping log
+ events with a common tag or set of data elements allows the
complete flow of a transaction or a request
+ to be tracked. We call this <i>Fish Tagging</i>.
+ </p>
+ <p>Log4j provides two mechanisms for performing Fish Tagging; the
Thread Context Map and the Thread
+ Context Stack. The Thread Context Map allows any number of items
to be added and be identified
+ using key/value pairs. The Thread Context Stack allows one or more
items to be pushed on the
+ Stack and then be identified by their order in the Stack or by the
data itself. Since key/value
+ pairs are more flexible, the Thread Context Map is recommended
when data items may be added during
+ the processing of the request or when there are more than one or
two items.
+ </p>
+ <p>To uniquely stamp each request using the Thread Context Stack,
the user pushes contextual information
+ on to the Stack.
+ </p>
+ <pre>
+ ThreadContext.push(UUID.randomUUID().toString()); // Add the fishtag;
+ logger.debug("Message 1");
+ .
+ .
+ .
+ logger.debug("Message 2");
+ .
+ .
+ ThreadContext.pop();</pre>
+ <p>
+ The alternative to the Thread Context Stack is the Thread Context
Map. In this case, attributes
+ associated with the request being processed are adding at the
beginning and removed at the end
+ as follows:
+ </p>
+ <pre>
+ ThreadContext.put("id", UUID.randomUUID().toString(); // Add the fishtag;
+ ThreadContext.put("ipAddress", request.getRemoteAddr());
+ ThreadContext.put("loginId", session.getAttribute("loginId"));
+ ThreadContext.put("hostName", request.getServerName());
+ .
+ logger.debug("Message 1");
+ .
+ .
+ logger.debug("Message 2");
+ .
+ .
+ ThreadContext.clear();</pre>
+ <p>The Stack and the Map are managed per thread and is based on
+ <a
href="http://docs.oracle.com/javase/6/docs/api/java/lang/InheritableThreadLocal.html">InheritableThreadLocal</a>.
+ Thus, in many cases the contents of the Stack and Map will be
passed to child threads. However, as
+ discussed in the
+ <a
href="http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Executors.html#privilegedThreadFactory()">Executors</a>
+ class and in other cases where thread pooling is utilized, the
ThreadContext may not always be
+ automatically passed to worker threads. In those cases the pooling
mechanism should provide a means for
+ doing so. The getContext() and cloneStack() methods can be used to
obtain copies of the Map and Stack
+ respectively.
+ </p>
+ <p>
+ Note that all methods of the
+ <a
href="../log4j2-api/apidocs/org/apache/logging/log4j/ThreadContext.html">ThreadContext</a>
+ class are static.
+ </p>
+ </subsection>
+ <subsection name="Including the ThreadContext when writing logs">
+ <p>
+ The PatternLayout provides mechanisms to print the contents of the
ThreadContext Map and Stack. Using
+ %X by itself will cause the full contents of the Map to be
included while %X{key} will cause the value
+ of the specified key to be included. %x will include the full
contents of the Stack.
+ </p>
+ </subsection>
</section>
</body>
</document>
\ No newline at end of file