正确使用 log4net (日志记录器命名)

配置和使用 log4net 有两种方法。第一个是我什么时候可以配置我自己的 appender 和相关的 logger:

<!-- language: xml -->


<appender name="myLogAppender" type="log4net.Appender.RollingFileAppender" >
<file value="Logs\myLog.log" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level - %message%n" />
</layout>
</appender>


<logger name="myLog">
<level value="All"></level>
<appender-ref ref="myLogAppender" />
</logger>

然后,当我想在日志中写一些东西时,我可以这样做:

ILog log = LogManager.GetLogger("myLog");
log.Info("message");

另一种使用它的方法是将 root 配置为我所希望的那样详细:

<!-- language: xml -->


<root>
<level value="Error" />
<appender-ref ref="myLogAppender" />
</root>

在这种情况下,我可以像这样记录信息:

ILog log = LogManager.GetLogger(typeof(Bar));
log.Info("message");

第二种方法的好处是可以动态启用或禁用某些消息。但问题是,我正在 EPiServer CMS 中开发,它有自己的日志系统,使用 log4net,如果我在根级别启用信息日志,那么将写入大量系统日志。

如何使用 log4net?系统的每个部分都在自己的日志记录器中写入,或者所有内容都在默认的日志记录器中写入,然后由配置决定下一步做什么?

142308 次浏览

Regarding how you log messages within code, I would opt for the second approach:

ILog log = LogManager.GetLogger(typeof(Bar));
log.Info("message");

Where messages sent to the log above will be 'named' using the fully-qualifed type Bar, e.g.

MyNamespace.Foo.Bar [INFO] message

The advantage of this approach is that it is the de-facto standard for organising logging, it also allows you to filter your log messages by namespace. For example, you can specify that you want to log INFO level message, but raise the logging level for Bar specifically to DEBUG:

<log4net>
<!-- appenders go here -->
<root>
<level value="INFO" />
<appender-ref ref="myLogAppender" />
</root>


<logger name="MyNamespace.Foo.Bar">
<level value="DEBUG" />
</logger>
</log4net>

The ability to filter your logging via name is a powerful feature of log4net, if you simply log all your messages to "myLog", you loose much of this power!

Regarding the EPiServer CMS, you should be able to use the above approach to specify a different logging level for the CMS and your own code.

For further reading, here is a codeproject article I wrote on logging:

My Answer might be coming late, but I think it can help newbie. You shall not see logs executed unless the changes are made as below.

2 Files have to be changes when you implement Log4net.


  1. Add Reference of log4net.dll in the project.
  2. app.config
  3. Class file where you will implement Logs.

Inside [app.config] :

First, under 'configSections', you need to add below piece of code;

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />

Then, under 'configuration' block, you need to write below piece of code.(This piece of code is customised as per my need , but it works like charm.)

<log4net debug="true">
<logger name="log">
<level value="All"></level>
<appender-ref ref="RollingLogFileAppender" />
</logger>


<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log.txt" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<maxSizeRollBackups value="1" />
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />


<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %C.%M [%line] %-5level - %message %newline %exception %newline" />
</layout>
</appender>
</log4net>

Inside Calling Class :

Inside the class where you are going to use this log4net, you need to declare below piece of code.

 ILog log = LogManager.GetLogger("log");

Now, you are ready call log wherever you want in that same class. Below is one of the method you can call while doing operations.

log.Error("message");

Instead of naming my invoking class, I started using the following:

private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

In this way, I can use the same line of code in every class that uses log4net without having to remember to change code when I copy and paste. Alternatively, i could create a logging class, and have every other class inherit from my logging class.

Disadvantage of second approach is big repository with created loggers. This loggers do the same if root is defined and class loggers are not defined. Standard scenario on production system is using few loggers dedicated to group of class. Sorry for my English.