blob: 3a91b0f0dd8ce131287bfe0a8d45ca4e98d38305 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--
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.
-->
<!-- Generated by Apache Maven Doxia at 2017-04-28 -->
<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 &#x2013; Apache log4net: Frequently Asked Questions - Apache log4net</title>
<link rel="stylesheet" href="../css/bootstrap.min.css" type="text/css" />
<link rel="stylesheet" href="../css/site.css" type="text/css" />
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script type="text/javascript" src="../js/bootstrap.min.js"></script>
<script type="text/javascript" src="../js/prettify.min.js"></script>
<script type="text/javascript" src="../js/site.js"></script>
<meta name="author" content="Nicko Cadell" />
<meta name="Date-Revision-yyyymmdd" content="20170428" />
<meta http-equiv="Content-Language" content="en" />
<meta name="keywords" content="log4net frequently asked questions, log4net faq, log4net" />
</head>
<body class="composite">
<a href="https://logging.apache.org/">
<img class="logo-left" src="../images/ls-logo.jpg" alt="Apache logging services logo" />
</a>
<!--img class="logo-right" src="../images/logo.png" alt="Apache log4net logo" /-->
<div class="clear"></div>
<div class="navbar">
<div class="navbar-inner">
<div class="container-fluid">
<a class="brand" href="http://logging.apache.org/log4net/">Apache log4net &trade;</a>
<ul class="nav">
<li>
<a href="https://wiki.apache.org/logging" class="external" target="_blank" title="Logging Wiki">Logging Wiki</a>
</li>
<li>
<a href="https://www.apache.org/" class="external" target="_blank" title="Apache">Apache</a>
</li>
<li>
<a href="https://logging.apache.org/" class="external" target="_blank" title="Logging Services">Logging Services</a>
</li>
<li>
<a href="https://github.com/apache/logging-log4net/" class="external" target="_blank" title="GitHub">GitHub</a>
</li>
</ul>
</div>
</div>
</div>
<div class="container-fluid">
<table class="layout-table">
<tr>
<td class="sidebar">
<div class="well sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><i class="icon-home"></i>Apache log4net</li>
<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>
<ul class="nav nav-list">
<li class="nav-header"><i class="icon-file"></i>Documentation</li>
<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 active">
<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>
<ul class="nav nav-list">
<li class="nav-header"><i class="icon-book"></i>Manual</li>
<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">
<a href="../release/manual/internals.html" title="Internals">Internals</a>
</li>
</ul>
<ul class="nav nav-list">
<li class="nav-header"><i class="icon-pencil"></i>For Contributors</li>
<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>
<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>
<ul class="nav nav-list">
<li class="nav-header"><i class="icon-cog"></i>Project Reports</li>
<li class="none">
<a href="../rat-report.html" title="RAT Report">RAT Report</a>
</li>
</ul>
<ul class="nav nav-list">
<li class="nav-header"><i class="icon-info-sign"></i>Apache</li>
<li class="none">
<a href="http://www.apache.org/" class="external" target="_blank" title="Home">Home</a>
</li>
<li class="none">
<a href="http://www.apache.org/licenses/" class="external" target="_blank" title="License">License</a>
</li>
<li class="none">
<a href="http://www.apache.org/foundation/sponsorship.html" class="external" target="_blank" title="Sponsorship">Sponsorship</a>
</li>
<li class="none">
<a href="http://www.apache.org/foundation/thanks.html" class="external" target="_blank" title="Thanks">Thanks</a>
</li>
<li class="none">
<a href="http://www.apache.org/security/" class="external" target="_blank" title="Security">Security</a>
</li>
<li class="none">
<a href="http://www.apachecon.com" class="external" target="_blank" title="Conferences">Conferences</a>
</li>
</ul>
</div>
<div id="poweredBy">
<a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy">
<img class="poweredBy" alt="Built by Maven" src="../images/maven-feather.png" />
</a>
</div>
</td>
<td class="content">
<!-- 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="top">
</a>
<a name="main"></a>
<div class="section" id="main">
<h2><a name="Apache_log4net_Frequently_Asked_Questions"></a>Apache log4net&#x2122; Frequently Asked Questions</h2>
<a name="information"></a>
<div class="section" id="information">
<h2><a name="Information"></a>Information</h2>
<a name="what-is-log4net"></a>
<div class="section" id="what-is-log4net">
<h2><a name="What_is_log4net"></a>What is log4net?</h2>
<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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="reliability"></a>
<div class="section" id="reliability">
<h2><a name="Is_log4net_a_reliable_logging_system"></a>Is log4net a reliable logging system?</h2>
<p>
No. log4net is not reliable. It is a best-effort and <i>fail-stop</i> 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 class="externalLink" href="mailto:log4net-user@logging.apache.org">
log4net-user@logging.apache.org</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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="prerequisites"></a>
<div class="section" id="prerequisites">
<h2><a name="What_are_the_prerequisites_for_log4net"></a>What are the prerequisites for log4net?</h2>
<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&#xae; .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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="examples"></a>
<div class="section" id="examples">
<h2><a name="Is_there_example_code_for_using_log4net"></a>Is there example code for using log4net?</h2>
<p>
There is a directory containing examples in <span class="code">log4net\examples</span>.
The examples are broken down by framework.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="features"></a>
<div class="section" id="features">
<h2><a name="What_are_the_features_of_log4net"></a>What are the features of log4net?</h2>
<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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="thread-safe"></a>
<div class="section" id="thread-safe">
<h2><a name="Is_log4net_thread-safe"></a>Is log4net thread-safe?</h2>
<p>
Yes, log4net is thread-safe.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="output"></a>
<div class="section" id="output">
<h2><a name="What_does_log_output_look_like"></a>What does log output look like?</h2>
<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>
<div class="source">
<pre>
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.</pre></div>
<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 <i>nested diagnostic context</i> (<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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="loggers"></a>
<div class="section" id="loggers">
<h2><a name="What_are_Loggers"></a>What are Loggers?</h2>
<p>
The logger concept lies at the heart of log4net's configuration. Loggers are organized into a
hierarchy and give the programmer <i>run-time</i> 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 <i>and</i> its logger.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="contributing"></a>
<div class="section" id="contributing">
<h2><a name="Why_should_I_donate_my_extensions_to_log4net_back_to_the_project"></a>Why should I donate my extensions to log4net back to the project?</h2>
<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. <i>You are free to do whatever you wish with
your proprietary log4net extensions.</i> In particular, you may choose to
never release your extensions to the wider public. For details see the
<a class="externalLink" 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 &quot;stupid-tax&quot;.
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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="contributing-guidelines"></a>
<div class="section" id="contributing-guidelines">
<h2><a name="What_should_I_keep_in_mind_when_contributing_code"></a>What should I keep in mind when contributing code?</h2>
<ol style="list-style-type: decimal">
<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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="history"></a>
<div class="section" id="history">
<h2><a name="What_is_the_history_of_log4net"></a>What is the history of log4net?</h2>
<p>
log4net is a port of the popular <a class="externalLink" href="http://logging.apache.org/log4j/">Apache log4j&#x2122;</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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="download"></a>
<div class="section" id="download">
<h2><a name="Where_can_I_find_the_latest_distribution_of_log4net"></a>Where can I find the latest distribution of log4net?</h2>
<p>
The log4net <a class="externalLink" href="http://logging.apache.org/log4net/">home page</a> is a good place to start.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="two-snks"></a>
<div class="section" id="two-snks">
<h2><a name="Why_are_there_two_different_strong_name_keys"></a>Why are there two different strong name keys?</h2>
<p>
Starting with log4net 1.2.11 there are two
different binary distributions,
<tt>oldkey</tt> and <tt>newkey</tt>.
</p>
<p>
The <tt>oldkey</tt> distribution contains
assemblies signed with the same strong name key
that was used to sign the assemblies of log4net
1.2.10 and earlier. This strong name key is only
available to log4net developers.
</p>
<p>
The <tt>newkey</tt> distribution contains
assemblies signed with the strong name key
available from <a class="externalLink" href="https://svn.apache.org/repos/asf/logging/log4net/trunk/log4net.snk">log4net's
svn area</a> or inside the source distribution.
Everybody can create assemblies that have the same
strong name.
</p>
<p>
For open source projects it is important that you
can create your own patched version of a product
and use it instead of the official release. This
is something that is now possible if the
<tt>newkey</tt> is used throughout.
</p>
<p>
The <tt>oldkey</tt> distribution is mostly
only for people who work with third-party
dependencies that require one of the earlier
releases of log4net and can't be recompiled to use
the new strong name. If you start a new project
or can recompile all your dependencies we strongly
recommend you use the <tt>newkey</tt>
assemblies.
</p>
<p>
If you are creating an assembly that is likely to
be combined with other assemblies that depend on
the old strong name, then it is better you use the
oldkey assemblies as well.
</p>
<p>
We currently plan to distribute the new-key
assembly under a different name while providing
old and newkey <tt>log4net.dll</tt> assemblies
holding type forwards to the new assembly. This
may create a cleaner migration path for projects
that have dependencies using both versions.
At the moment such projects will either need to
use the GAC or create sub-directories inside the
application directory and configure assembly
probing with a <tt>privatePath</tt>.
</p>
<p>
Note that the &quot;new&quot; strong name no longer provides
any kind of authenticity. If you want to be sure
you have the &quot;real&quot; Apache log4net, download the binary
release from one of the mirrors and verify the PGP
signature.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
</div>
<a name="configuration"></a>
<div class="section" id="configuration">
<h2><a name="Configuration"></a>Configuration</h2>
<a name="dynamic"></a>
<div class="section" id="dynamic">
<h2><a name="How_can_I_change_log_behavior_at_runtime"></a>How can I change log behavior at runtime?</h2>
<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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="runtime-disable"></a>
<div class="section" id="runtime-disable">
<h2><a name="How_do_I_completely_disable_all_logging_at_runtime"></a>How do I completely disable all logging at runtime?</h2>
<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 &quot;threshold&quot; attribute on the log4net configuration element to &quot;OFF&quot;.
For example:
</p>
<div class="source">
<pre>
&lt;log4net threshold=&quot;OFF&quot; /&gt;</pre></div>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="appender-options"></a>
<div class="section" id="appender-options">
<h2><a name="What_are_the_configurable_options_for_an_appender"></a>What are the configurable options for an appender?</h2>
<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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="appender-level"></a>
<div class="section" id="appender-level">
<h2><a name="Is_it_possible_to_direct_log_output_to_different_appenders_by_level"></a>Is it possible to direct log output to different appenders by level?</h2>
<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 <i>lower</i> 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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="config-reload"></a>
<div class="section" id="config-reload">
<h2><a name="Is_there_a_way_to_get_log4net_to_automatically_reload_a_configuration_file_if_it_changes"></a>Is there a way to get log4net to automatically reload a configuration file if it changes?</h2>
<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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="appender-assembly"></a>
<div class="section" id="appender-assembly">
<h2><a name="Can_I_load_an_appender_from_another_assembly"></a>Can I load an appender from another assembly?</h2>
<p>
Yes. When specifying the type in the configuration file you can give the assembly
qualified name of the type. For example:
</p>
<div class="source">
<pre>
&lt;appender name=&quot;...&quot; type=&quot;MyNamespace.MyAppender, MyAssembly&quot;&gt;</pre></div>
<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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="assembly-public-key"></a>
<div class="section" id="assembly-public-key">
<h2><a name="How_do_I_get_the_Public_Key_for_an_assembly"></a>How do I get the Public Key for an assembly?</h2>
<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 class="externalLink" href="http://www.aisto.com/roeder/dotnet">http://www.aisto.com/roeder/dotnet</a>.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="layout-header-xml-newlines"></a>
<div class="section" id="layout-header-xml-newlines">
<h2><a name="How_do_I_insert_newlines_into_the_layout_header"></a>How do I insert newlines into the layout header?</h2>
<p>
Newlines in the config file need to be escaped using an XML numeric character reference.
The sequence that represents a CR LF is &amp;#13; &amp;#10;. The following example adds
a header and footer to the output each followed by a newline.
</p>
<div class="source">
<pre>
&lt;layout type=&quot;log4net.Layout.PatternLayout&quot;&gt;
&lt;header value=&quot;[Header]&amp;#13;&amp;#10;&quot; /&gt;
&lt;footer value=&quot;[Footer]&amp;#13;&amp;#10;&quot; /&gt;
&lt;conversionPattern value=&quot;%date [%thread] %-5level %logger - %message%newline&quot; /&gt;
&lt;/layout&gt;</pre></div>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="pattern-string"></a>
<div class="section" id="pattern-string">
<h2><a name="How_do_I_use_a_pattern_to_set_the_value_of_a_string_property"></a>How do I use a pattern to set the value of a string property?</h2>
<p>
Log4net supports a pattern syntax for setting string properties similar to the
<span class="code">PatternLayout</span> used to format the output messages.
This pattern syntax can be used by specifying <span class="code">type=&quot;log4net.Util.PatternString&quot;</span>
on the string property in the config file. This tells the config parser to pass the
value to the <span class="code">PatternString</span> type before converting the result
to a string. For details on the patterns supported see the <a href="sdk/html/T_log4net_Util_PatternString.htm">
PatternString SDK Reference</a>.
</p>
<p>
The following example sets the file name for a <span class="code">FileAppender</span> to include the
current process id by specifying the <span class="code">%processid</span> pattern in the
<span class="code">File</span> property.
</p>
<div class="source">
<pre>
&lt;appender name=&quot;LogFileAppender&quot; type=&quot;log4net.Appender.FileAppender&quot;&gt;
&lt;file type=&quot;log4net.Util.PatternString&quot; value=&quot;log-file-[%processid].txt&quot; /&gt;
&lt;layout type=&quot;log4net.Layout.PatternLayout&quot; value=&quot;%date [%thread] %-5level %logger - %message%newline&quot; /&gt;
&lt;/appender&gt;</pre></div>
</div>
<p><a href="#top">Back to Top</a></p>
</div>
<a name="implementing"></a>
<div class="section" id="implementing">
<h2><a name="Implementing_Logging"></a>Implementing Logging</h2>
<a name="naming"></a>
<div class="section" id="naming">
<h2><a name="Are_there_any_suggested_ways_for_naming_loggers"></a>Are there any suggested ways for naming loggers?</h2>
<p>
Yes, there are.
</p>
<p>
You can name logging loggers by <b>locality</b>. 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 <b>functional areas</b>. For example, the
&quot;database&quot; logger, &quot;remoting&quot; logger, &quot;security&quot; logger, or the &quot;XML&quot;
logger.
</p>
<p>
You may choose to name loggers by functionality and subcategorize by
locality, as in &quot;DATABASE.MyApp.MyClass&quot; or
&quot;DATABASE.MyApp.MyModule.MyOtherClass&quot;.
</p>
<p>
<i>You are totally free in choosing the names of your loggers.</i> 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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="static-class-name"></a>
<div class="section" id="static-class-name">
<h2><a name="How_do_I_get_the_fully-qualified_name_of_a_class_in_a_static_block"></a>How do I get the fully-qualified name of a class in a static block?</h2>
<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>
<div class="source">
<pre>
public class Foo
{
private static readonly ILog log = LogManager.GetLogger(typeof(Foo));
... other code
}</pre></div>
<p>
An equivalent and more portable solution, though slightly longer, is to use the declaring type
of the static constructor.
</p>
<div class="source">
<pre>
public class Foo
{
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
... other code
}</pre></div>
<p>
<b>Note:</b> the .NET Compact Framework 1.0 does not support <span class="code">System.Reflection.MethodBase.GetCurrentMethod()</span>.
</p>
<p>
<b>Note:</b> the two forms are only equivalent
if <span class="code">Foo</span> is not a
generic class. For a generic class <span class="code">Foo&lt;T&gt;</span> the variant
using <span class="code">typeof</span> generates
a different logger for each different type
parameter <span class="code">T</span> while the
variant using reflection generates the same
logger for all <span class="code">T</span>s.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="perf-not-logging"></a>
<div class="section" id="perf-not-logging">
<h2><a name="What_is_the_fastest_way_of_not_logging"></a>What is the fastest way of (not) logging?</h2>
<p>
For some logger <span class="code">log</span>, writing,
</p>
<div class="source">
<pre>
log.Debug(&quot;Entry number: &quot; + i + &quot; is &quot; + entry[i]);</pre></div>
<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>
<div class="source">
<pre>
if(log.IsDebugEnabled)
{
log.Debug(&quot;Entry number: &quot; + i + &quot; is &quot; + entry[i]);
}</pre></div>
<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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="perf-not-logging2"></a>
<div class="section" id="perf-not-logging2">
<h2><a name="What_is_REALLY_the_FASTEST_way_of_not_logging"></a>What is REALLY the FASTEST way of (not) logging?</h2>
<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>
<div class="source">
<pre>
if(log.IsDebugEnabled)
{
log.Debug(&quot;Entry number: &quot; + i + &quot; is &quot; + entry[i]);
}</pre></div>
<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>
<div class="source">
<pre>
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(&quot;Entry number: &quot; + i + &quot; is &quot; + entry[i]);
}
}
}</pre></div>
<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 <i>run-time</i> 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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="multiple-files"></a>
<div class="section" id="multiple-files">
<h2><a name="Can_the_outputs_of_multiple_client_request_go_to_different_log_files"></a>Can the outputs of multiple client request go to different log files?</h2>
<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 context property or stack (<span class="code">ThreadContext</span>).
Typically, one would <span class="code">ThreadContext.Properties[&quot;ID&quot;] = &quot;XXX&quot;</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 context data
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">ThreadContext</span> and the <span class="code">PatternLayout</span> classes for more
information.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="remove-logger"></a>
<div class="section" id="remove-logger">
<h2><a name="Logger_instances_seem_to_be_create_only._Why_isnt_there_a_method_to_remove_logger_instances"></a>Logger instances seem to be create only. Why isn't there a method to remove logger instances?</h2>
<p>
It is quite nontrivial to define the semantics of a &quot;removed&quot; logger which is
still referenced by the user.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="single-file"></a>
<div class="section" id="single-file">
<h2><a name="How_do_I_get_multiple_process_to_log_to_the_same_file"></a>How do I get multiple process to log to the same file?</h2>
<p>
Before you even start trying any of the
alternatives provided, ask yourself whether you
really need to have multiple processes log to the
same file, then don't do it ;-).
</p>
<p>
FileAppender offers pluggable locking models for
this usecase but all existing implementations have
issues and drawbacks.
</p>
<p>
By default the <span class="code">FileAppender</span> holds an
exclusive write lock on the log file while it
is logging. This prevents other processes from
writing to the file. This model is known to
break down with (at least on some versions of)
Mono on Linux and log files may get corrupted
as soon as another process tries to access the
log file.
</p>
<p>
<span class="code">MinimalLock</span> only
acquires the write lock while a log is being
written. This allows multiple processes to
interleave writes to the same file, albeit with
a considerable loss in performance.
</p>
<p>
<span class="code">InterProcessLock</span>
doesn't lock the file at all but synchronizes
using a system wide Mutex. This will only work
if all processes cooperate (and use the same
locking model). The acquisition and release of a
Mutex for every log entry to be written will
result in a loss of performance, but the Mutex
is preferable to the use of MinimalLock.
</p>
<p>
If you use <span class="code">RollingFileAppender</span> things
become even worse as several process may try to
start rolling the log file concurrently. <span class="code">RollingFileAppender</span>
completely ignores the locking model when
rolling files, rolling files is simply not
compatible with this scenario.
</p>
<p>
A better alternative is to have your processes
log to <span class="code">RemotingAppenders</span>. Using
the <span class="code">RemoteLoggingServerPlugin</span>
(or <span class="code">IRemoteLoggingSink</span>) a
process can receive all the events and log
them to a single log file. One of the
examples shows how to use the <span class="code">RemoteLoggingServerPlugin</span>.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="distributed"></a>
<div class="section" id="distributed">
<h2><a name="If_I_have_many_processes_across_multiple_hosts_possibly_across_multiple_time_zones_logging_to_the_same_file_using_the_RemotingAppender_what_happens_to_timestamps"></a>If I have many processes across multiple hosts (possibly across multiple time zones) logging to the same file using the RemotingAppender, what happens to timestamps?</h2>
<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
transmitted in UTC format by the <span class="code">RemotingAppender</span>,
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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="first-log"></a>
<div class="section" id="first-log">
<h2><a name="When_should_I_log_my_first_message"></a>When should I log my first message?</h2>
<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>
</div>
<p><a href="#top">Back to Top</a></p>
</div>
<a name="customization"></a>
<div class="section" id="customization">
<h2><a name="Customization"></a>Customization</h2>
<a name="custom-output"></a>
<div class="section" id="custom-output">
<h2><a name="Can_the_log_output_format_be_customized"></a>Can the log output format be customized?</h2>
<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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="custom-appender"></a>
<div class="section" id="custom-appender">
<h2><a name="Can_I_write_a_custom_appender"></a>Can I write a custom appender?</h2>
<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>
<div class="source">
<pre>
&lt;appender name=&quot;...&quot; type=&quot;MyNamespace.MyAppender, MyAssembly&quot;&gt;</pre></div>
<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>
</div>
<p><a href="#top">Back to Top</a></p>
</div>
<a name="troubleshooting"></a>
<div class="section" id="troubleshooting">
<h2><a name="Troubleshooting"></a>Troubleshooting</h2>
<a name="internalDebug"></a>
<div class="section" id="internalDebug">
<h2><a name="How_do_I_enable_log4net_internal_debugging"></a>How do I enable log4net internal debugging?</h2>
<p>
There are 2 different ways to enable internal debugging in log4net.
These 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>
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>
<div class="syntax">
<div>
<pre class="code">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;configuration&gt;
&lt;appSettings&gt;
&lt;add key=&quot;log4net.Internal.Debug&quot; value=&quot;true&quot;/&gt;
&lt;/appSettings&gt;
&lt;/configuration&gt;</pre></div></div>
<p>
This setting is read immediately on startup an will cause all internal
debugging messages to be emitted.
</p>
</li>
<li>
<p>
To enable log4net's internal debug programmatically you need
to set the <span class="code">log4net.Util.LogLog.InternalDebugging</span>
property to <span class="code">true</span>. Obviously the sooner this
is set the more debug will be produced.
</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 class="externalLink" href="http://www.sysinternals.com">http://www.sysinternals.com</a>
may be used to capture these messages.
</p>
<p>
As log4net internal debug messages are written to the <span class="code">System.Diagnostics.Trace</span>
system it is possible to redirect those messages to a local file. You can define
a trace listener by adding the following to your application's .config file:
</p>
<div class="syntax">
<div>
<pre class="code">
&lt;configuration&gt;
...
&lt;system.diagnostics&gt;
&lt;trace autoflush=&quot;true&quot;&gt;
&lt;listeners&gt;
&lt;add
name=&quot;textWriterTraceListener&quot;
type=&quot;System.Diagnostics.TextWriterTraceListener&quot;
initializeData=&quot;C:\tmp\log4net.txt&quot; /&gt;
&lt;/listeners&gt;
&lt;/trace&gt;
&lt;/system.diagnostics&gt;
...
&lt;/configuration&gt;</pre></div></div>
<p>
Make sure that the process running your application has permission
to write to this file.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="trouble-evaluate-configurationerrors-at-runtime"></a>
<div class="section" id="trouble-evaluate-configurationerrors-at-runtime">
<h2><a name="How_can_I_evaluate_configuration_errors_at_runtime"></a>How can I evaluate configuration errors at runtime?</h2>
<p>
To prevent silent failure of log4net as reported as <a class="externalLink" href="http://issues.apache.org/jira/browse/LOG4NET-342">LOG4NET-342</a>,
log4net supports a way to evaluate if it was configured and also to evaluate messages generated on startup since 1.2.11. To
check if log4net was started and configured properly one can check the property
<span class="code">log4net.Repository.ILoggerRepository.Configured</span> and enumerate the configuration messages as follows:
</p>
<div class="syntax">
<div>
<pre class="code">
if(!log4net.LogManager.GetRepository().Configured)
{
// log4net not configured
foreach(log4net.Util.LogLog message in log4net.LogManager.GetRepository().ConfigurationMessages.Cast&lt;log4net.Util.LogLog())
{
// evaluate configuration message
}
}
</pre></div>
</div>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="trouble-EventLog"></a>
<div class="section" id="trouble-EventLog">
<h2><a name="Why_doesnt_the_EventLogAppender_work"></a>Why doesn't the EventLogAppender work?</h2>
<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 style="list-style-type: decimal">
<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 <b>not recommended</b>
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>
<p>
There is a Microsoft Knowledge Base article that covers this issue and how to resolve
it. <a class="externalLink" href="http://support.microsoft.com/default.aspx?scid=kb;en-us;329291">
PRB: &quot;Requested Registry Access Is Not Allowed&quot; Error Message When ASP.NET
Application Tries to Write New EventSource in the EventLog</a>.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="trouble-file-perm"></a>
<div class="section" id="trouble-file-perm">
<h2><a name="Why_cant_I_log_to_a_FileAppender_from_a_web_application"></a>Why can't I log to a FileAppender from a web application?</h2>
<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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="trouble-service"></a>
<div class="section" id="trouble-service">
<h2><a name="Why_doesnt_the_logging_in_my_service_work"></a>Why doesn't the logging in my service work?</h2>
<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>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="trouble-webapp-stops-logging"></a>
<div class="section" id="trouble-webapp-stops-logging">
<h2><a name="Why_does_my_ASP.NET_web_application_stop_logging_when_deployed_on_an_IIS"></a>Why does my ASP.NET web application stop logging when deployed on an IIS?</h2>
<p>
This problem has been reported by several people as issue
<a class="externalLink" href="https://issues.apache.org/jira/browse/LOG4NET-178">LOG4NET-178</a>.
The issue seems to be caused by a broken LOG4NET configuration
or a timing problem caused by an application shutdown event that
floats in late after an application start event and thus LOG4NET
stops logging immediately after it has been started.
</p>
<p>
The first thing step to troubleshoot problems is enabling
the log4net internal debugging features as described
<a class="externalLink" href="http://logging.apache.org/log4net/release/faq.html#internalDebug">here</a>
and fix all errors that pop up. If the problem still persists,
<a class="externalLink" href="https://issues.apache.org/jira/browse/LOG4NET-178?focusedCommentId=13504094&amp;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13504094">this comment</a>
suggests to move the LOG4NET configuration out of the
<span class="code">web.config</span> into a separate file
like <span class="code">log4net.config</span>. Finally,
if both previous steps did not help and the problem still
occurs, you can try to work around the event timing problem
by invoking the configuration call from the class constructor as described in
<a class="externalLink" href="https://issues.apache.org/jira/browse/LOG4NET-178?focusedCommentId=13504485&amp;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13504485">this comment</a>.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="trouble-db"></a>
<div class="section" id="trouble-db">
<h2><a name="I_am_having_trouble_using_the_AdoNetAppender_to_connect_to_my_database"></a>I am having trouble using the AdoNetAppender to connect to my database?</h2>
<p>
For details on the different ways in which ADO.NET can connect to a database see:
<a class="externalLink" 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 class="externalLink" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6ccd8427-1017-4f33-a062-d165078e32b1">ODBC .NET Data Provider</a>.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="report-bugs"></a>
<div class="section" id="report-bugs">
<h2><a name="How_do_I_report_bugs"></a>How do I report bugs?</h2>
<p>
First make sure it really is a bug and not a
usage error. When in doubt, ask on the <a href="../mail-lists.html">log4net-user mailing
list</a> first.
</p>
<p>
If you have identified a bug, please report it
via our <a href="../issue-tracking.html">Issue
Tracker</a>. You may want to check it hasn't
been reported before by searching the existing
issues.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="log-early"></a>
<div class="section" id="log-early">
<h2><a name="log4net_doesnt_log_when_built_in_RELEASE_mode"></a>log4net doesn't log when built in RELEASE mode</h2>
<p>
If you use attributes to configure log4net then
the order by which assemblies are loaded may
determine whether you attributes are used or
not. Assembly load order may be different in
DEBUG and RELEASE mode.
</p>
<p>
As stated in <a href="manual/configuration.html#attributes">the
manual</a> the attribute will only be read for
the first assembly that tries to use log4net.
So it is important that you obtain your
<tt>ILog</tt> instance as early as possible.
</p>
<p>
For a command line application &quot;as early as
possible&quot; probably is the class holding the
<tt>Main</tt> method, for a Web-Application
it would be your <tt>Global.asax</tt> class
and for a Windows Service it would be the class
deriving from <tt>ServiceBase</tt>.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="no-explicit-configuration"></a>
<div class="section" id="no-explicit-configuration">
<h2><a name="log4net_doesnt_log_at_all"></a>log4net doesn't log at all</h2>
<p>
You may have overlooked initialization code for
log4net in your application. log4net can be
initialized explicitly by calling one of the
configurators
(e.g. <tt>BasicConfigurator</tt> or
<tt>XmlConfigurator</tt> in the
<tt>log4net.Config</tt> namespace, or
implicitly by including the
<tt>[XmlConfiguratorAttribute]</tt> in the
assembly where log4net is first used.
</p>
<p>
See <a href="manual/configuration.html">the
manual</a> for more information. If you use
attributes to configure log4net then the order
by which assemblies are loaded may determine
whether you attributes are used or not.
Assembly load order may be different in DEBUG
and RELEASE mode. See also <a href="#log-early">log4net doesn't log when built
in RELEASE mode</a>.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
<a name="adonet-doesnt-reconnect"></a>
<div class="section" id="adonet-doesnt-reconnect">
<h2><a name="The_ADO.NET_Appender_doesnt_reconnect________________________________after_a_DB_failure_on_.NET_4.5.1"></a>The ADO.NET Appender doesn't reconnect after a DB failure on .NET 4.5.1</h2>
<p>
Starting with .NET 4.5.1 ADO.NET has added
connection resiliency which is supposed to
re-establish the connection as part if the
framework. As a result log4net doesn't know the
connection is broken and will never attempt to
re-establish the connection.
</p>
<p>
Unfortunately re-connecting doesn't seem to be
working reliably. A workaround may be to add
<tt>ConnectRetryCount=0</tt> to your
connection string.
</p>
<p>
For details see <a class="externalLink" href="https://issues.apache.org/jira/browse/LOG4NET-442">LOG4NET-442</a>
</p>
</div>
</div>
<a name="misc"></a>
<div class="section" id="misc">
<h2><a name="Miscellaneous"></a>Miscellaneous</h2>
<a name="vsnet-add-reference"></a>
<div class="section" id="vsnet-add-reference">
<h2><a name="How_do_I_make_log4net_appear_in_the_Visual_Studio_Add_References_dialog"></a>How do I make log4net appear in the Visual Studio Add References dialog?</h2>
<p>
There is a good discussion of this topic on Robert McLaws blog:
<a class="externalLink" href="http://weblogs.asp.net/rmclaws/archive/2003/11/15/37743.aspx">Building a Better Server Control Experience, Part 2</a>.
</p>
</div>
<a name="nuget"></a>
<div class="section" id="nuget">
<h2><a name="Do_you_provide_a_Nuget_package"></a>Do you provide a Nuget package?</h2>
<p>
Starting with version 2.0.6 we provide <a class="externalLink" href="https://www.nuget.org/packages/log4net/" rel="nofollow">Nuget packages</a>. For earlier
versions <a class="externalLink" href="http://blog.cincura.net/" rel="nofollow">Ji&#x159;&#xed; &#x10c;in&#x10d;ura</a> has kindly created
Nuget packages.
</p>
</div>
<p><a href="#top">Back to Top</a></p>
</div>
</div>
</td>
</tr>
</table>
</div>
<div class="footer">
<p>Copyright &copy; 2004-2017 <a class="external" href="http://www.apache.org">Apache Software Foundation</a>. All Rights Reserved.</p>
<p>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.</p>
<p>Site powered by <a class="external" href="http://getbootstrap.com/">Twitter Bootstrap</a>. Icons from <a class="external" href="http://glyphicons.com/">Glyphicons Free</a>.</p>
</div>
</div>
</body>
</html>