Log4net學習心得
我們每次開發系統時候,那邊系統會有這樣那樣的問題,如果出了問題,該怎樣發現問題與解決問題呢?寫Log就是一個很好的注意.怎樣使用好的Log工具對開發與維護系統至關重要.目前起碼在VS2003中沒有看到Log工具的影子.但是在開源社區就有幾個不錯的東東.Log4net就是其中的一個.
Log4net是Log4J的.NET版本.下面介紹怎樣用這個Tool方便的寫Log.
1.1 第一個範例程式之Cs,調用Log4net.
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文件
<!-- 輸出到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 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
<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里面寫入代碼來配置全局變量.
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用法。
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的用户权限即可。