| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| <!-- Generated by Apache Maven Doxia at 2015-03-30 --> |
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
| <title>Apache log4net – Apache log4net Manual: Internals</title> |
| <style type="text/css" media="all"> |
| @import url("../../css/maven-base.css"); |
| @import url("../../css/maven-theme.css"); |
| @import url("../../css/site.css"); |
| </style> |
| <link rel="stylesheet" href="../../css/print.css" type="text/css" media="print" /> |
| <meta name="author" content="Nicko Cadell" /> |
| <meta name="Date-Revision-yyyymmdd" content="20150330" /> |
| <meta http-equiv="Content-Language" content="en" /> |
| <meta name="keywords" content="log4net internals, log4net" /> |
| </head> |
| <body class="composite"> |
| <div id="banner"> |
| <a href="../../../" id="bannerLeft"> |
| <img src="../../images/ls-logo.jpg" alt="Apache Logging Services Project" /> |
| </a> |
| <div class="clear"> |
| <hr/> |
| </div> |
| </div> |
| <div id="breadcrumbs"> |
| |
| |
| <div class="xleft"> |
| <span id="publishDate">Last Published: 2015-03-30</span> |
| | <span id="projectVersion">Version: 1.2.13</span> |
| | <a href="http://www.apache.org/" class="externalLink" title="Apache">Apache</a> |
| > |
| <a href="../../../" title="Logging Services">Logging Services</a> |
| > |
| <a href="../.././" title="log4net">log4net</a> |
| > |
| Apache log4net – Apache log4net Manual: Internals |
| </div> |
| <div class="xright"> |
| |
| </div> |
| <div class="clear"> |
| <hr/> |
| </div> |
| </div> |
| <div id="leftColumn"> |
| <div id="navcolumn"> |
| |
| |
| <h5>Apache log4net</h5> |
| <ul> |
| <li class="none"> |
| <a href="../../index.html" title="About">About</a> |
| </li> |
| <li class="none"> |
| <a href="../../download_log4net.cgi" title="Download">Download</a> |
| </li> |
| <li class="none"> |
| <a href="../../release/release-notes.html" title="Release Notes">Release Notes</a> |
| </li> |
| <li class="none"> |
| <a href="../../license.html" title="License">License</a> |
| </li> |
| </ul> |
| <h5>Documentation</h5> |
| <ul> |
| <li class="none"> |
| <a href="../../release/features.html" title="Features">Features</a> |
| </li> |
| <li class="none"> |
| <a href="../../release/framework-support.html" title="Supported Frameworks">Supported Frameworks</a> |
| </li> |
| <li class="none"> |
| <a href="../../release/example-apps.html" title="Example Apps">Example Apps</a> |
| </li> |
| <li class="none"> |
| <a href="../../release/config-examples.html" title="Config Examples">Config Examples</a> |
| </li> |
| <li class="none"> |
| <a href="../../release/building.html" title="Building">Building</a> |
| </li> |
| <li class="none"> |
| <a href="../../release/faq.html" title="FAQ">FAQ</a> |
| </li> |
| <li class="none"> |
| <a href="../../release/howto/index.html" title="How Tos">How Tos</a> |
| </li> |
| <li class="none"> |
| <a href="../../release/sdk/index.html" title="SDK Reference">SDK Reference</a> |
| </li> |
| </ul> |
| <h5>Manual</h5> |
| <ul> |
| <li class="none"> |
| <a href="../../release/manual/introduction.html" title="Introduction">Introduction</a> |
| </li> |
| <li class="none"> |
| <a href="../../release/manual/configuration.html" title="Configuration">Configuration</a> |
| </li> |
| <li class="none"> |
| <a href="../../release/manual/contexts.html" title="Contexts">Contexts</a> |
| </li> |
| <li class="none"> |
| <a href="../../release/manual/plugins.html" title="Plugins">Plugins</a> |
| </li> |
| <li class="none"> |
| <a href="../../release/manual/repositories.html" title="Repositories">Repositories</a> |
| </li> |
| <li class="none"> |
| <strong>Internals</strong> |
| </li> |
| </ul> |
| <h5>Community</h5> |
| <ul> |
| <li class="none"> |
| <a href="../../mail-lists.html" title="Mailing Lists">Mailing Lists</a> |
| </li> |
| <li class="none"> |
| <a href="../../issue-tracking.html" title="Issue Tracking">Issue Tracking</a> |
| </li> |
| </ul> |
| <h5>Development</h5> |
| <ul> |
| <li class="none"> |
| <a href="../../source-repository.html" title="Repository">Repository</a> |
| </li> |
| <li class="none"> |
| <a href="../../integration.html" title="Continuous Integration">Continuous Integration</a> |
| </li> |
| </ul> |
| <h5>Project Documentation</h5> |
| <ul> |
| <li class="collapsed"> |
| <a href="../../project-info.html" title="Project Information">Project Information</a> |
| </li> |
| </ul> |
| <h5>Apache</h5> |
| <ul> |
| <li class="none"> |
| <a href="http://www.apache.org/" class="externalLink" title="Home">Home</a> |
| </li> |
| <li class="none"> |
| <a href="http://www.apache.org/licenses/" class="externalLink" title="License">License</a> |
| </li> |
| <li class="none"> |
| <a href="http://www.apache.org/foundation/sponsorship.html" class="externalLink" title="Sponsorship">Sponsorship</a> |
| </li> |
| <li class="none"> |
| <a href="http://www.apache.org/foundation/thanks.html" class="externalLink" title="Thanks">Thanks</a> |
| </li> |
| <li class="none"> |
| <a href="http://www.apache.org/security/" class="externalLink" title="Security">Security</a> |
| </li> |
| <li class="none"> |
| <a href="http://www.apachecon.com" class="externalLink" title="Conferences">Conferences</a> |
| </li> |
| </ul> |
| <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"> |
| <img class="poweredBy" alt="Built by Maven" src="../../images/logos/maven-feather.png" /> |
| </a> |
| |
| |
| </div> |
| </div> |
| <div id="bodyColumn"> |
| <div id="contentBox"> |
| <!-- Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to you under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. --> |
| |
| |
| <a name="main"></a> |
| <div class="section" id="main"> |
| <h2><a name="Apache_log4net_Manual_-_Internals"></a>Apache log4net™ Manual - Internals</h2> |
| <a name="perf"></a> |
| <div class="section" id="perf"> |
| <h2><a name="Performance"></a>Performance</h2> |
| |
| <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> |
| |
| <ol style="list-style-type: decimal"> |
| |
| <li> |
| <b>Logging performance when logging is turned off.</b> |
| |
| <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"> |
| <div> |
| <pre class="code"> |
| log.Debug("Entry number: " + i + " is " + entry[i].ToString());</pre></div></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"> |
| <div> |
| <pre class="code"> |
| if(log.IsDebugEnabled) |
| { |
| log.Debug("Entry number: " + i + " is " + entry[i].ToString()); |
| }</pre></div></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> |
| <b>The performance of deciding whether to log or not to log when logging is |
| turned on.</b> |
| |
| <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> |
| <b>Actually outputting log messages</b> |
| |
| <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> |
| </div> |
| |
| <a name="flow"></a> |
| <div class="section" id="flow"> |
| <h2><a name="Logging_Event_Flow"></a>Logging Event Flow</h2> |
| |
| <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 style="list-style-type: decimal"> |
| |
| <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> |
| |
| <ol style="list-style-type: decimal"> |
| |
| <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> |
| |
| <ol style="list-style-type: decimal"> |
| |
| <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> |
| |
| |
| </div> |
| </div> |
| <div class="clear"> |
| <hr/> |
| </div> |
| <div id="footer"> |
| <div class="xright"> |
| <div class="xright">Copyright © 2004-2015 |
| <a href="http://www.apache.org">Apache Software Foundation</a>. |
| |
| |
| Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache Software License, Version 2.0</a>.</div><br /> |
| <div class="xright">Apache log4net, Apache, log4net, the Apache feather logo, the Apache Logging Services project logo and the Built by Maven logo are trademarks of The Apache Software Foundation.</div> |
| <div class="clear"> |
| </div> |
| </div> |
| </body> |
| </html> |