Log4net學習心得

我們每次開發系統時候,那邊系統會有這樣那樣的問題,如果出了問題,該怎樣發現問題與解決問題呢?寫Log就是一個很好的注意.怎樣使用好的Log工具對開發與維護系統至關重要.目前起碼在VS2003中沒有看到Log工具的影子.但是在開源社區就有幾個不錯的東東.Log4net就是其中的一個.

Log4net是Log4J的.NET版本.下面介紹怎樣用這個Tool方便的寫Log.

1.1 第一個範例程式之Cs,調用Log4net.

using System;
using log4net;//註1
using log4net.Config;


namespace Log4Net
{
    
public class Bar
    
{
        
private static readonly ILog log = LogManager.GetLogger(typeof(Bar));

        
public void DoIt()
        
{
            log.Fatal(
"Fatal");
        }

    }


    
class Program
    
{
        
//註2

        
private static readonly ILog log = LogManager.GetLogger(typeof(Program));

        
static void Main(string[] args)
        
{
    
//註3
            XmlConfigurator.Configure(new System.IO.FileInfo("d:/config.xml")); 

            log.Info(
"Entering application.");//註4

            Bar bar 
= new Bar();
            bar.DoIt();
            log.Info(
"Exiting application.");
            Console.ReadLine();
        }

    }

}

執行結果 - Console
2006-07-01 20:59:32,437 INFO  Log4Net.Program - Entering application.
2006-07-01 20:59:32,468 FATAL Log4Net.Bar - Fatal
2006-07-01 20:59:32,468 INFO  Log4Net.Program - Exiting application.

執行結果 - logfile.log
INFO  Log4Net.Program
    (D:\Project\CS\Log4Net\Log4Net\Program.cs:26) - Entering application.
FATAL Log4Net.Bar
    (D:\Project\CS\Log4Net\Log4Net\Program.cs:14) - Fatal
INFO  Log4Net.Program
    (D:\Project\CS\Log4Net\Log4Net\Program.cs:29) - Exiting application.

1.2 第一個範例程式之設定檔 .Config文件

<log4net>
  
<!-- 輸出到Console -->
  
<appender name="A1" type="log4net.Appender.ConsoleAppender">
    
<layout type="log4net.Layout.PatternLayout">
      
<conversionPattern value="%date %-5level %logger - %message%newline" />
    
</layout>
  
</appender>
  
  
<!-- 輸出到檔案 -->
  
<appender name="A2" type="log4net.Appender.RollingFileAppender">
    
<file value="d:/logfile.log" /> <!-- 輸出檔名 -->
    
<appendToFile value="true" />
    
<maximumFileSize value="2048KB" /> <!-- 每個檔案最大size -->
    
<maxSizeRollBackups value="5" />
    
<rollingStyle value="Date" />
    
<datePattern value="yyyyMMdd-HHmm" />
    
<layout type="log4net.Layout.PatternLayout">
      
<conversionPattern value="%level %logger (%file:%line) - %message%newline" />
    
</layout>
  
</appender>

  
<root>
    
<!-- 輸出訊息等級 -->
    
<level value="INFO" />
    
<appender-ref ref="A1" />
    
<appender-ref ref="A2" />
  
</root>
</log4net>

2.1 第二個範例程式

using System;
using First;
using log4net;
using log4net.Config;

namespace First
{
    
public class GrandFather
    
{
        
public GrandFather()
        
{
            
//System.Reflection.MethodBase.GetCurrentMethod().DeclaringType
            
//可取得class type
            ILog log =  LogManager.GetLogger(
                System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            log.Error(
"");
        }

    }

}


namespace Second
{
    
public class Father : GrandFather
    
{
        
public Father()
        
{
            ILog log 
= LogManager.GetLogger(
                System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            log.Fatal(
"");
        }

    }


    
public class Child : Father
    
{
        
public void Play()
        
{
            ILog log 
= LogManager.GetLogger(
                System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            log.Warn(
"");
        }

    }


    
class Program
    
{
        
static void Main(string[] args)
        
{
            XmlConfigurator.Configure(
new System.IO.FileInfo("d:/config.xml"));            

            Child child 
= new Child();
            child.Play();
            
            Console.ReadLine();
        }

    }

}


2.2 第二個範例程式的設定檔 config.xml
<log4net>
  
<appender name="A1" type="log4net.Appender.ConsoleAppender">
    
<layout type="log4net.Layout.PatternLayout">
      
<!-- Print the date in ISO 8601 format -->
      
<conversionPattern value="%date %-5level %logger - %message%newline" />
    
</layout>
  
</appender>
  
  
<appender name="A2" type="log4net.Appender.RollingFileAppender">
    
<file value="d:/logfile.log" />
    
<appendToFile value="true" />
    
<maximumFileSize value="2048KB" />
    
<maxSizeRollBackups value="5" />
    
<rollingStyle value="Date" />
    
<datePattern value="yyyyMMdd-HHmm" />
    
<layout type="log4net.Layout.PatternLayout">
      
<conversionPattern value="%level %logger (%file:%line) - %message%newline" />
    
</layout>
  
</appender>

  
<!-- 所有的訊息輸出都要輸出到A1 -->
  
<root>
    
<level value="INFO" />
    
<appender-ref ref="A1" />
  
</root>
  
  
<!-- 僅namespace Second中的Child class輸出訊息至A2 -->
  
<logger name="Second.Child">
    
<level value="DEBUG" />
    
<appender-ref ref="A2" />
  
</logger>

</log4net>


註1: 因為LogManager在namespace log4net,XmlConfigurator在namespace log4net.Config,所以將這兩個namespace引入。
註2: 特別注意LogManager.GetLogger的參數,一定要是所在的class,這樣輸出的訊息才能正確指出是由那一個class輸出的。
註3: 載入設定檔。
註4: 輸出訊息,訊息有五種等級由低而高為Debug、Info、Warn、Error、Fatal,訊息要輸出那一等級的訊息,由<root>裡的<level>設定,上面的設定檔設為INFO,則所有大於等於INFO的訊息都會輸出。
        除了上述四項外,請各位網友注意一下Console輸出和檔案輸出的格式不同,這可由<appender>中設定。
看完第一個範例程式基本上就可以運用在大多數的專案中了,底下第二個範例則要解說,當輸出訊息很多,不適合全部輸出到同一個檔案時,如何將訊息依class輸出到不同檔案。

補充:
日誌級別: 低 ALL<< Debug<<Info<<Warn<<Error<<Fatal<<OFF 高.

log4net.Layout.PatternLayout中的轉換模式(ConversionPattern)

%m (message):輸入的日志消息,如ILog.Debug(...)輸出的消息.
%n (new line):換行.
%d (datetime):輸出當前語句運行的時刻.
%r (run time):輸出程式從運行到當前語句消耗的毫秒數.
%t (thread id):當前語句所在的線程ID.
%p (priorty):日誌的當前優先級別.即DEBUG,INFO,WARN...
%c (class):當前日誌對象的名稱,LogManager.GetLogger(type);type所在的類.
下面是一個模式串的例子:
%-10c -%m%n > org.foo.Bar -INFO
%r [%t]%-5p %c - %m%n > 176 [main] INFO org.foo.Bar - Located nearest gas station
注意:在class裡面可以用以下模式來顯示:
%L 輸出語句所在的行號.
%F 輸出語句所在的文件名.
%-數字 該項的最小長度,如果不夠用空格填充.

(2008/1/4 補充)
log4net 也可以不用CONFIG文件配置,通過程序代碼也可以輕松搞定.
如果在web上面則要在Application_Start里面寫入代碼來配置全局變量.

 1 void Application_Start(object sender, EventArgs e) 
 2    {
 3        // Code that runs on application startup
 4        log4net.Config.BasicConfigurator.Configure(new log4net.Appender.FileAppender(
 5                                                    new log4net.Layout.PatternLayout("[%d{yyyy/MM/dd HH:mm:ss}] %level %logger - %message%newline"),
 6                                                    "Log/WebTemplate.log")
 7                                                    );
 8        
 9        log4net.Appender.RollingFileAppender rf = new log4net.Appender.RollingFileAppender();
10        rf.File = "Log/WebTemplate1.log";
11        rf.AppendToFile = true;
12        rf.MaxSizeRollBackups = 10;
13        rf.MaximumFileSize = "2048KB";
14        rf.RollingStyle = log4net.Appender.RollingFileAppender.RollingMode.Size;
15        rf.StaticLogFileName = true;
16        rf.Layout = new log4net.Layout.PatternLayout("[%d{yyyy/MM/dd HH:mm:ss}] %level %logger - %message%newline");
            
17        rf.ActivateOptions();
18        
19        log4net.Config.BasicConfigurator.Configure(rf);
20
21        //log4net.Config.BasicConfigurator.Configure(new log4net.Appender.FileAppender(
22        //                                            new log4net.Layout.XmlLayout(), "Log/WebTemplate.xml")
23        //                                            );
24        
25        //log4net.Config.BasicConfigurator.Configure(new log4net.Appender.ConsoleAppender(
26        //                                            new log4net.Layout.PatternLayout("%d [%t] %-5p %c - %message%newline"))); 
27
28
29    }

這與CONFIG是一個效果.只是一個系統只能一個設置,不能設置多個配置.

2008年6月补充相关Filter用法。
1log4net.Appender.FileAppender fa = new log4net.Appender.FileAppender();
2fa.Layout = new log4net.Layout.PatternLayout("[%d{yyyy/MM/dd HH:mm:ss}] %level %logger - %message%newline");
3fa.File = "Log/AUTH.log";
4log4net.Filter.LevelRangeFilter filter = new log4net.Filter.LevelRangeFilter();
5filter.LevelMax = log4net.Core.Level.Fatal;
6filter.LevelMin = log4net.Core.Level.Info;
7fa.AddFilter(filter);
8fa.ActivateOptions();

2008年7月补充

最近用VS2005开发系统是发现LOG总是不会产生,觉得非常奇怪,后来试来试去才知道是目录权限的问题,如上Log/Auth.log,那个Log目录一定要给ASPNET一定的权限才可以,原则上加上aspnet的用户权限即可。

posted @ 2007-04-24 17:54  芙蓉客  阅读(2835)  评论(0编辑  收藏  举报