From commits-return-488-apmail-logging-commits-archive=logging.apache.org@logging.apache.org Tue Feb 14 17:12:04 2012 Return-Path: X-Original-To: apmail-logging-commits-archive@minotaur.apache.org Delivered-To: apmail-logging-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 0EF8E9B40 for ; Tue, 14 Feb 2012 17:12:03 +0000 (UTC) Received: (qmail 81342 invoked by uid 500); 14 Feb 2012 17:12:03 -0000 Delivered-To: apmail-logging-commits-archive@logging.apache.org Received: (qmail 81287 invoked by uid 500); 14 Feb 2012 17:12:02 -0000 Mailing-List: contact commits-help@logging.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@logging.apache.org Delivered-To: mailing list commits@logging.apache.org Received: (qmail 81267 invoked by uid 99); 14 Feb 2012 17:12:02 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 14 Feb 2012 17:12:02 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 14 Feb 2012 17:11:44 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 2EABD2388AA9; Tue, 14 Feb 2012 17:10:58 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1244132 [6/14] - in /logging/log4net/site: ./ css/ images/ images/logos/ release/ release/howto/ release/manual/ Date: Tue, 14 Feb 2012 17:10:56 -0000 To: commits@logging.apache.org From: bodewig@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120214171058.2EABD2388AA9@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: logging/log4net/site/release/faq.html URL: http://svn.apache.org/viewvc/logging/log4net/site/release/faq.html?rev=1244132&view=auto ============================================================================== --- logging/log4net/site/release/faq.html (added) +++ logging/log4net/site/release/faq.html Tue Feb 14 17:10:54 2012 @@ -0,0 +1,1289 @@ + + + + + + + Apache log4net: Frequently Asked Questions + + + + + + + + + + +
+ +
+
+
+ + + + + +

Apache log4net™ Frequently Asked Questions

+

Information

+ +

What is log4net?

+

+ log4net is a tool to help the programmer output log statements to a variety of + output targets. +

+

+ 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 production code without incurring a + high performance cost. It follows that the speed of logging (or rather not + logging) is crucial. +

+

+ 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 hierarchical + loggers. Using these loggers it is possible to selectively control + which log statements are output at arbitrary granularity. +

+

+ log4net is designed with two distinct goals in mind: speed and flexibility. There + is a tight balance between these two requirements. +

+
+

Back to Top

+ + +

Is log4net a reliable logging system?

+

+ No. log4net is not reliable. It is a best-effort and fail-stop logging system. +

+

+ By fail-stop, we mean that log4net will not throw unexpected exceptions at + run-time potentially causing your application to crash. If for any reason, log4net + throws an uncaught exception (except for ArgumentException and + ArgumentNullException which may be thrown), please send an email + to the + log4net-user@logging.apache.org mailing list. Uncaught exceptions + are handled as serious bugs requiring immediate attention. +

+

+ Moreover, log4net will not revert to System.Console.Out + or System.Console.Error 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 + System.Console.Error and System.Diagnostics.Trace + indicating that logging can not be performed. +

+
+

Back to Top

+ + +

What are the prerequisites for log4net?

+

+ 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). +

+

+ Not all frameworks are created equal and some features have been excluded from + some of the builds. See the Framework Support + document for more information. +

+
+

Back to Top

+ + +

Is there example code for using log4net?

+

+ There is a directory containing examples in log4net\examples. + The examples are broken down by framework. +

+
+

Back to Top

+ + +

What are the features of log4net?

+
    +
  • + log4net is optimized for speed.
  • +
  • + log4net is based on a named logger hierarchy.
  • +
  • + log4net is fail-stop but not reliable.
  • +
  • + log4net is thread-safe.
  • +
  • + log4net is not restricted to a predefined set of facilities.
  • +
  • + Logging behavior can be set at runtime using a configuration file. + Configuration files are in XML format.
  • +
  • + log4net is designed to handle exceptions from the start.
  • +
  • + log4net can direct its output to many sinks including: a file, the console, the NT EventLog or even e-mail.
  • +
  • + log4net categorizes logging into levels: DEBUG, INFO, WARN, ERROR and FATAL.
  • +
  • + The format of the log output can be easily changed by implementing a new layout class.
  • +
  • + The target of the log output as well as the writing strategy can be altered by + writing a new appender class.
  • +
  • + log4net supports multiple output appenders per logger.
  • +
+

+ See the features overview document for more information on the features of log4net. +

+
+

Back to Top

+ + +

Is log4net thread-safe?

+

+ Yes, log4net is thread-safe. +

+
+

Back to Top

+ + +

What does log output look like?

+

+ The log output can be customized in many ways. Moreover, one can completely + override the output format by implementing one's own ILayout +

+

+ Here is an example output using PatternLayout with the conversion + pattern %timestamp [%thread] %-5level %logger{2} %ndc - %message%newline +

+
+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.
+

+ 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 nested diagnostic context (NDC). Note the + nested diagnostic context may be empty as in the first two statements. The text + after the '-' is the message of the statement. +

+
+

Back to Top

+ + +

What are Loggers?

+

+ The logger concept lies at the heart of log4net's configuration. Loggers are organized into a + hierarchy and give the programmer run-time control on which logging statements + are printed or not. +

+

+ Loggers are assigned levels through the configuration of log4net. A log statement is + routed through to the appender depending on its level and its logger. +

+
+

Back to Top

+ + +

Why should I donate my extensions to log4net back to the project?

+

+ 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. You are free to do whatever you wish with + your proprietary log4net extensions. In particular, you may choose to + never release your extensions to the wider public. For details see the + Apache License, Version 2.0. +

+

+ 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. +

+

+ 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. +

+

+ Unless the proprietary log4net extension is business critical, there is little + reason for not donating your extensions back to the project. +

+
+

Back to Top

+ + +

What should I keep in mind when contributing code?

+
    +
  1. + Stick to the existing indentation style even if you hate it. +

    + Alternating between indentation styles makes it hard to understand the source + code. Make it hard on yourself but easier on others. +

    +
  2. +
  3. + Thoroughly test your code. +

    + There is nothing more irritating than finding the bugs in debugging (i.e. logging) code. +

    +
  4. +
  5. + Keep it simple, small and fast. +

    + It's all about the application not about logging. +

    +
  6. +
  7. + Did I mention sticking with the indentation style?
  8. +
+
+

Back to Top

+ + +

How fast do bugs in log4net get fixed?

+

+ As fast as they get reported ;-) +

+
+

Back to Top

+ + +

What is the history of log4net?

+

+ log4net is a port of the popular Apache log4j™ 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 history page for more details. +

+
+

Back to Top

+ + +

Where can I find the latest distribution of log4net?

+

+ The log4net home page is a good place to start. +

+
+

Back to Top

+ +

Why are there two different strong name keys?

+

+ Starting with log4net 1.2.11 there are two + different binary distributions, + oldkey and newkey. +

+ +

+ The oldkey 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. +

+ +

+ The newkey distribution contains + assemblies signed with the strong name key + available from log4net's + svn area or inside the source distribution. + Everybody can create assemblies that have the same + strong name. +

+ +

+ 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 + newkey is used throughout. +

+ +

+ The oldkey 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 newkey + assemblies. +

+ +

+ Note that the "new" strong name no longer provides + any kind of authenticity. If you want to be sure + you have the "real" Apache log4net, download the binary + release from one of the mirrors and verify the PGP + signature. +

+ +
+

Back to Top

+ +
+ +

Configuration

+ +

How can I change log behavior at runtime?

+

+ 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. +

+

+ Configuration files are specified in XML. See log4net.Config.XmlConfigurator + for more details. +

+

+ See the various log4net.Layout and log4net.Appender + components for specific configuration options. +

+
+

Back to Top

+ + +

How do I completely disable all logging at runtime?

+

+ Setting the Threshold 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: +

+
+<log4net threshold="OFF" />
+
+

Back to Top

+ +

What are the configurable options for an appender?

+

+ log4net uses public properties to configure components such as + Appenders, Layouts, Loggers etc. +

+

+ Thus, any writable public property in on the appender corresponds to a + configurable option. For example, in RollingFileAppender the + public int MaxSizeRollBackups { set; } property corresponds to + the MaxSizeRollBackups option. +

+

+ Layouts options are also defined by their writable properties. Same goes for most + other log4net components. +

+
+

Back to Top

+ + +

Is it possible to direct log output to different appenders by level?

+

+ Yes it is. Setting the Threshold option of any appender extending + AppenderSkeleton, (most log4net appenders extend + AppenderSkeleton) will filter out all log events + with a lower level than the value of the threshold option. +

+

+ 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. +

+

+ This policy usually best encapsulates what the user actually wants to do, as + opposed to her mind-projected solution. +

+

+ If you must filter events by exact level match, then you can attach a + LevelMatchFilter to any appender to filter out logging + events by exact level match. +

+
+

Back to Top

+ + +

Is there a way to get log4net to automatically reload a configuration file if it changes?

+

+ Yes. The XmlConfigurator supports automatic + reloading through the ConfigureAndWatch APIs. See the API + documentation for more details. +

+
+

Back to Top

+ + +

Can I load an appender from another assembly?

+

+ Yes. When specifying the type in the configuration file you can give the assembly + qualified name of the type. For example: +

+
+<appender name="..." type="MyNamespace.MyAppender, MyAssembly">
+

+ The .NET runtime will try to locate the assembly called MyAssembly. + How .NET locates assemblies is beyond the scope of this FAQ. +

+

+ 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 System.Type.GetType. + See the next FAQ on how to get the version and public key for an assembly. +

+
+

Back to Top

+ + +

How do I get the Public Key for an assembly?

+

+ 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 + http://www.aisto.com/roeder/dotnet. +

+
+

Back to Top

+ + +

How do I insert newlines into the layout header?

+

+ Newlines in the config file need to be escaped using an XML numeric character reference. + The sequence that represents a CR LF is &#13; &#10;. The following example adds + a header and footer to the output each followed by a newline. +

+
+<layout type="log4net.Layout.PatternLayout">
+    <header value="[Header]&#13;&#10;" />
+    <footer value="[Footer]&#13;&#10;" />
+    <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
+</layout>
+
+

Back to Top

+ + +

How do I use a pattern to set the value of a string property?

+

+ Log4net supports a pattern syntax for setting string properties similar to the + PatternLayout used to format the output messages. + This pattern syntax can be used by specifying type="log4net.Util.PatternString" + on the string property in the config file. This tells the config parser to pass the + value to the PatternString type before converting the result + to a string. For details on the patterns supported see the + PatternString SDK Reference. +

+

+ The following example sets the file name for a FileAppender to include the + current process id by specifying the %processid pattern in the + File property. +

+
+<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
+    <file type="log4net.Util.PatternString" value="log-file-[%processid].txt" />
+    <layout type="log4net.Layout.PatternLayout" value="%date [%thread] %-5level %logger - %message%newline" />
+</appender>
+
+

Back to Top

+ + +
+ +

Implementing Logging

+ +

Are there any suggested ways for naming loggers?

+

+ Yes, there are. +

+

+ You can name logging loggers by locality. 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: +

+
    +
  • + It is very simple to implement.
  • +
  • + It is very simple to explain to new developers.
  • +
  • + It automatically mirrors your application's own modular design.
  • +
  • + It can be further refined at will.
  • +
  • + Printing the logger automatically gives information on the locality of the + log statement.
  • +
+

+ However, this is not the only way for naming loggers. A common alternative + is to name loggers by functional areas. For example, the + "database" logger, "remoting" logger, "security" logger, or the "XML" + logger. +

+

+ You may choose to name loggers by functionality and subcategorize by + locality, as in "DATABASE.MyApp.MyClass" or + "DATABASE.MyApp.MyModule.MyOtherClass". +

+

+ You are totally free in choosing the names of your loggers. The + log4net package merely allows you to manage your names in a hierarchy. However, + it is your responsibility to define this hierarchy. +

+

+ Note: by naming loggers by locality one tends to name things by + functionality, since in most cases the locality relates closely to + functionality. +

+
+

Back to Top

+ + +

How do I get the fully-qualified name of a class in a static block?

+

+ You can easily retrieve the fully-qualified name of a class in a static block + for class X, with the statement typeof(X).Name. + Note that X is the class name and span an instance. + However because the LogManager.GetLogger method is overloaded + to take an instance of Type as well as string + usually only the type of the class is required. +

+

+ Here is the suggested usage template: +

+
+public class Foo
+{
+    private static readonly ILog log = LogManager.GetLogger(typeof(Foo));
+    ... other code
+}
+

+ An equivalent and more portable solution, though slightly longer, is to use the declaring type + of the static constructor. +

+
+public class Foo
+{
+    private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+    ... other code
+}
+

+ Note: the .NET Compact Framework 1.0 does not support System.Reflection.MethodBase.GetCurrentMethod(). +

+ +

+ Note: the two forms are only equivalent + if Foo is not a + generic class. For a generic class Foo<T> the variant + using typeof generates + a different logger for each different type + parameter T while the + variant using reflection generates the same + logger for all Ts. +

+
+

Back to Top

+ + +

What is the fastest way of (not) logging?

+

+ For some logger log, writing, +

+
+log.Debug("Entry number: " + i + " is " + entry[i]);
+

+ incurs the cost of constructing the message parameter, that is converting both + integer i and entry[i] to + a string, and concatenating intermediate strings. This, regardless of whether + the message will be logged or not. +

+

+ If you are worried about speed, then write +

+
+if(log.IsDebugEnabled) 
+{
+    log.Debug("Entry number: " + i + " is " + entry[i]);
+}
+

+ This way you will not incur the cost of parameter construction if debugging is + disabled for logger log. 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 IsDebugEnabled and once in Debug. + This is an insignificant overhead since evaluating a logger takes less than + 1% of the time it takes to actually log a statement. +

+
+

Back to Top

+ + +

What is REALLY the FASTEST way of (not) logging?

+

+ 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: +

+
+if(log.IsDebugEnabled) 
+{
+    log.Debug("Entry number: " + i + " is " + entry[i]);
+}
+

+ It is possible to further eliminate the calls to IsDebugEnabled + 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: +

+
+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]);
+        }
+    }
+}
+

+ So why exactly is this faster? Well to start with the IsDebugEnabled + is not called for each log statement, it is called once per logger. Furthermore as the + isDebugEnabled variable is private static readonly + the JIT compiler can at run-time optimize out the if 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. +

+

+ 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 XmlConfigurator.ConfigureAndWatch 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. +

+
+

Back to Top

+ + +

Can the outputs of multiple client request go to different log files?

+

+ 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. +

+

+ It is simpler to use a context property or stack (ThreadContext). + Typically, one would ThreadContext.Properties["ID"] = "XXX" + 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. +

+

+ See the ThreadContext and the PatternLayout classes for more + information. +

+
+

Back to Top

+ + +

Logger instances seem to be create only. Why isn't there a method to remove logger instances?

+

+ It is quite nontrivial to define the semantics of a "removed" logger which is + still referenced by the user. +

+
+

Back to Top

+ + +

How do I get multiple process to log to the same file?

+

+ 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 ;-). +

+ +

+ FileAppender offers pluggable locking models for + this usecase but all existing implementations have + issues and drawbacks. +

+ +

+ By default the FileAppender 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. +

+ +

+ MinimalLock 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. +

+

+ InterProcessLock + 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. +

+

+ If you use RollingFileAppender things + become even worse as several process may try to + start rolling the log file concurrently. RollingFileAppender + completely ignores the locking model when + rolling files, rolling files is simply not + compatible with this scenario. +

+

+ A better alternative is to have your processes + log to RemotingAppenders. Using + the RemoteLoggingServerPlugin + (or IRemoteLoggingSink) a + process can receive all the events and log + them to a single log file. One of the + examples shows how to use the RemoteLoggingServerPlugin. +

+
+

Back to Top

+ + +

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?

+

+ The timestamp is created when the logging event is created. That is so say, + when the Debug, Info, + Warn, Error + or Fatal 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 RemotingAppender, + 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. +

+
+

Back to Top

+ + +

When should I log my first message?

+

+ The simple answer is as soon as possible. The long answer is more complex. +

+

+ If you are configuring log4net programmatically, i.e. by calling the + XmlConfigurator.Configure method then you should do so + before you begin logging and it is reasonable to do this very soon after application + start. +

+

+ 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 LogManager.GetLogger is made. It is necessary + that the first call to LogManager.GetLogger 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. +

+
+

Back to Top

+ + +
+ +

Customization

+ +

Can the log output format be customized?

+

+ Yes. You can implement the log4net.Layout.ILayout + interface to create you own customized log format, or you can extend the + LayoutSkeleton class which provides a default + implementation of the ILayout interface. + Appenders can be parameterized to use the layout of your choice. +

+
+

Back to Top

+ + +

Can I write a custom appender?

+

+ Yes. You can implement the log4net.Appender.IAppender + interface to create you own customized appender. We recommend that you extend the + log4net.Appender.AppenderSkeleton 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 log4net.Appender.TraceAppender as an + example of the minimum amount of code required to get an appender working. +

+

+ 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: +

+
+<appender name="..." type="MyNamespace.MyAppender, MyAssembly">
+

+ The .NET runtime will try to locate the assembly called MyAssembly. + How .NET locates assemblies is beyond the scope of this FAQ. +

+
+

Back to Top

+ +
+ +

Troubleshooting

+ +

How do I enable log4net internal debugging?

+

+ There are 2 different ways to enable internal debugging in log4net. + These are listed below. The preferred method is to specify + the log4net.Internal.Debug option in the application's + config file. +

+
    +
  • +

    + 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 log4net.Internal.Debug + application setting must be set to the value true. + For example: +

    +
    +<?xml version="1.0" encoding="utf-8" ?>
    +<configuration>
    +    <appSettings>
    +        <add key="log4net.Internal.Debug" value="true"/>
    +    </appSettings>
    +</configuration>
    +

    + This setting is read immediately on startup an will cause all internal + debugging messages to be emitted. +

    +
  • +
  • +

    + To enable log4net's internal debug programmatically you need + to set the log4net.Util.LogLog.InternalDebugging + property to true. Obviously the sooner this + is set the more debug will be produced. +

    +
  • +
+

+ Internal debugging messages are written to the console and to the + System.Diagnostics.Trace + 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 System.Console.Out. 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 + http://www.sysinternals.com + may be used to capture these messages. +

+

+ As log4net internal debug messages are written to the System.Diagnostics.Trace + 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: +

+
+<configuration>
+    ...
+    
+    <system.diagnostics>
+        <trace autoflush="true">
+            <listeners>
+                <add 
+                    name="textWriterTraceListener" 
+                    type="System.Diagnostics.TextWriterTraceListener" 
+                    initializeData="C:\tmp\log4net.txt" />
+            </listeners>
+        </trace>
+    </system.diagnostics>
+
+    ...
+</configuration>
+

+ Make sure that the process running your application has permission + to write to this file. +

+
+

Back to Top

+ + +

Why doesn't the EventLogAppender work?

+

+ 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. +

+

+ 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. +

+

+ There are a couple of solutions: +

+
    +
  1. +

    + 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. +

    +
  2. +
  3. +

    + 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 + System.Diagnostics.EventLogInstaller in the Microsoft .NET + Framework SDK for an example of how to create a simple event log installer. +

    +
  4. +
+

+ There is a Microsoft Knowledge Base article that covers this issue and how to resolve + it. + PRB: "Requested Registry Access Is Not Allowed" Error Message When ASP.NET + Application Tries to Write New EventSource in the EventLog. +

+
+

Back to Top

+ + +

Why can't I log to a FileAppender from a web application?

+

+ 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. +

+
+

Back to Top

+ + +

Why doesn't the logging in my service work?

+

+ 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. +

+

+ A windows service is launched by windows. The current directory in + a service is set to the windows system directory (e.g. + C:\Windows\System32). 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 + AppDomain.BaseDirectory. + Note that the log4net internals never use the current directory. +

+
+

Back to Top

+ + +

I am having trouble using the AdoNetAppender to connect to my database?

+

+ For details on the different ways in which ADO.NET can connect to a database see: + Connecting to a Data Source Using ADO.NET. +

+

+ 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: + ODBC .NET Data Provider. +

+
+

Back to Top

+ + +

How do I report bugs?

+

+ First make sure it really is a bug and not a + usage error. When in doubt, ask on the log4net-user mailing + list first. +

+

+ If you have identified a bug, please report it + via our Issue + Tracker. You may want to check it hasn't + been reported before by searching the existing + issues. +

+
+

Back to Top

+ +

log4net doesn't log when built in RELEASE mode

+

+ 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. +

+ +

+ As stated in the + manual the attribute will only be read for + the first assembly that tries to use log4net. + So it is important that you obtain your + ILog instance as early as possible. +

+ +

+ For a command line application "as early as + possible" probably is the class holding the + Main method, for a Web-Application + it would be your Global.asax class + and for a Windows Service it would be the class + deriving from ServiceBase. +

+
+

Back to Top

+ +
+ +

Miscellaneous

+ +

How do I make log4net appear in the Visual Studio Add References dialog?

+

+ There is a good discussion of this topic on Robert McLaws blog: + Building a Better Server Control Experience, Part 2. +

+
+

Back to Top

+ +
+ +
+ + + +
+
+
+
+
+