nicko       2005/02/07 12:46:01

  Added:       xdocs/src/release faq.xml
  Removed:     xdocs/src/release/manual faq.xml
  Log:
  Moved FAQ doc out of manual folder
  
  Revision  Changes    Path
  1.1                  logging-log4net/xdocs/src/release/faq.xml
  
  Index: faq.xml
  ===================================================================
  <?xml version="1.0" ?>
  <!--
  Copyright 2004-2005 The Apache Software Foundation
  
  Licensed 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.
  -->
  <document>
  
        <properties>
                <author email="nicko at apache dot org">Nicko Cadell</author>
                <title>log4net Manual - Frequently Asked Questions</title>
        </properties>
  
        <meta name="keywords" content="log4net frequently asked questions, 
log4net faq, log4net" />
  
        <body>
                <section name="log4net Manual - Frequently Asked Questions">
                        <sectionMenu name="Contents" />
                        
                        <section name="Information">
                        
                                <section name="What is log4net?">
                                        <p>
                                                log4net is a tool to help the 
programmer output log statements to a variety of 
                                                output targets.
                                        </p>
                                        <p>
                                                In case of problems with an 
application, it is helpful to enable logging so 
                                                that the problem can be 
located. With log4net it is possible to enable logging at 
                                                runtime without modifying the 
application binary. The log4net package is designed 
                                                so that log statements can 
remain in <i>production</i> code without incurring a 
                                                high performance cost. It 
follows that the speed of logging (or rather not 
                                                logging) is crucial.
                                        </p>
                                        <p>
                                                At the same time, log output 
can be so voluminous that it quickly becomes 
                                                overwhelming. One of the 
distinctive features of log4net (and common to all of
                                                the log4x libraries) is the 
notion of <i>hierarchical 
                                                loggers</i>. Using these 
loggers it is possible to selectively control 
                                                which log statements are output 
at arbitrary granularity.
                                        </p>
                                        <p>
                                                log4net is designed with two 
distinct goals in mind: speed and flexibility. There 
                                                is a tight balance between 
these two requirements.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="Is log4net a reliable logging 
system?">
                                        <p>
                                                No. log4net is not reliable. It 
is a best-effort and <em>fail-stop</em> logging system.
                                        </p>
                                        <p>
                                                By fail-stop, we mean that 
log4net will not throw unexpected exceptions at 
                                                run-time potentially causing 
your application to crash. <b>If for any reason, log4net 
                                                throws an uncaught 
exception</b> (except for <span class="code">ArgumentException</span> and 
                                                <span 
class="code">ArgumentNullException</span> which may be thrown), <b>please send 
an email 
                                                to the <a 
href="mailto:[email protected]";>
                                                
[email protected]</a> mailing list</b>. Uncaught exceptions 
                                                are handled as serious bugs 
requiring immediate attention.
                                        </p>
                                        <p>
                                                Moreover, log4net will not 
revert to <span class="code">System.Console.Out</span>
                                                or <span 
class="code">System.Console.Error</span> when its designated 
                                                output stream is not opened, is 
not writable or becomes full. This avoids 
                                                corrupting an otherwise working 
program by flooding the user's terminal because 
                                                logging fails. However, log4net 
will output a single message to 
                                                <span 
class="code">System.Console.Error</span> and 
<span>System.Diagnostics.Trace</span>
                                                indicating that logging can not 
be performed.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="What are the prerequisites for 
log4net?">
                                        <p>
                                                log4net runs on many different 
frameworks and each framework has its own requirements.
                                                As a rule of thumb you will 
need an ECMA-335 compliant CLI runtime, for example, 
                                                the Microsoft .NET runtime 1.0 
(1.0.3705) or 1.1 (1.1.4322).
                                        </p>
                                        <p>
                                                Not all frameworks are created 
equal and some features have been excluded from 
                                                some of the builds. See the <a 
href="../framework-support.html">Framework Support</a> 
                                                document for more information.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="Is there example code for using 
log4net?">
                                        <p>
                                                There is a directory containing 
examples in <span class="code">log4net\examples</span>. 
                                                The examples are broken down by 
framework.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="What are the features of 
log4net?">
                                        <ul>
                                                <li>
                                                        log4net is optimized 
for speed.</li>
                                                <li>
                                                        log4net is based on a 
named logger hierarchy.</li>
                                                <li>
                                                        log4net is fail-stop 
but not reliable.</li>
                                                <li>
                                                        log4net is 
thread-safe.</li>
                                                <li>
                                                        log4net is not 
restricted to a predefined set of facilities.</li>
                                                <li>
                                                        Logging behavior can be 
set at runtime using a configuration file. 
                                                        Configuration files are 
in XML format.</li>
                                                <li>
                                                        log4net is designed to 
handle exceptions from the start.</li>
                                                <li>
                                                        log4net can direct its 
output to many sinks including: a file, the console, the NT EventLog or even 
e-mail.</li>
                                                <li>
                                                        log4net categorizes 
logging into levels: DEBUG, INFO, WARN, ERROR and FATAL.</li>
                                                <li>
                                                        The format of the log 
output can be easily changed by implementing a new layout class.</li>
                                                <li>
                                                        The target of the log 
output as well as the writing strategy can be altered by 
                                                        writing a new appender 
class.</li>
                                                <li>
                                                        log4net supports 
multiple output appenders per logger.</li>
                                        </ul>
                                        <p>
                                                See the <a 
href="../features.html">features</a> overview document for more information on 
the features of log4net.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="Is log4net thread-safe?">
                                        <p>
                                                Yes, log4net is thread-safe.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="What does log output look like?">
                                        <p>
                                                The log output can be 
customized in many ways. Moreover, one can completely 
                                                override the output format by 
implementing one's own <span class="code">ILayout</span>
                                        </p>
                                        <p>
                                                Here is an example output using 
<span class="code">PatternLayout</span> with the conversion 
                                                pattern <span 
class="code">%timestamp [%thread] %-5level %logger{2} %ndc - 
%message%newline</span>
                                        </p>
                                        <source language="text"><![CDATA[
  176 [main] INFO  examples.Sort - Populating an array of 2 elements in reverse 
order.
  225 [main] INFO  examples.SortAlgo - Entered the sort method.
  262 [main] DEBUG SortAlgo.OUTER i=1 - Outer loop.
  276 [main] DEBUG SortAlgo.SWAP i=1 j=0 - Swapping intArray[0] = 1 and 
intArray[1] = 0
  290 [main] DEBUG SortAlgo.OUTER i=0 - Outer loop.
  304 [main] INFO  SortAlgo.DUMP - Dump of integer array:
  317 [main] INFO  SortAlgo.DUMP - Element [0] = 0
  331 [main] INFO  SortAlgo.DUMP - Element [1] = 1
  343 [main] INFO  examples.Sort - The next log statement should be an error 
message.
  346 [main] ERROR SortAlgo.DUMP - Tried to dump an uninitialized array.
  467 [main] INFO  examples.Sort - Exiting main method.]]></source>
                                        <p>
                                                The first field is the number 
of milliseconds elapsed since the start of the 
                                                program. The second field is 
the thread outputting the log statement. The third 
                                                field is the level of the log 
statement. The fourth field is the rightmost 
                                                two components of the name of 
the logger making the log request. The fifth field (just 
                                                before the '-') is the 
<em>nested diagnostic context</em> (<span class="code">NDC</span>). Note the 
                                                nested diagnostic context may 
be empty as in the first two statements. The text 
                                                after the '-' is the message of 
the statement.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="What are Loggers?">
                                        <p>
                                                The logger concept lies at the 
heart of log4net's configuration. Loggers are organized into a 
                                                hierarchy and give the 
programmer <em>run-time</em> control on which logging statements 
                                                are printed or not.
                                        </p>
                                        <p>
                                                Loggers are assigned levels 
through the configuration of log4net. A log statement is 
                                                routed through to the appender 
depending on its level <em>and</em> its logger.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
                                
                                
                                <section name="Why should I donate my 
extensions to log4net back to the project?">
                                        <p>
                                                Contrary to the GNU Public 
License (GPL) the Apache Software License does not 
                                                make any claims over your 
extensions. By extensions, we mean totally new code 
                                                that invokes existing log4net 
code. <em>You are free to do whatever you wish with 
                                                your proprietary log4net 
extensions.</em> In particular, you may choose to 
                                                never release your extensions 
to the wider public. For details see the
                                                <a 
href="http://www.apache.org/licenses/LICENSE-2.0";>Apache License, Version 
2.0</a>.
                                        </p>
                                        <p>
                                                We are very careful not to 
unnecessarily change the log4net client API so that newer log4net 
                                                releases are backward 
compatible with previous versions. We are a lot less 
                                                scrupulous with the internal 
log4net API. Thus, if your extension is designed to 
                                                work with the internals of a 
specific log4net version, then when the next release
                                                of log4net comes out, you will 
probably need to adapt your proprietary extensions to the 
                                                new release. Thus, you will be 
forced to spend precious resources in order to 
                                                keep up with log4net changes. 
This is commonly referred to as the "stupid-tax". 
                                                By donating the code and making 
it part of the standard distribution, you save 
                                                yourself the unnecessary 
maintenance work.
                                        </p>
                                        <p>
                                                If your extensions are useful 
then someone will eventually write an extension 
                                                providing the same or very 
similar functionality. Your development effort will 
                                                be wasted.
                                        </p>
                                        <p>
                                                Unless the proprietary log4net 
extension is business critical, there is little 
                                                reason for not donating your 
extensions back to the project.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="What should I keep in mind when 
contributing code?">
                                        <ol>
                                                <li>
                                                        Stick to the existing 
indentation style even if you hate it.
                                                        <p>
                                                                Alternating 
between indentation styles makes it hard to understand the source 
                                                                code. Make it 
hard on yourself but easier on others.
                                                        </p>
                                                </li>
                                                <li>
                                                        <b>Thoroughly test your 
code.</b>
                                                        <p>
                                                                There is 
nothing more irritating than finding the bugs in debugging (i.e. logging) code.
                                                        </p>
                                                </li>
                                                <li>
                                                        Keep it simple, small 
and fast.
                                                        <p>
                                                                It's all about 
the application not about logging.
                                                        </p>
                                                </li>
                                                <li>
                                                        Did I mention sticking 
with the indentation style?</li>
                                        </ol>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
                                
  
                                <section name="How fast do bugs in log4net get 
fixed?">
                                        <p>
                                                As fast as they get reported ;-)
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="What is the history of log4net?">
                                        <p>
                                                log4net is a port of the 
popular <a href="http://logging.apache.org/log4j/";>log4j</a> logging library.
                                                The initial port was done in 
June 2001, since then we have tried to remain in the
                                                spirit of the original log4j. 
See the log4net <a href="../../history.html">history</a> page for more details.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
                                                
  
                                <section name="Where can I find the latest 
distribution of log4net?">
                                        <p>
                                                The log4net <a 
href="http://logging.apache.org/log4net/";>home page</a> is a good place to 
start.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
                                
                                                                
                        </section>
  
                        <section name="Configuration">
  
                                <section name="How can I change log behavior at 
runtime?">
                                        <p>
                                                Logging behavior can be set 
using configuration files which are parsed at runtime. 
                                                Using configuration files the 
programmer can define loggers and set their 
                                                levels.
                                        </p>
                                        <p>
                                                Configuration files are 
specified in XML. See <span class="code">log4net.Config.XmlConfigurator</span>
                                                for more details.
                                        </p>
                                        <p>
                                                See the various <span 
class="code">log4net.Layout</span> and <span 
class="code">log4net.Appender</span>
                                                components for specific 
configuration options.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="How do I completely disable all 
logging at runtime?">
                                        <p>
                                                Setting the <span 
class="code">Threshold</span> on the Hierarchy to Level OFF will disable all
                                                logging from that Hierarchy. 
This can be done in the log4net configuration file
                                                by setting the "threshold" 
attribute on the log4net configuration element to "OFF".
                                                For example:
                                        </p>
                                        <source language="xml"><![CDATA[
  <log4net threshold="OFF" />]]></source>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
                                
                                <section name="What are the configurable 
options for an appender?">
                                        <p>
                                                log4net uses public properties 
to configure components such as
                                                Appenders, Layouts, Loggers etc.
                                        </p>
                                        <p>
                                                Thus, any writable public 
property in on the appender corresponds to a 
                                                configurable option. For 
example, in <span class="code">RollingFileAppender</span> the 
                                                <span class="code">public int 
MaxSizeRollBackups { set; }</span> property corresponds to 
                                                the <span 
class="code">MaxSizeRollBackups</span> option.
                                        </p>
                                        <p>
                                                Layouts options are also 
defined by their writable properties. Same goes for most 
                                                other log4net components. 
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
                                
  
                                <section name="Is it possible to direct log 
output to different appenders by level?">
                                        <p>
                                                Yes it is. Setting the <span 
class="code">Threshold</span> option of any appender extending 
                                                <span 
class="code">AppenderSkeleton</span>, (most log4net appenders extend 
                                                <span 
class="code">AppenderSkeleton</span>) will filter out all log events 
                                                with a <em>lower</em> level 
than the value of the threshold option.
                                        </p>
                                        <p>
                                                For example, setting the 
threshold of an appender to DEBUG will also allow INFO, 
                                                WARN, ERROR and FATAL messages 
to log along with DEBUG messages. (DEBUG is the 
                                                lowest level). This is usually 
acceptable as there is little use for DEBUG 
                                                messages without the 
surrounding INFO, WARN, ERROR and FATAL messages. 
                                                Similarly, setting the 
threshold of an appender to ERROR will filter out DEBUG, 
                                                INFO and WARN messages but not 
ERROR or FATAL messages.
                                        </p>
                                        <p>
                                                This policy usually best 
encapsulates what the user actually wants to do, as 
                                                opposed to her mind-projected 
solution.
                                        </p>
                                        <p>
                                                If you must filter events by 
exact level match, then you can attach a 
                                                <span 
class="code">LevelMatchFilter</span> to any appender to filter out logging 
                                                events by exact level match.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
                                
                                <section name="Is there a way to get log4net to 
automatically reload a configuration file if it changes?">
                                        <p>
                                                Yes. The <span 
class="code">XmlConfigurator</span> supports automatic 
                                                reloading through the <span 
class="code">ConfigureAndWatch</span> APIs. See the API 
                                                documentation for more details.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="Can I load an appender from 
another assembly?">
                                        <p>
                                                Yes. When specifying the type 
in the configuration file you can give the assembly
                                                qualified name of the type. For 
example:
                                        </p>
                                        <source language="xml"><![CDATA[
  <appender name="..." type="MyNamespace.MyAppender, MyAssembly">]]></source>
                                        <p>
                                                The .NET runtime will try to 
locate the assembly called <i>MyAssembly</i>.
                                                How .NET locates assemblies is 
beyond the scope of this FAQ.
                                        </p>
                                        <p>
                                                When loading an assembly from 
the GAC the fully qualified assembly name,
                                                including the version, culture 
and public key must be specified. This is 
                                                in the standard syntax 
supported by <span class="code">System.Type.GetType</span>.
                                                See the next FAQ on how to get 
the version and public key for an assembly.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
                                
                                <section name="How do I get the Public Key for 
an assembly?">
                                        <p>
                                                The fully qualified name for an 
assembly includes the version, culture and
                                                public key. The public key is 
derived from the strong name used to identify
                                                the publisher. When referencing 
an assembly from the GAC the fully qualified
                                                name must be used. To get the 
version, culture and public key you can use a
                                                tool like the excellent .NET 
Reflector from Lutz Roeder available from
                                                <a 
href="http://www.aisto.com/roeder/dotnet";>http://www.aisto.com/roeder/dotnet</a>.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
                                
                
                        </section>
  
                        <section name="Implementing Logging">
                        
                                <section name="Are there any suggested ways for 
naming loggers?">
                                        <p>
                                                Yes, there are.
                                        </p>
                                        <p>
                                                You can name logging loggers by 
<strong>locality</strong>. It turns out that 
                                                instantiating a logger in each 
class, with the logger name equal to the 
                                                fully-qualified name of the 
class, is a useful and straightforward approach of 
                                                defining loggers. This approach 
has many benefits:
                                        </p>
                                        <ul>
                                                <li>
                                                        It is very simple to 
implement.</li>
                                                <li>
                                                        It is very simple to 
explain to new developers.</li>
                                                <li>
                                                        It automatically 
mirrors your application's own modular design.</li>
                                                <li>
                                                        It can be further 
refined at will.</li>
                                                <li>
                                                        Printing the logger 
automatically gives information on the locality of the 
                                                        log statement.</li>
                                        </ul>
                                        <p>
                                                However, this is not the only 
way for naming loggers. A common alternative 
                                                is to name loggers by 
<strong>functional areas</strong>. For example, the 
                                                "database" logger, "remoting" 
logger, "security" logger, or the "XML" 
                                                logger.
                                        </p>
                                        <p>
                                                You may choose to name loggers 
by functionality and subcategorize by 
                                                locality, as in 
"DATABASE.MyApp.MyClass" or 
                                                
"DATABASE.MyApp.MyModule.MyOtherClass".
                                        </p>
                                        <p>
                                                <em>You are totally free in 
choosing the names of your loggers.</em> The 
                                                log4net package merely allows 
you to manage your names in a hierarchy. However, 
                                                it is your responsibility to 
define this hierarchy.
                                        </p>
                                        <p>
                                                <b>Note:</b> by naming loggers 
by locality one tends to name things by 
                                                functionality, since in most 
cases the locality relates closely to 
                                                functionality.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
                                
  
                                <section name="How do I get the fully-qualified 
name of a class in a static block?">
                                        <p>
                                                You can easily retrieve the 
fully-qualified name of a class in a static block 
                                                for class <span 
class="code">X</span>, with the statement <span 
class="code">typeof(X).Name</span>. 
                                                Note that <span 
class="code">X</span> is the class name and span an instance.
                                                However because the <span 
class="code">LogManager.GetLogger</span> method is overloaded
                                                to take an instance of <span 
class="code">Type</span> as well as <span class="code">string</span>
                                                usually only the type of the 
class is required.
                                        </p>
                                        <p>
                                                Here is the suggested usage 
template:
                                        </p>
                                        <source language="C#"><![CDATA[
  public class Foo
  {
        private static readonly ILog log = LogManager.GetLogger(typeof(Foo));
        ... other code
  }]]></source>
                                        <p>
                                                An equivalent and more portable 
solution, though slightly longer, is to use the declaring type 
                                                of the static constructor.
                                        </p>
                                        <source language="C#"><![CDATA[
  public class Foo
  {
        private static readonly ILog log = 
LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        ... other code
  }]]></source>
                                        <p>
                                                <b>Note:</b> the .NET Compact 
Framework 1.0 does not support <span 
class="code">System.Reflection.MethodBase.GetCurrentMethod()</span>.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="What is the fastest way of (not) 
logging?">
                                        <p>
                                                For some logger <span 
class="code">log</span>, writing,
                                        </p>
                                        <source language="C#"><![CDATA[
  log.Debug("Entry number: " + i + " is " + entry[i]);]]></source>
                                        <p>
                                                incurs the cost of constructing 
the message parameter, that is converting both 
                                                integer <span 
class="code">i</span> and <span class="code">entry[i]</span> to 
                                                a string, and concatenating 
intermediate strings. This, regardless of whether 
                                                the message will be logged or 
not.
                                        </p>
                                        <p>
                                                If you are worried about speed, 
then write
                                        </p>
                                        <source language="C#"><![CDATA[
  if(log.IsDebugEnabled) 
  {
        log.Debug("Entry number: " + i + " is " + entry[i]);
  }]]></source>
                                        <p>
                                                This way you will not incur the 
cost of parameter construction if debugging is 
                                                disabled for logger <span 
class="code">log</span>. On the other hand, if the logger is 
                                                debug enabled, you will incur 
the cost of evaluating whether the logger is 
                                                enabled or not, twice: once in 
<span class="code">IsDebugEnabled</span> and once in <span 
class="code">Debug</span>. 
                                                This is an insignificant 
overhead since evaluating a logger takes less than 
                                                1% of the time it takes to 
actually log a statement.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="What is REALLY the FASTEST way 
of (not) logging?">
                                        <p>
                                                So you don't think that the 
previous FAQ is really the fastest way
                                                of not logging? Well there is a 
faster way but it does have some
                                                drawbacks. Starting from: 
                                        </p>
                                        <source language="C#"><![CDATA[
  if(log.IsDebugEnabled) 
  {
        log.Debug("Entry number: " + i + " is " + entry[i]);
  }]]></source>
                                        <p>
                                                It is possible to further 
eliminate the calls to <span class="code">IsDebugEnabled</span>
                                                so that the call is only made 
once per logger. If you are using one logger 
                                                for each class then you can 
store the enabled state for the logger in a static
                                                variable in the class and then 
test against this variable:
                                        </p>
                                        <source language="C#"><![CDATA[
  public class FastLogger
  {
        private static readonly ILog log = 
LogManager.GetLogger(typeof(FastLogger));
        private static readonly bool isDebugEnabled = log.IsDebugEnabled;
  
        public void MyMethod()
        {
                if(isDebugEnabled) 
                {
                        log.Debug("Entry number: " + i + " is " + entry[i]);
                }
        }
  }]]></source>
                                        <p>
                                                So why exactly is this faster? 
Well to start with the <span class="code">IsDebugEnabled</span>
                                                is not called for each log 
statement, it is called once per logger. Furthermore as the
                                                <span 
class="code">isDebugEnabled</span> variable is <span class="code">private 
static readonly</span>
                                                the JIT compiler can at 
<em>run-time</em> optimize out the <span class="code">if</span> test 
altogether. 
                                                This means that at runtime the 
JIT compiler won't even compile the logging statements into native code, i.e.
                                                all the logging just disappears.
                                        </p>
                                        <p>
                                                So what is the downside to 
using this? Well one of the clever features of log4net is that
                                                you can change the logging 
configuration while your program is running. If you need to 
                                                investigate an issue in your 
application, you don't have to stop the application, setup the
                                                logging and restart the 
application, you can change the logging configuration and the
                                                log4net will reload it (see 
<span class="code">XmlConfigurator.ConfigureAndWatch</span> APIs for more 
                                                information). However if the 
JIT has compiled out all of the logging statements
                                                then they are gone and you 
can't get them back by reloading the configuration file. Effectively
                                                this means that the logging 
configuration can only be set when the application loads and
                                                it cannot be changed at 
runtime. It is up to you to decide if you need ultimate speed or need
                                                to be able to reload the 
logging configuration while the application is running.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="Can the outputs of multiple 
client request go to different log files?">
                                        <p>
                                                Many developers are confronted 
with the problem of distinguishing the log 
                                                output originating from the 
same class but different client requests. They come 
                                                up with ingenious mechanisms to 
fan out the log output to different files. In 
                                                most cases, this is not the 
right approach.
                                        </p>
                                        <p>
                                                It is simpler to use a nested 
diagnostic context (<span class="code">NDC</span>). 
                                                Typically, one would <span 
class="code">NDC.Push()</span>
                                                client specific information, 
such as the client's hostname, ID or any other 
                                                distinguishing information when 
starting to handle the client's request. 
                                                Thereafter, log output will 
automatically include the nested diagnostic context 
                                                so that you can distinguish 
logs from different client requests even if they 
                                                are output to the same file.
                                        </p>
                                        <p>
                                                See the <span 
class="code">NDC</span> and the <span class="code">PatternLayout</span> classes 
for more 
                                                information.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="Logger instances seem to be 
create only. Why isn't there a method to remove logger instances?">
                                        <p>
                                                It is quite nontrivial to 
define the semantics of a "removed" logger which is 
                                                still referenced by the user.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="How do I get multiple process to 
log to the same file?">
                                        <p>
                                                The <span 
class="code">FileAppender</span> holds a write lock on the log
                                                file while it is logging. This 
prevents other processes from writing to the
                                                file, therefore it is not 
possible to have multiple processes log directly 
                                                to the same log file, even if 
they are on the same machine.
                                        </p>
                                        <p>
                                                You may have each process log 
to a <span class="code">RemotingAppender</span>. 
                                                The receiving <span 
class="code">RemoteLoggingServerPlugin</span> (or 
                                                <span 
class="code">IRemoteLoggingSink</span>) can receive all the events and 
                                                send them to a single log file.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
                                
  
                                <section name="If I have many processes across 
multiple hosts (possibly across multiple time zones) logging to the same file 
using the method above, what happens to timestamps?">
                                        <p>
                                                The timestamp is created when 
the logging event is created. That is so say, 
                                                when the <span 
class="code">Debug</span>, <span class="code">Info</span>, 
                                                <span class="code">Warn</span>, 
<span class="code">Error</span>
                                                or <span 
class="code">Fatal</span> method is invoked. This is unaffected by the time at 
                                                which they may arrive at a 
remote server. Since the timestamps are 
                                                stored in UTC format inside the 
event, they all appear in the same time zone as 
                                                the host creating the logfile. 
Since the clocks of various machines may not be 
                                                synchronized, this may account 
for time interval inconsistencies between events 
                                                generated on different hosts.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
                                
                                
                                <section name="When should I log my first 
message?">
                                        <p>
                                                The simple answer is as soon as 
possible. The long answer is more complex.
                                        </p>
                                        <p>
                                                If you are configuring log4net 
programmatically, i.e. by calling the 
                                                <span 
class="code">XmlConfigurator.Configure</span> method then you should do so
                                                before you begin logging and it 
is reasonable to do this very soon after application
                                                start.
                                        </p>
                                        <p>
                                                If you are configuring log4net 
by specifying assembly level attributes on 
                                                your assembly then the 
configuration will be loaded once the first call to
                                                the <span 
class="code">LogManager.GetLogger</span> is made. It is necessary
                                                that the first call to <span 
class="code">LogManager.GetLogger</span> made
                                                during the process (or 
AppDomain) is made from the assembly that has the
                                                configuration attributes. 
Log4net will look only once and only on the first 
                                                calling assembly for the 
configuration attributes.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
                                
                                
                        </section>
                        
                        <section name="Customization">
  
                                <section name="Can the log output format be 
customized?">
                                        <p>
                                                Yes. You can implement the 
<span class="code">log4net.Layout.ILayout</span> 
                                                interface to create you own 
customized log format, or you can extend the 
                                                <span 
class="code">LayoutSkeleton</span> class which provides a default
                                                implementation of the <span 
class="code">ILayout</span> interface.
                                                Appenders can be parameterized 
to use the layout of your choice.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
                                
                                
                                <section name="Can I write a custom appender?">
                                        <p>
                                                Yes. You can implement the 
<span class="code">log4net.Appender.IAppender</span> 
                                                interface to create you own 
customized appender. We recommend that you extend the
                                                <span 
class="code">log4net.Appender.AppenderSkeleton</span> class rather than
                                                starting from scratch. You 
should implement your custom code in a assembly
                                                separate from the log4net 
assembly. To get started it is worth looking at the
                                                source of the <span 
class="code">log4net.Appender.TraceAppender</span> as an
                                                example of the minimum amount 
of code required to get an appender working.
                                        </p>
                                        <p>
                                                To configure log4net to use 
your custom appender you need to specify the
                                                assembly qualified name of the 
appender type in the config file. For
                                                example:
                                        </p>
                                        <source language="xml"><![CDATA[
  <appender name="..." type="MyNamespace.MyAppender, MyAssembly">]]></source>
                                        <p>
                                                The .NET runtime will try to 
locate the assembly called <i>MyAssembly</i>.
                                                How .NET locates assemblies is 
beyond the scope of this FAQ.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
                        </section>
  
                        <section name="Troubleshooting">
  
                                <section id="internalDebug" name="How do I 
enable log4net internal debugging?">
                                        <p>
                                                There are several different 
ways to enable internal debugging in log4net.
                                                These different methods are 
listed below. The preferred method is to specify
                                                the <span 
class="code">log4net.Internal.Debug</span> option in the application's
                                                config file.
                                        </p>
                                        <ul>
                                                <li>
                                                        <p>
                                                                To enable 
log4net's internal debug programmatically you need
                                                                to set the 
<span class="code">log4net.helpers.LogLog.InternalDebugging</span>
                                                                property to 
<span class="code">true</span>. Obviously the sooner this
                                                                is set the more 
debug will be produced.
                                                        </p>
                                                </li>
                                                <li>
                                                        <p>
                                                                Internal 
debugging can also be enabled by setting a value in the application's
                                                                configuration 
file (not the log4net configuration file, unless the log4net config
                                                                data is 
embedded in the application's config file). The <span 
class="code">log4net.Internal.Debug</span>
                                                                application 
setting must be set to the value <span class="code">true</span>.
                                                                For example:
                                                        </p>
                                                        <source 
language="xml"><![CDATA[
  <?xml version="1.0" encoding="utf-8" ?>
  <configuration>
        <appSettings>
                <add key="log4net.Internal.Debug" value="true"/>
        </appSettings>
  </configuration>]]></source>
                                                        <p>
                                                                This setting is 
read immediately on startup an will cause all internal
                                                                debugging 
messages to be emitted.
                                                        </p>
                                                </li>
                                                <li>
                                                        <p>
                                                                To enable 
internal debugging from a configuration file, the 
                                                                <span 
class="code">debug</span> attribute on the log4net
                                                                configuration 
element can be set to the value <span class="code">true</span>. 
                                                                For example:
                                                        </p>
                                                        <source 
language="xml"><![CDATA[
  <log4net debug="true">
  
        ... configuration ...
        
  </log4net>]]></source>
                                                        <p>
                                                                Using this 
method does require that your configuration file is located
                                                                and loaded, 
otherwise the attribute will not be read. If you need to
                                                                debug the 
process of locating the configuration file then use one of the other
                                                                methods for 
enabling debugging.
                                                        </p>
                                                </li>
                                        </ul>
                                        <p>
                                                Internal debugging messages are 
written to the console and to the 
                                                <span 
class="code">System.Diagnostics.Trace</span>
                                                system. If the application does 
not have a console the messages logged
                                                there will be lost. Note that 
an application can redirect the console
                                                stream by setting the <span 
class="code">System.Console.Out</span>. The
                                                Trace system will by default 
send the message to an attached debugger
                                                (where the messages will appear 
in the output window). If the process
                                                does not have a debugger 
attached then the messages are sent to the 
                                                system debugger. A utility like 
DebugView from 
                                                <a 
href="http://www.sysinternals.com";>http://www.sysinternals.com</a>
                                                may be used to capture these 
messages.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section id="trouble-EventLog" name="Why 
doesn't the EventLogAppender work?">
                                        <p>
                                                If you are not getting events 
delivered to the event log this usually indicates 
                                                a permissions problem. 
Basically if the event log does not exist the EventLogAppender 
                                                tries to create it, but you 
need local administrator permissions to create event logs 
                                                (just to write into the right 
bit of the registry). You don't need administrator 
                                                permissions to log to an 
existing event log, but it must exist. If you are using the 
                                                event log from a web 
application or service using the event log can be a little tricky. 
                                        </p>
                                        <p>
                                                A web application will run as 
the user account ASPNET. This account deliberately has 
                                                few permissions to reduce the 
chances of someone hacking into the web server. While the 
                                                account has permission to write 
to the event log it does not have permission to create 
                                                event sources (registry create 
and write access), which are needed to write to the event log.
                                        </p>
                                        <p>
                                                There are a couple of solutions:
                                        </p>
                                        <ol>
                                                <li>
                                                        <p>
                                                                Make the ASPNET 
user a member of the Administrators group. This will work because the 
                                                                user will then 
have the required permissions. This is not recommended for production use.
                                                        </p>
                                                </li>
                                                <li>
                                                        <p>
                                                                As the event 
source only needs to be created once for the machine, create an installer
                                                                and configure 
it to create the event source. 
                                                                The installer 
will need to be run as Administrator (don't they all). See 
                                                                <span 
class="code">System.Diagnostics.EventLogInstaller</span> in the Microsoft .NET 
                                                                Framework SDK 
for an example of how to create a simple event log installer.
                                                        </p>
                                                </li>
                                        </ol>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="Why can't I log to a 
FileAppender from a web application?">
                                        <p>
                                                The web application runs as a 
special user account on the web server
                                                called ASPNET. This account has 
restricted permissions to protect the 
                                                web server from attacks. By 
default this account may not have permission
                                                to write to the file system. 
Make sure that the ASPNET account has 
                                                permission to create and write 
to files in the directory chosen for
                                                logging.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="Why doesn't the logging in my 
service work?">
                                        <p>
                                                A windows service runs as a 
user account specified in the services
                                                control panel. This account may 
have restricted permissions, make 
                                                sure that the account has 
permission to create and write to files 
                                                in the directory chosen for 
logging.
                                        </p>
                                        <p>
                                                A windows service is launched 
by windows. The current directory in
                                                a service is set to the windows 
system directory (e.g. 
                                                <span 
class="code">C:\Windows\System32</span>). If you are loading
                                                the configuration file from the 
current directory then be aware
                                                that this path will not be the 
location of your assemblies.
                                                The best way to get the path to 
your assemblies is to use
                                                <span 
class="code">AppDomain.BaseDirectory</span>.
                                                Note that the log4net internals 
never use the current directory.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
                                
                                <section name="I am having trouble using the 
AdoNetAppender to connect to my database?">
                                        <p>
                                                For details on the different 
ways in which ADO.NET can connect to a database see:
                                                <a 
href="http://msdn.microsoft.com/library/en-us/cpguide/html/cpconadonetconnections.asp";>Connecting
 to a Data Source Using ADO.NET</a>.
                                        </p>
                                        <p>
                                                If you need to use ODBC to 
connect to your database then please note that the
                                                ADO.NET ODBC drivers are not 
included in the standard .NET framework redistributable.
                                                You can download the drivers 
from microsoft download at: 
                                                <a 
href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6ccd8427-1017-4f33-a062-d165078e32b1";>ODBC
 .NET Data Provider</a>.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                                <section name="How do I report bugs?">
                                        <p>
                                                See the <a 
href="../../support.html">support</a> page for details.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
  
  
                        </section>
                        
                        <section name="Miscellaneous">
                        
                                <section name="How do I make log4net appear in 
the Visual Studio Add References dialog?">
                                        <p>
                                                There is a good discussion of 
this topic on Robert GcLaws blog:
                                                <a 
href="http://weblogs.asp.net/rmclaws/archive/2003/11/15/37743.aspx";>Building a 
Better Server Control Experience, Part 2</a>.
                                        </p>
                                </section>
                                <p><a href="#top">Back to Top</a></p>
                                
                        </section>
                        
                </section>
  
        </body>
  </document>
  
  
  

Reply via email to