You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4net-dev@logging.apache.org by ni...@apache.org on 2007/02/26 03:10:29 UTC
svn commit: r511694 [9/24] - in /logging/log4net/trunk: ./ doc/ doc/release/
doc/release/howto/ doc/release/manual/ xdocs/ xdocs/lib/ xdocs/src/
xdocs/src/release/ xdocs/src/release/howto/ xdocs/src/release/manual/
xdocs/src/stylesheets/
Modified: logging/log4net/trunk/doc/release/manual/contexts.html
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/doc/release/manual/contexts.html?view=diff&rev=511694&r1=511693&r2=511694
==============================================================================
--- logging/log4net/trunk/doc/release/manual/contexts.html (original)
+++ logging/log4net/trunk/doc/release/manual/contexts.html Sun Feb 25 18:10:21 2007
@@ -37,12 +37,12 @@
<meta name="keywords" content="building log4net, log4net" />
-
+
<link href="../../css/site.css" rel="stylesheet" type="text/css"/>
- <link href="../../css/style.css" rel="stylesheet" type="text/css"/>
-
- <title>log4net - log4net Manual - Contexts</title>
+ <link href="../../css/style.css" rel="stylesheet" type="text/css"/>
+
+ <title>Apache log4net Manual: Contexts</title>
</head>
@@ -50,7 +50,12 @@
bgcolor="#ffffff"
text="#000000"
link="#525D76"
- >
+ >
+ <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ _uacct = "UA-1416250-1";
+ </script>
+
<!-- START Header table -->
<table class="banner" border="0">
<tr>
@@ -66,134 +71,134 @@
<!-- END Header table -->
- <div class="centercol">
+ <div class="centercol">
<!-- START main table -->
- <h1><a id="main"></a>log4net Manual - Contexts</h1>
+ <h1><a id="main"></a>log4net Manual - Contexts</h1>
<div class="i1">
- <h2>Contents</h2>
- <div class="i1">
- <a href="#scopes">Scopes</a><br/>
+ <h2>Contents</h2>
+ <div class="i1">
+ <a href="#scopes">Scopes</a><br/>
<div class="i1">
</div>
- <a href="#properties">Context Properties</a><br/>
+ <a href="#properties">Context Properties</a><br/>
<div class="i1">
<a href="#active">Active Property Values</a><br/>
<div class="i1">
</div>
</div>
- <a href="#stacks">Context Stacks</a><br/>
+ <a href="#stacks">Context Stacks</a><br/>
<div class="i1">
</div>
- <a href="#ndc">Nested Diagnostic Contexts</a><br/>
+ <a href="#ndc">Nested Diagnostic Contexts</a><br/>
<div class="i1">
</div>
- <a href="#mdc">Mapped Diagnostic Contexts</a><br/>
+ <a href="#mdc">Mapped Diagnostic Contexts</a><br/>
<div class="i1">
</div>
- </div>
- <p>
- Most real-world systems have to deal with multiple clients simultaneously. In a
- typical multithreaded implementation of such a system, different threads will
- handle different clients. Logging is especially well suited to trace and debug
- complex distributed applications. An approach to differentiate the
- logging output of one client from another is to instantiate a new separate
- logger for each client. However 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.
- </p>
+ </div>
+ <p>
+ Most real-world systems have to deal with multiple clients simultaneously. In a
+ typical multithreaded implementation of such a system, different threads will
+ handle different clients. Logging is especially well suited to trace and debug
+ complex distributed applications. An approach to differentiate the
+ logging output of one client from another is to instantiate a new separate
+ logger for each client. However 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.
+ </p>
<p>
- Log4net supports different types of contextual logging and contexts with different scopes.
- </p>
+ Log4net supports different types of contextual logging and contexts with different scopes.
+ </p>
<h2><a id="scopes"></a>Scopes</h2>
<div class="i1">
<p>
- Contextual data can be set in different scopes. These contexts have progressively narrower visibility.
- In the logging event itself the values from all of the contexts are combined together such that
- values specified in a lower scoped context hide values from a higher context.
- </p>
+ Contextual data can be set in different scopes. These contexts have progressively narrower visibility.
+ In the logging event itself the values from all of the contexts are combined together such that
+ values specified in a lower scoped context hide values from a higher context.
+ </p>
<div class="table">
- <table cellspacing="0">
- <tr>
- <th>Scope</th>
- <th>Type</th>
- <th>Description</th>
- </tr>
- <tr align="left">
- <td>Global</td>
- <td><span class="code">log4net.GlobalContext</span></td>
- <td>
- The global context is shared by all threads in the current AppDomain.
- This context is thread safe for use by multiple threads concurrently.
- </td>
- </tr>
- <tr align="left">
- <td>Thread</td>
- <td><span class="code">log4net.ThreadContext</span></td>
- <td>
- The thread context is visible only to the current managed thread.
- </td>
- </tr>
- <tr align="left">
- <td>Logical Thread</td>
- <td><span class="code">log4net.ThreadLogicalContext</span></td>
- <td>
- The logical thread context is visible to a logical thread. Logical
- threads can jump from one managed thread to another. For more details
- see the .NET API <span class="code">System.Runtime.Remoting.Messaging.CallContext</span>.
- </td>
- </tr>
- <tr align="left">
- <td>Event</td>
- <td><span class="code">log4net.Core.LoggingEvent</span></td>
- <td>
- Each event captures the current contextual state at the time the event
- is generated. Contextual data can be set on the event itself. This context
- is only visible to the code generating the event itself.
- </td>
- </tr>
- </table>
- </div>
+ <table cellspacing="0">
+ <tr>
+ <th>Scope</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+ <tr align="left">
+ <td>Global</td>
+ <td><span class="code">log4net.GlobalContext</span></td>
+ <td>
+ The global context is shared by all threads in the current AppDomain.
+ This context is thread safe for use by multiple threads concurrently.
+ </td>
+ </tr>
+ <tr align="left">
+ <td>Thread</td>
+ <td><span class="code">log4net.ThreadContext</span></td>
+ <td>
+ The thread context is visible only to the current managed thread.
+ </td>
+ </tr>
+ <tr align="left">
+ <td>Logical Thread</td>
+ <td><span class="code">log4net.ThreadLogicalContext</span></td>
+ <td>
+ The logical thread context is visible to a logical thread. Logical
+ threads can jump from one managed thread to another. For more details
+ see the .NET API <span class="code">System.Runtime.Remoting.Messaging.CallContext</span>.
+ </td>
+ </tr>
+ <tr align="left">
+ <td>Event</td>
+ <td><span class="code">log4net.Core.LoggingEvent</span></td>
+ <td>
+ Each event captures the current contextual state at the time the event
+ is generated. Contextual data can be set on the event itself. This context
+ is only visible to the code generating the event itself.
+ </td>
+ </tr>
+ </table>
+ </div>
</div>
<h2><a id="properties"></a>Context Properties</h2>
<div class="i1">
<p>
- The log4net contexts store properties, i.e. name value pairs. The name is a string
- the value is any object. A property can be set as follows:
- </p>
+ The log4net contexts store properties, i.e. name value pairs. The name is a string
+ the value is any object. A property can be set as follows:
+ </p>
<div class="syntax"><pre class="code">
log4net.GlobalContext.Properties["name"] = value;
</pre></div>
<p>
- If properties with the same name are set in more than one context scope then
- the value in the narrowest scope (lower down in the list above) will hide the
- other values.
- </p>
- <p>
- The property values are stored as objects within the <span class="code">LoggingEvent</span>.
- The <span class="code">PatternLayout</span> supports rendering the value of a named
- property using the <span class="code">%property{name}</span> syntax. The value is
- converted to a string by passing it to the <span class="code">log4net.ObjectRenderer.RendererMap</span>
- which will locate any custom renderer for the value type. The default behavior for
- custom types is to call the object's <span class="code">ToString()</span> method.
- </p>
+ If properties with the same name are set in more than one context scope then
+ the value in the narrowest scope (lower down in the list above) will hide the
+ other values.
+ </p>
+ <p>
+ The property values are stored as objects within the <span class="code">LoggingEvent</span>.
+ The <span class="code">PatternLayout</span> supports rendering the value of a named
+ property using the <span class="code">%property{name}</span> syntax. The value is
+ converted to a string by passing it to the <span class="code">log4net.ObjectRenderer.RendererMap</span>
+ which will locate any custom renderer for the value type. The default behavior for
+ custom types is to call the object's <span class="code">ToString()</span> method.
+ </p>
<h3><a id="active"></a>Active Property Values</h3>
<div class="i1">
<p>
- An active property value is one who's value changes over time.
- </p>
+ An active property value is one who's value changes over time.
+ </p>
<p>
- For example, imagine a custom type that implemented the
- <span class="code">ToString()</span> method to return the
- number of bytes allocated by the runtime garbage collector.
- </p>
+ For example, imagine a custom type that implemented the
+ <span class="code">ToString()</span> method to return the
+ number of bytes allocated by the runtime garbage collector.
+ </p>
<div class="syntax"><pre class="code">
public class GCAllocatedBytesHelper
@@ -205,55 +210,55 @@
}</pre></div>
<p>
- An instance of this type can be added to the <span class="code">log4net.GlobalContext</span>
- during application startup:
- </p>
+ An instance of this type can be added to the <span class="code">log4net.GlobalContext</span>
+ during application startup:
+ </p>
<div class="syntax"><pre class="code">
log4net.GlobalContext.Properties["GCAllocatedBytes"] = new GCAllocatedBytesHelper();
</pre></div>
<p>
- Once this property is set in the context all subsequent logging events will have a property
- called <i>GCAllocatedBytes</i>. The value of the property will be an instance of the
- <span class="code">GCAllocatedBytesHelper</span> type. When this value is rendered to a
- string by calling the <span class="code">ToString</span> method the current number of bytes
- allocated by the garbage collector will be returned and included in the output.
- </p>
+ Once this property is set in the context all subsequent logging events will have a property
+ called <i>GCAllocatedBytes</i>. The value of the property will be an instance of the
+ <span class="code">GCAllocatedBytesHelper</span> type. When this value is rendered to a
+ string by calling the <span class="code">ToString</span> method the current number of bytes
+ allocated by the garbage collector will be returned and included in the output.
+ </p>
</div>
</div>
<h2><a id="stacks"></a>Context Stacks</h2>
<div class="i1">
<p>
- Sometimes simple key value pairs are not the most convenient way of capturing contextual
- information. A stack of information is a very convenient way of storing data especially
- as our applications tend to be stack based.
- </p>
- <p>
- The <span class="code">ThreadContext</span> and <span class="code">LogicalThreadContext</span>
- also support storing contextual data in a stack. The stack is stored in context property,
- therefore stacks have names and more than one stack can exist in the same context. A property
- value set in a narrower context would override a stack with the same property name set in a
- wider scoped context.
- </p>
- <p>
- The stack supports <span class="code">Push</span> and <span class="code">Pop</span> methods.
- As more contextual data is pushed onto the stack the stack grows. When the stack is rendered
- all the data pushed onto the stack is output with the most recent data to the right hand
- end of the string.
- </p>
- <p>
- As the stack is just an object stored in the context properties it is also rendered
- using the same <span class="code">PatternLayout</span> syntax: <span class="code">%property{name}</span>.
- Where <i>name</i> is the name of the stack.
- </p>
- <p>
- Calls the the stack's <span class="code">Push</span> and <span class="code">Pop</span>
- methods must be matched up so that each push has a corresponding pop. The
- <span class="code">Push</span> method also returns an <span class="code">IDisposable</span>
- object that will perform the required pop operation when it is disposed. This allows
- the C# <i>using</i> syntax to be used to automate the stack management.
- </p>
+ Sometimes simple key value pairs are not the most convenient way of capturing contextual
+ information. A stack of information is a very convenient way of storing data especially
+ as our applications tend to be stack based.
+ </p>
+ <p>
+ The <span class="code">ThreadContext</span> and <span class="code">LogicalThreadContext</span>
+ also support storing contextual data in a stack. The stack is stored in context property,
+ therefore stacks have names and more than one stack can exist in the same context. A property
+ value set in a narrower context would override a stack with the same property name set in a
+ wider scoped context.
+ </p>
+ <p>
+ The stack supports <span class="code">Push</span> and <span class="code">Pop</span> methods.
+ As more contextual data is pushed onto the stack the stack grows. When the stack is rendered
+ all the data pushed onto the stack is output with the most recent data to the right hand
+ end of the string.
+ </p>
+ <p>
+ As the stack is just an object stored in the context properties it is also rendered
+ using the same <span class="code">PatternLayout</span> syntax: <span class="code">%property{name}</span>.
+ Where <i>name</i> is the name of the stack.
+ </p>
+ <p>
+ Calls the the stack's <span class="code">Push</span> and <span class="code">Pop</span>
+ methods must be matched up so that each push has a corresponding pop. The
+ <span class="code">Push</span> method also returns an <span class="code">IDisposable</span>
+ object that will perform the required pop operation when it is disposed. This allows
+ the C# <i>using</i> syntax to be used to automate the stack management.
+ </p>
<div class="syntax"><pre class="code">
using(log4net.ThreadContext.Stacks["NDC"].Push("context"))
@@ -263,54 +268,54 @@
</pre></div>
<p>
- The INFO level log has a stack stored in its <i>NDC</i> property. The top item in the
- stack is the string <i>context</i>.
- The <i>using</i> syntax ensures that the value <i>context</i> is popped off the stack
- at the end of the block.
- </p>
- <p>
- The <span class="code">using</span>
- syntax is recommended because it removes some work load from the developer and
- reduces errors in matching up the Push and Pop calls, especially when exceptions
- can occur.
- </p>
+ The INFO level log has a stack stored in its <i>NDC</i> property. The top item in the
+ stack is the string <i>context</i>.
+ The <i>using</i> syntax ensures that the value <i>context</i> is popped off the stack
+ at the end of the block.
+ </p>
+ <p>
+ The <span class="code">using</span>
+ syntax is recommended because it removes some work load from the developer and
+ reduces errors in matching up the Push and Pop calls, especially when exceptions
+ can occur.
+ </p>
</div>
<h2><a id="ndc"></a>Nested Diagnostic Contexts</h2>
<div class="i1">
<p>
- The <span class="code">NDC</span> (Nested Diagnostic Context) exists for compatibility
- with older versions of log4net. This helper class implements a stack which is stored
- in the thread context property named <i>NDC</i>.
- </p>
+ The <span class="code">NDC</span> (Nested Diagnostic Context) exists for compatibility
+ with older versions of log4net. This helper class implements a stack which is stored
+ in the thread context property named <i>NDC</i>.
+ </p>
</div>
<h2><a id="mdc"></a>Mapped Diagnostic Contexts</h2>
<div class="i1">
<p>
- The <span class="code">MDC</span> (MappedDiagnostic Context) exists for compatibility
- with older versions of log4net. This helper class implements a properties map which is
- mapped directly through to the thread context properties.
- </p>
+ The <span class="code">MDC</span> (MappedDiagnostic Context) exists for compatibility
+ with older versions of log4net. This helper class implements a properties map which is
+ mapped directly through to the thread context properties.
+ </p>
</div>
<p>
- To illustrate this point, let us take the example of a web service delivering
- content to numerous clients. The web service can build the <span class="code">NDC</span> at the very
- beginning of the request before executing other code. The contextual
- information can be the client's host name and other information inherent to the
- request, typically information contained in cookies. Hence, even if the web
- service is serving multiple clients simultaneously, the logs initiated by the
- same code, i.e. belonging to the same logger, can still be distinguished
- because each client request will have a different <span class="code">NDC</span> stack. Contrast this with
- the complexity of passing a freshly instantiated logger to all code exercised
- during the client's request.
- </p>
- <p>
- Nevertheless, some sophisticated applications, such as virtual hosting web
- servers, must log differently depending on the virtual host context and also
- depending on the software component issuing the request. Log4net supports
- multiple logger repositories. This would allow each virtual host to possess its own copy
- of the logger hierarchy. Configuring multiple logger hierarchies is beyond the
- scope of this document.
- </p>
+ To illustrate this point, let us take the example of a web service delivering
+ content to numerous clients. The web service can build the <span class="code">NDC</span> at the very
+ beginning of the request before executing other code. The contextual
+ information can be the client's host name and other information inherent to the
+ request, typically information contained in cookies. Hence, even if the web
+ service is serving multiple clients simultaneously, the logs initiated by the
+ same code, i.e. belonging to the same logger, can still be distinguished
+ because each client request will have a different <span class="code">NDC</span> stack. Contrast this with
+ the complexity of passing a freshly instantiated logger to all code exercised
+ during the client's request.
+ </p>
+ <p>
+ Nevertheless, some sophisticated applications, such as virtual hosting web
+ servers, must log differently depending on the virtual host context and also
+ depending on the software component issuing the request. Log4net supports
+ multiple logger repositories. This would allow each virtual host to possess its own copy
+ of the logger hierarchy. Configuring multiple logger hierarchies is beyond the
+ scope of this document.
+ </p>
</div>
@@ -321,9 +326,9 @@
<div align="center"><font color="#525D76" size="-1"><em>
Copyright ©
- 2004-2006,
- Apache Software Foundation
- </em></font></div>
+ 2004-2007,
+ Apache Software Foundation
+ </em></font></div>
<!-- END main table -->
</div>
@@ -332,60 +337,63 @@
<!-- ============================================================ -->
<div class="leftcol">
<div class="menu_header">Apache</div>
- <div class="menu_item"> <a href="http://www.apache.org">Apache Home</a>
+ <div class="menu_item"> <a href="http://www.apache.org">Apache Home</a>
</div>
- <div class="menu_item"> <a href="http://logging.apache.org/">Logging Services</a>
+ <div class="menu_item"> <a href="http://logging.apache.org/">Logging Services</a>
</div>
<div class="menu_header">log4net Project</div>
- <div class="menu_item"> <a href="../../index.html">About</a>
+ <div class="menu_item"> <a href="../../index.html">About</a>
</div>
- <div class="menu_item"> <a href="../../license.html">License</a>
+ <div class="menu_item"> <a href="../../license.html">License</a>
</div>
- <div class="menu_item"> <a href="../../support.html">Support</a>
+ <div class="menu_item"> <a href="../../support.html">Support</a>
</div>
- <div class="menu_item"> <a href="../../roadmap.html">Roadmap</a>
+ <div class="menu_item"> <a href="../../roadmap.html">Roadmap</a>
</div>
- <div class="menu_item"> <a href="../../contributing.html">Contributing</a>
+ <div class="menu_item"> <a href="../../contributing.html">Contributing</a>
</div>
- <div class="menu_item"> <a href="../../history.html">History</a>
+ <div class="menu_item"> <a href="../../history.html">History</a>
</div>
- <div class="menu_item"> <a href="../../downloads.html">Downloads</a>
+ <div class="menu_item"> <a href="../../downloads.html">Downloads</a>
</div>
<div class="menu_header">log4net 1.2 Documentation</div>
- <div class="menu_item"> <a href="../../release/features.html">Features</a>
+ <div class="menu_item"> <a href="../../release/features.html">Features</a>
</div>
- <div class="menu_item"> <a href="../../release/framework-support.html">Supported Frameworks</a>
+ <div class="menu_item"> <a href="../../release/framework-support.html">Supported Frameworks</a>
</div>
- <div class="menu_item"> <a href="../../release/release-notes.html">Release Notes</a>
+ <div class="menu_item"> <a href="../../release/release-notes.html">Release Notes</a>
</div>
- <div class="menu_item"> <a href="../../release/example-apps.html">Example Apps</a>
+ <div class="menu_item"> <a href="../../release/example-apps.html">Example Apps</a>
</div>
- <div class="menu_item"> <a href="../../release/config-examples.html">Config Examples</a>
+ <div class="menu_item"> <a href="../../release/config-examples.html">Config Examples</a>
</div>
- <div class="menu_item"> <a href="../../release/building.html">Building</a>
+ <div class="menu_item"> <a href="../../release/building.html">Building</a>
</div>
- <div class="menu_item"> <a href="../../release/faq.html">FAQ</a>
+ <div class="menu_item"> <a href="../../release/faq.html">FAQ</a>
</div>
- <div class="menu_item"> <a href="../../release/howto/index.html">How Tos</a>
+ <div class="menu_item"> <a href="../../release/howto/index.html">How Tos</a>
</div>
- <div class="menu_item"> <a href="../../release/sdk/index.html">SDK Reference</a>
+ <div class="menu_item"> <a href="../../release/sdk/index.html">SDK Reference</a>
</div>
<div class="menu_header">log4net 1.2 Manual</div>
- <div class="menu_item"> <a href="../../release/manual/introduction.html">Introduction</a>
+ <div class="menu_item"> <a href="../../release/manual/introduction.html">Introduction</a>
</div>
- <div class="menu_item"> <a href="../../release/manual/configuration.html">Configuration</a>
+ <div class="menu_item"> <a href="../../release/manual/configuration.html">Configuration</a>
</div>
- <div class="menu_item"> <a href="../../release/manual/contexts.html">Contexts</a>
+ <div class="menu_item"> <a href="../../release/manual/contexts.html">Contexts</a>
</div>
- <div class="menu_item"> <a href="../../release/manual/plugins.html">Plugins</a>
+ <div class="menu_item"> <a href="../../release/manual/plugins.html">Plugins</a>
</div>
- <div class="menu_item"> <a href="../../release/manual/repositories.html">Repositories</a>
+ <div class="menu_item"> <a href="../../release/manual/repositories.html">Repositories</a>
</div>
- <div class="menu_item"> <a href="../../release/manual/internals.html">Internals</a>
+ <div class="menu_item"> <a href="../../release/manual/internals.html">Internals</a>
</div>
</div>
+ <script type="text/javascript">
+ urchinTracker();
+ </script>
</body>
</html>
<!-- end the processing -->
Modified: logging/log4net/trunk/doc/release/manual/internals.html
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/doc/release/manual/internals.html?view=diff&rev=511694&r1=511693&r2=511694
==============================================================================
--- logging/log4net/trunk/doc/release/manual/internals.html (original)
+++ logging/log4net/trunk/doc/release/manual/internals.html Sun Feb 25 18:10:21 2007
@@ -37,12 +37,12 @@
<meta name="keywords" content="log4net internals, log4net" />
-
+
<link href="../../css/site.css" rel="stylesheet" type="text/css"/>
- <link href="../../css/style.css" rel="stylesheet" type="text/css"/>
-
- <title>log4net - log4net Manual - Internals</title>
+ <link href="../../css/style.css" rel="stylesheet" type="text/css"/>
+
+ <title>Apache log4net Manual: Internals</title>
</head>
@@ -50,7 +50,12 @@
bgcolor="#ffffff"
text="#000000"
link="#525D76"
- >
+ >
+ <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ _uacct = "UA-1416250-1";
+ </script>
+
<!-- START Header table -->
<table class="banner" border="0">
<tr>
@@ -66,249 +71,249 @@
<!-- END Header table -->
- <div class="centercol">
+ <div class="centercol">
<!-- START main table -->
- <h1><a id="main"></a>log4net Manual - Internals</h1>
+ <h1><a id="main"></a>log4net Manual - Internals</h1>
<div class="i1">
- <h2>Contents</h2>
- <div class="i1">
- <a href="#perf">Performance</a><br/>
+ <h2>Contents</h2>
+ <div class="i1">
+ <a href="#perf">Performance</a><br/>
<div class="i1">
</div>
- <a href="#flow">Logging Event Flow</a><br/>
+ <a href="#flow">Logging Event Flow</a><br/>
<div class="i1">
</div>
- </div>
- <h2><a id="perf"></a>Performance</h2>
+ </div>
+ <h2><a id="perf"></a>Performance</h2>
<div class="i1">
<p>
- One of the often-cited arguments against logging is its computational cost.
- This is a legitimate concern as even moderately sized applications can generate
- thousands of log requests. Much effort was spent measuring and tweaking logging
- performance. Log4net claims to be fast and flexible: speed first, flexibility
- second.
- </p>
+ One of the often-cited arguments against logging is its computational cost.
+ This is a legitimate concern as even moderately sized applications can generate
+ thousands of log requests. Much effort was spent measuring and tweaking logging
+ performance. Log4net claims to be fast and flexible: speed first, flexibility
+ second.
+ </p>
<p>
- The user should be aware of the following performance issues.
- </p>
+ The user should be aware of the following performance issues.
+ </p>
<ol>
- <li>
- <strong>Logging performance when logging is turned off.</strong>
- <p>
- When logging is turned off entirely or just for a set of levels, the cost of a
- log request consists of a method invocation plus an integer comparison.
- </p>
- <p>
- However, The method invocation involves the "hidden" cost of parameter
- construction.
- </p>
- <p>
- For example, for some logger
- <span class="code">log</span>, writing,
- </p>
- <div class="syntax"><pre class="code">
+ <li>
+ <strong>Logging performance when logging is turned off.</strong>
+ <p>
+ When logging is turned off entirely or just for a set of levels, the cost of a
+ log request consists of a method invocation plus an integer comparison.
+ </p>
+ <p>
+ However, The method invocation involves the "hidden" cost of parameter
+ construction.
+ </p>
+ <p>
+ For example, for some logger
+ <span class="code">log</span>, writing,
+ </p>
+ <div class="syntax"><pre class="code">
log.Debug("Entry number: " + i + " is " + entry[i].ToString());</pre></div>
- <p>
- incurs the cost of constructing the message parameter, i.e. converting both
- integer
- <span class="code">i</span>
- and
- <span class="code">entry[i]</span>
- to strings, and concatenating intermediate strings, regardless of whether the
- message will be logged or not. This cost of parameter construction can be quite
- high and it depends on the number and type of the parameters involved.
- </p>
- <p>
- To avoid the parameter construction cost write:
- </p>
- <div class="syntax"><pre class="code">
+ <p>
+ incurs the cost of constructing the message parameter, i.e. converting both
+ integer
+ <span class="code">i</span>
+ and
+ <span class="code">entry[i]</span>
+ to strings, and concatenating intermediate strings, regardless of whether the
+ message will be logged or not. This cost of parameter construction can be quite
+ high and it depends on the number and type of the parameters involved.
+ </p>
+ <p>
+ To avoid the parameter construction cost write:
+ </p>
+ <div class="syntax"><pre class="code">
if(log.IsDebugEnabled)
{
- log.Debug("Entry number: " + i + " is " + entry[i].ToString());
+ log.Debug("Entry number: " + i + " is " + entry[i].ToString());
}</pre></div>
- <p>
- This will not incur the cost of parameter construction if debugging is
- disabled. On the other hand, if the logger is debug-enabled, it will incur
- twice the cost of evaluating whether the logger is enabled or not: once in
- <span class="code">IsDebugEnabled</span>
- and once in
- <span class="code">Debug</span>. This is an insignificant overhead because
- evaluating a logger takes about 1% of the time it takes to actually log.
- </p>
- <p>
- Certain users resort to pre-processing or compile-time techniques to compile
- out all log statements. This leads to perfect performance efficiency with
- respect to logging. However, since the resulting application binary does not
- contain any log statements, logging cannot be turned on for that binary. In
- many people's opinion this is a disproportionate price to pay in exchange for a
- small performance gain.
- </p>
- </li>
- <li>
- <strong>The performance of deciding whether to log or not to log when logging is
- turned on.</strong>
- <p>
- This is essentially the performance of walking the logger hierarchy. When
- logging is turned on, log4net still needs to compare the level of the log
- request with the level of the request logger. However, loggers may not have an
- assigned level; they can inherit them from the logger hierarchy. Thus, before
- inheriting a level, the logger may need to search its ancestors.
- </p>
- <p>
- There has been a serious effort to make this hierarchy walk to be as fast as
- possible. For example, child loggers link only to their existing ancestors. In
- the
- <span class="code">BasicConfigurator</span>
- example shown earlier, the logger named
- <span class="code">Com.Foo.Bar</span>
- is linked directly to the <i>root</i> logger, thereby circumventing the nonexistent
- <span class="code">Com</span>
- or
- <span class="code">Com.Foo</span>
- loggers. This significantly improves the speed of the walk, especially in
- "sparse" hierarchies.
- </p>
- <p>
- The typical cost of walking the hierarchy is typically 3 times slower than when
- logging is turned off entirely.
- </p>
- </li>
- <li>
- <strong>Actually outputting log messages</strong>
- <p>
- This is 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.
- </p>
- </li>
- </ol>
+ <p>
+ This will not incur the cost of parameter construction if debugging is
+ disabled. On the other hand, if the logger is debug-enabled, it will incur
+ twice the cost of evaluating whether the logger is enabled or not: once in
+ <span class="code">IsDebugEnabled</span>
+ and once in
+ <span class="code">Debug</span>. This is an insignificant overhead because
+ evaluating a logger takes about 1% of the time it takes to actually log.
+ </p>
+ <p>
+ Certain users resort to pre-processing or compile-time techniques to compile
+ out all log statements. This leads to perfect performance efficiency with
+ respect to logging. However, since the resulting application binary does not
+ contain any log statements, logging cannot be turned on for that binary. In
+ many people's opinion this is a disproportionate price to pay in exchange for a
+ small performance gain.
+ </p>
+ </li>
+ <li>
+ <strong>The performance of deciding whether to log or not to log when logging is
+ turned on.</strong>
+ <p>
+ This is essentially the performance of walking the logger hierarchy. When
+ logging is turned on, log4net still needs to compare the level of the log
+ request with the level of the request logger. However, loggers may not have an
+ assigned level; they can inherit them from the logger hierarchy. Thus, before
+ inheriting a level, the logger may need to search its ancestors.
+ </p>
+ <p>
+ There has been a serious effort to make this hierarchy walk to be as fast as
+ possible. For example, child loggers link only to their existing ancestors. In
+ the
+ <span class="code">BasicConfigurator</span>
+ example shown earlier, the logger named
+ <span class="code">Com.Foo.Bar</span>
+ is linked directly to the <i>root</i> logger, thereby circumventing the nonexistent
+ <span class="code">Com</span>
+ or
+ <span class="code">Com.Foo</span>
+ loggers. This significantly improves the speed of the walk, especially in
+ "sparse" hierarchies.
+ </p>
+ <p>
+ The typical cost of walking the hierarchy is typically 3 times slower than when
+ logging is turned off entirely.
+ </p>
+ </li>
+ <li>
+ <strong>Actually outputting log messages</strong>
+ <p>
+ This is 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.
+ </p>
+ </li>
+ </ol>
<p>
- Although log4net has many features, its first design goal was speed. Some
- log4net components have been rewritten many times to improve performance.
- Nevertheless, contributors frequently come up with new optimizations. You
- should be pleased to know that when configured with the
- <span class="code">SimpleLayout</span>
- performance tests have shown log4net to log within an order of magnitude of
- <span class="code">System.Console.WriteLine</span>.
- </p>
+ Although log4net has many features, its first design goal was speed. Some
+ log4net components have been rewritten many times to improve performance.
+ Nevertheless, contributors frequently come up with new optimizations. You
+ should be pleased to know that when configured with the
+ <span class="code">SimpleLayout</span>
+ performance tests have shown log4net to log within an order of magnitude of
+ <span class="code">System.Console.WriteLine</span>.
+ </p>
</div>
<h2><a id="flow"></a>Logging Event Flow</h2>
<div class="i1">
<p>
- The following is the series of steps and checks that a messages goes through while being logged.
- For the purposes of this example we will document an <span class="code">INFO</span> level
- message being logged on logger <i>ConsoleApp.LoggingExample</i>. This logger is configured
- to use the <span class="code">log4net.Appender.ConsoleAppender</span>. The repository used
- in this example is a <span class="code">log4net.Repository.Hierarchy</span> object.
- </p>
+ The following is the series of steps and checks that a messages goes through while being logged.
+ For the purposes of this example we will document an <span class="code">INFO</span> level
+ message being logged on logger <i>ConsoleApp.LoggingExample</i>. This logger is configured
+ to use the <span class="code">log4net.Appender.ConsoleAppender</span>. The repository used
+ in this example is a <span class="code">log4net.Repository.Hierarchy</span> object.
+ </p>
<ol>
- <li>
- <p>
- The user logs a message using the <span class="code">ILog.Info</span> method on the logger
- obtained using a call to <span class="code">log4net.LogManager.GetLogger("ConsoleApp.LoggingExample")</span>.
- For example: <span class="code">log4net.LogManager.GetLogger("ConsoleApp.LoggingExample").Info("Application Start");</span>
- The <span class="code">ILog</span> interface is actually an extension to log4net that provides level
- specific logging methods (i.e. Debug, Info, Warn, Error, and Fatal).
- </p>
- </li>
- <li>
- <p>
- The message is then logged through to the <span class="code">ILogger.Log</span> method on the
- appropriate <span class="code">log4net.Repository.Hierarchy.Logger</span> object. The
- <span class="code">ILogger.Log</span> method takes the <span class="code">Level</span> to
- log at as a parameter and therefore works for all levels.
- </p>
- </li>
- <li>
- <p>
- The repository threshold level is compared to the message level to determine if the message
- can be logged. If the message level is below the threshold level the message is not logged.
- In this case the repository is a <span class="code">log4net.Repository.Hierarchy</span> object.
- </p>
- </li>
- <li>
- <p>
- The <span class="code">Logger</span> level is compared to the message level to determine if the
- message can be logged. Note that the <span class="code">Logger</span> level is inherited from a
- parent <span class="code">Logger</span> if not specified explicitly for this <span class="code">Logger</span>.
- If the message level is below the <span class="code">Logger</span> level the message is not logged.
- </p>
- </li>
- <li>
- <p>
- A <span class="code">LoggingEvent</span> instance is created to encapsulate the message being logged.
- </p>
- </li>
- <li>
- <p>
- The list of appenders for the <span class="code">Logger</span> is built. This includes appenders
- attached to parent <span class="code">Logger</span>s except where excluded by the
- <span class="code">Logger.Additivity</span> property.
- </p>
- </li>
- <li>
- <p>
- The <span class="code">LoggingEvent</span> object is passed to the
- <span class="code">IAppender.DoAppend</span> method for each appender.
- </p>
- </li>
- </ol>
+ <li>
+ <p>
+ The user logs a message using the <span class="code">ILog.Info</span> method on the logger
+ obtained using a call to <span class="code">log4net.LogManager.GetLogger("ConsoleApp.LoggingExample")</span>.
+ For example: <span class="code">log4net.LogManager.GetLogger("ConsoleApp.LoggingExample").Info("Application Start");</span>
+ The <span class="code">ILog</span> interface is actually an extension to log4net that provides level
+ specific logging methods (i.e. Debug, Info, Warn, Error, and Fatal).
+ </p>
+ </li>
+ <li>
+ <p>
+ The message is then logged through to the <span class="code">ILogger.Log</span> method on the
+ appropriate <span class="code">log4net.Repository.Hierarchy.Logger</span> object. The
+ <span class="code">ILogger.Log</span> method takes the <span class="code">Level</span> to
+ log at as a parameter and therefore works for all levels.
+ </p>
+ </li>
+ <li>
+ <p>
+ The repository threshold level is compared to the message level to determine if the message
+ can be logged. If the message level is below the threshold level the message is not logged.
+ In this case the repository is a <span class="code">log4net.Repository.Hierarchy</span> object.
+ </p>
+ </li>
+ <li>
+ <p>
+ The <span class="code">Logger</span> level is compared to the message level to determine if the
+ message can be logged. Note that the <span class="code">Logger</span> level is inherited from a
+ parent <span class="code">Logger</span> if not specified explicitly for this <span class="code">Logger</span>.
+ If the message level is below the <span class="code">Logger</span> level the message is not logged.
+ </p>
+ </li>
+ <li>
+ <p>
+ A <span class="code">LoggingEvent</span> instance is created to encapsulate the message being logged.
+ </p>
+ </li>
+ <li>
+ <p>
+ The list of appenders for the <span class="code">Logger</span> is built. This includes appenders
+ attached to parent <span class="code">Logger</span>s except where excluded by the
+ <span class="code">Logger.Additivity</span> property.
+ </p>
+ </li>
+ <li>
+ <p>
+ The <span class="code">LoggingEvent</span> object is passed to the
+ <span class="code">IAppender.DoAppend</span> method for each appender.
+ </p>
+ </li>
+ </ol>
<p>
- For Each Appender that the <span class="code">LoggingEvent</span> is delivered to the following
- actions take place:
- </p>
+ For Each Appender that the <span class="code">LoggingEvent</span> is delivered to the following
+ actions take place:
+ </p>
<ol>
- <li>
- <p>
- The appender threshold level is compared to the message level to determine if the message
- can be logged. If the message level is below the threshold level the message is not logged.
- </p>
- </li>
- <li>
- <p>
- If the appender has a filter chain the <span class="code">LoggingEvent</span> is passed down the
- filter chain which can decide if the message can be logged or not.
- </p>
- </li>
- <li>
- <p>
- Next an appender specific check is performed. Usually this check will verify that all the
- required properties are set for the appender (e.g. a <span class="code">Layout</span> is set if required).
- </p>
- </li>
- <li>
- <p>
- The <span class="code">LoggingEvent</span> is passed to the appender specific
- <span class="code">Append</span> method. What happens now is specific to the appender.
- </p>
- </li>
- </ol>
+ <li>
+ <p>
+ The appender threshold level is compared to the message level to determine if the message
+ can be logged. If the message level is below the threshold level the message is not logged.
+ </p>
+ </li>
+ <li>
+ <p>
+ If the appender has a filter chain the <span class="code">LoggingEvent</span> is passed down the
+ filter chain which can decide if the message can be logged or not.
+ </p>
+ </li>
+ <li>
+ <p>
+ Next an appender specific check is performed. Usually this check will verify that all the
+ required properties are set for the appender (e.g. a <span class="code">Layout</span> is set if required).
+ </p>
+ </li>
+ <li>
+ <p>
+ The <span class="code">LoggingEvent</span> is passed to the appender specific
+ <span class="code">Append</span> method. What happens now is specific to the appender.
+ </p>
+ </li>
+ </ol>
<p>
- The following actions take place in the <span class="code">ConsoleAppender.Append</span> method:
- </p>
+ The following actions take place in the <span class="code">ConsoleAppender.Append</span> method:
+ </p>
<ol>
- <li>
- <p>
- The <span class="code">ConsoleAppender</span> uses a <span class="code">Layout</span> to
- format the message as a string for display.
- </p>
- </li>
- <li>
- <p>
- The <span class="code">Layout</span> uses the <span class="code">LoggingEvent.RenderedMessage</span>
- property to get the string for the message object. This uses the registered
- <span class="code">IObjectRenderer</span> for the type of the message object.
- </p>
- </li>
- <li>
- <p>
- The message text is displayed on the console using the <span class="code">Console.WriteLine</span> method.
- </p>
- </li>
- </ol>
+ <li>
+ <p>
+ The <span class="code">ConsoleAppender</span> uses a <span class="code">Layout</span> to
+ format the message as a string for display.
+ </p>
+ </li>
+ <li>
+ <p>
+ The <span class="code">Layout</span> uses the <span class="code">LoggingEvent.RenderedMessage</span>
+ property to get the string for the message object. This uses the registered
+ <span class="code">IObjectRenderer</span> for the type of the message object.
+ </p>
+ </li>
+ <li>
+ <p>
+ The message text is displayed on the console using the <span class="code">Console.WriteLine</span> method.
+ </p>
+ </li>
+ </ol>
</div>
</div>
@@ -320,9 +325,9 @@
<div align="center"><font color="#525D76" size="-1"><em>
Copyright ©
- 2004-2006,
- Apache Software Foundation
- </em></font></div>
+ 2004-2007,
+ Apache Software Foundation
+ </em></font></div>
<!-- END main table -->
</div>
@@ -331,60 +336,63 @@
<!-- ============================================================ -->
<div class="leftcol">
<div class="menu_header">Apache</div>
- <div class="menu_item"> <a href="http://www.apache.org">Apache Home</a>
+ <div class="menu_item"> <a href="http://www.apache.org">Apache Home</a>
</div>
- <div class="menu_item"> <a href="http://logging.apache.org/">Logging Services</a>
+ <div class="menu_item"> <a href="http://logging.apache.org/">Logging Services</a>
</div>
<div class="menu_header">log4net Project</div>
- <div class="menu_item"> <a href="../../index.html">About</a>
+ <div class="menu_item"> <a href="../../index.html">About</a>
</div>
- <div class="menu_item"> <a href="../../license.html">License</a>
+ <div class="menu_item"> <a href="../../license.html">License</a>
</div>
- <div class="menu_item"> <a href="../../support.html">Support</a>
+ <div class="menu_item"> <a href="../../support.html">Support</a>
</div>
- <div class="menu_item"> <a href="../../roadmap.html">Roadmap</a>
+ <div class="menu_item"> <a href="../../roadmap.html">Roadmap</a>
</div>
- <div class="menu_item"> <a href="../../contributing.html">Contributing</a>
+ <div class="menu_item"> <a href="../../contributing.html">Contributing</a>
</div>
- <div class="menu_item"> <a href="../../history.html">History</a>
+ <div class="menu_item"> <a href="../../history.html">History</a>
</div>
- <div class="menu_item"> <a href="../../downloads.html">Downloads</a>
+ <div class="menu_item"> <a href="../../downloads.html">Downloads</a>
</div>
<div class="menu_header">log4net 1.2 Documentation</div>
- <div class="menu_item"> <a href="../../release/features.html">Features</a>
+ <div class="menu_item"> <a href="../../release/features.html">Features</a>
</div>
- <div class="menu_item"> <a href="../../release/framework-support.html">Supported Frameworks</a>
+ <div class="menu_item"> <a href="../../release/framework-support.html">Supported Frameworks</a>
</div>
- <div class="menu_item"> <a href="../../release/release-notes.html">Release Notes</a>
+ <div class="menu_item"> <a href="../../release/release-notes.html">Release Notes</a>
</div>
- <div class="menu_item"> <a href="../../release/example-apps.html">Example Apps</a>
+ <div class="menu_item"> <a href="../../release/example-apps.html">Example Apps</a>
</div>
- <div class="menu_item"> <a href="../../release/config-examples.html">Config Examples</a>
+ <div class="menu_item"> <a href="../../release/config-examples.html">Config Examples</a>
</div>
- <div class="menu_item"> <a href="../../release/building.html">Building</a>
+ <div class="menu_item"> <a href="../../release/building.html">Building</a>
</div>
- <div class="menu_item"> <a href="../../release/faq.html">FAQ</a>
+ <div class="menu_item"> <a href="../../release/faq.html">FAQ</a>
</div>
- <div class="menu_item"> <a href="../../release/howto/index.html">How Tos</a>
+ <div class="menu_item"> <a href="../../release/howto/index.html">How Tos</a>
</div>
- <div class="menu_item"> <a href="../../release/sdk/index.html">SDK Reference</a>
+ <div class="menu_item"> <a href="../../release/sdk/index.html">SDK Reference</a>
</div>
<div class="menu_header">log4net 1.2 Manual</div>
- <div class="menu_item"> <a href="../../release/manual/introduction.html">Introduction</a>
+ <div class="menu_item"> <a href="../../release/manual/introduction.html">Introduction</a>
</div>
- <div class="menu_item"> <a href="../../release/manual/configuration.html">Configuration</a>
+ <div class="menu_item"> <a href="../../release/manual/configuration.html">Configuration</a>
</div>
- <div class="menu_item"> <a href="../../release/manual/contexts.html">Contexts</a>
+ <div class="menu_item"> <a href="../../release/manual/contexts.html">Contexts</a>
</div>
- <div class="menu_item"> <a href="../../release/manual/plugins.html">Plugins</a>
+ <div class="menu_item"> <a href="../../release/manual/plugins.html">Plugins</a>
</div>
- <div class="menu_item"> <a href="../../release/manual/repositories.html">Repositories</a>
+ <div class="menu_item"> <a href="../../release/manual/repositories.html">Repositories</a>
</div>
- <div class="menu_item"> <a href="../../release/manual/internals.html">Internals</a>
+ <div class="menu_item"> <a href="../../release/manual/internals.html">Internals</a>
</div>
</div>
+ <script type="text/javascript">
+ urchinTracker();
+ </script>
</body>
</html>
<!-- end the processing -->