一 Log4net簡介
Log4net是基於.net開發的一款非常著名的記錄日誌開源組件。他最早是2001年7月由NeoWorks Limited啓動的項目,基本的框架源於另外的一個非常著名的姐妹組件-log4j。Log4net記錄日誌的功能非常強大。
優點:它可以提供應用程序運行時的精確環境,可供開發人員儘快找到應用程序中的Bug;一旦在程序中加入了Log 輸出代碼,程序運行過程中就能生成並輸出日誌信息而無需人工幹預。另外,日誌信息可以輸出到不同的地方(控制檯,文件等)以備以後研究之用。
Log4net可從http://logging.apache.org/log4net/downloads.html網站下載最新版本。
二 Log4net核心組成
Log4net主要由五個部分組成,分別爲Logger,Appenders, Filters, Layouts 和Object Renders。
一)Logger(日誌)
1. 記錄日誌的分類:
Log4net能夠以多種方式輸出日誌。支持的日誌輸出常用的主要媒介有數據庫(包括MS SQL Server, Access, Oracle9i,Oracle8i,DB2,SQLite,控制檯,文件,事件日誌(可以用事件查看器查看)和郵件等多種方式。
2.日誌的級別
Log4net支持多種級別的日誌。優先級從高到低依次排列如下:
FATAL > ERROR > WARN > INFO > DEBUG
此外還有ALL(允許所有的日誌請求)和OFF(拒絕所有的日誌請求)這兩種特殊的級別。如果沒有定義LEVEL的值,則缺省爲DEBUG。
二)Appenders
Appenders決定日誌輸出的方式。
Appenders必須實現log4net.Appenders.IAppender接口。
Log4net目前支持的輸出方式包括:
1 AdoNetAppender將日誌記錄到數據庫中。可以採用SQL和存儲過程兩種方式。
2 AnsiColorTerminalAppender在ANSI 窗口終端寫下高亮度的日誌事件。
3 AspNetTraceAppender能用asp.net中Trace的方式查看記錄的日誌。
4 BufferingForwardingAppender在輸出到子Appenders之前先緩存日誌事件。
5 ConsoleAppender將日誌輸出到控制檯。
6 EventLogAppender將日誌寫到Windows Event Log
7 FileAppender將日誌寫到文件中。
8 LocalSyslogAppender將日誌寫到local syslog service (僅用於UNIX環境下).
9 MemoryAppender將日誌存到內存緩衝區。
10 NetSendAppender 將日誌輸出到Windows Messenger service.這些日誌信息將在
用戶終端的對話框中顯示。
11 RemoteSyslogAppender 通過UDP網絡協議將日誌寫到Remote syslog service。
12 RemotingAppender通過.NET Remoting將日誌寫到遠程接收端。
13 RollingFileAppender將日誌以回滾文件的形式寫到文件中。
14 SmtpAppender將日誌寫到郵件中。
15 TraceAppender將日誌寫到.NET trace 系統。
16 UdpAppender將日誌connectionless UDP datagrams的形式送到遠程宿主或以UdpClient的形式廣播。
三) Filters
Appender對象將日誌以缺省的方式傳到輸出流,然後Filter可以按照不同的標準控制日誌的輸出。Filter可以再配置文件中配置。最簡單的形式是在appender中寫明一個Threshold.這樣只有級別大於或等於此Threshold的日誌才被記錄。
Filters必須實現log4net.Filters.IFilter接口。
四)Layouts
Layouts控制日誌顯示的格式樣式。日誌的顯示格式如下:
"%timestamp [%thread] %-5level %logger - %message%newline"
Timestamp: 表示程序已經開始執行的時間。 單位[毫秒]。
Thread:執行當前代碼的線程。
Level:日誌的級別。
Logger:日誌相關請求的名稱。
Message: 日誌消息。
layout節點的配置說明
%m(message):輸出的日誌消息,如ILog.Debug(…)輸出的一條消息
%n(new line):換行
%d(datetime):輸出當前語句運行的時刻
%r(run time):輸出程序從運行到執行到當前語句時消耗的毫秒數
%t(thread id):當前語句所在的線程ID
%p(priority): 日誌的當前優先級別,即DEBUG、INFO、WARN…等
%c(class):當前日誌對象的名稱,例如:
模式字符串爲:%-10c -%m%n
代碼爲:
ILog log=LogManager.GetLogger(“Exam.Log”);
log.Debug(“Hello”);
則輸出爲下面的形式: Exam.Log
- Hello
%L:輸出語句所在的行號
%F:輸出語句所在的文件名
%-數字:表示該項的最小長度,如果不夠,則用空格填充
例如,轉換模式爲%r [%t]%-5p %c - %m%n 的 PatternLayout 將生成類似於以下內容的輸出:
176 [main] INFO
org.foo.Bar - Located nearest gas station.
Layouts還可以控制日誌的輸出樣式,比如以普通形式或以xml等形式輸出。
五)Object Renderers
這是很重要的一項,log4net將按照用戶定義的標準輸出日誌消息。
Object Renders必須實現log4net.ObjectRenderer.IObjectRenerer接口。
三 在項目中使用log4net
1:站點下的配置(參考附件內容)
*********************************
Log4Net五步走
1:引入log4net.dll組件
2:建立一個配置文件
兩種方法,一種是在Web.Config或App.Config裏
加入以下配置節
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
加入log4net配置內容的定義,下面是一個範例:
<log4net>
<appender name="FileAppender" type="log4net.Appender.RollingFileAppender" >
<param name="File" value="c:/test/log4/log4netTestError.log" />
<param name="AppendToFile" value="true" />
<param name="DatePattern" value="yyyyMMdd" />
<param name="RollingStyle" value="Date" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date{yyyy-MM-dd HH:mm:ss} [%thread] %-5p %m%n" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="ERROR" />
<levelMax value="FATAL" />
</filter>
</appender>
<appender name="DebugFileAppender" type="log4net.Appender.RollingFileAppender" >
<param name="File" value="c:/test/log4/log4netTestDebug.log" />
<param name="AppendToFile" value="true" />
<param name="MaximumFileSize" value="2KB" />
<param name="RollingStyle" value="Size" />
<param name="StaticLogFileName" value="false" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date{yyyy-MM-dd HH:mm:ss} [%thread] %type %method %-5p %m%n" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<levelMax value="WARN" />
</filter>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="FileAppender" />
<appender-ref ref="DebugFileAppender" />
</root>
</log4net>
3:新建Global.asax文件
<%@ Application Language="C#" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
// アプリケーションのスタートアップで実行するコードです
log4net.Config.XmlConfigurator.Configure();
}
void Application_End(object sender, EventArgs e)
{
// アプリケーションのシャットダウンで実行するコードです
}
void Application_Error(object sender, EventArgs e)
{
// ハンドルされていないエラーが発生したときに実行するコードです
}
void Session_Start(object sender, EventArgs e)
{
// 新規セッションを開始したときに実行するコードです
}
void Session_End(object sender, EventArgs e)
{
// セッションが終了したときに実行するコードです
}
</script>
4:新建Log4netTest.aspx文件,添加按鈕事件:
<asp:Button ID="btnLog" runat="server" Text="日誌輸出" OnClick="btnLog_Click" />
5:在Log4netTest.aspx.cs文件中
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "web.config", Watch = true)]
public partial class Log4netTest : System.Web.UI.Page
{
log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnLog_Click(object sender, EventArgs e)
{
logger.Error("gggggggggggggggggggggggggggggggggggggggg");
logger.Debug("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
}
}
運行程序點擊按鈕,在web.config定義的目錄c:/test/log4下就會生成文件log4netTestError.log 及log4netTestDebug.log,查看就會有相應的信息輸出。
*****************************************************************
2:バッチ中的配置(參考附件內容)
********************************************************
1:前言 (3):將CustomLayout類繼承自log4net.Layout.PatternLayout並在構造函數中調用AddConverter()方法。該方法將佔用較多的系統內存,但它代碼簡單易於理解。具體如下: **************************************************************************
針對在Log4Net中添加自定義日誌信息。在寫日誌的時候並不是只寫消息(Message),有些情況需要記錄自定義的日誌信息等。下面將說明在Log4Net中增加自定義字段UserName(用戶名),Category(類別)這兩個字段。
2:建立數據庫
CREATE TABLE [dbo].[Log] (
[Id] [int] IDENTITY (1, 1) NOT NULL ,
[Date] [datetime] NOT NULL ,
[Thread] [varchar] (255) NOT NULL ,
[Level] [varchar] (50) NOT NULL ,
[Logger] [varchar] (255) NOT NULL ,
[Message] [varchar] (4000) NOT NULL ,
[Exception] [varchar] (2000) NULL ,
[User] [varchar] (50) NULL ,
[Category] [varchar] (50) NULL
)
其中Date,Thread,Level,Logger,Message,Exception是log4net內置的信息。User與Category是自定義的字段。
3:編寫配置文件
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<log4net>
<logger name="AA">
<level value="All" />
<appender-ref ref="ADONetAppender" />
</logger>
<!--<root>
<level value="All" />
<appender-ref ref="ADONetAppender" />
</root>-->
<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
<!--BufferSize爲緩衝區大小-->
<param name="BufferSize" value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<connectionString value="database=aa;server=(local);User ID=sa;Password=;" />
<commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception],[User],[Category]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception,@User,@Category)" />
<parameter>
<parameterName value="@log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="@thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="@log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="@logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%logger" />
</layout>
</parameter>
<parameter>
<parameterName value="@message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message" />
</layout>
</parameter>
<parameter>
<parameterName value="@exception" />
<dbType value="String" />
<size value="2000" />
<layout type="log4net.Layout.ExceptionLayout" />
</parameter>
<parameter>
<parameterName value="@User" />
<dbType value="String" />
<size value="50" />
<layout type="Log4NetToDatabase.CustomLayout">
<conversionPattern value="%UserName" />
</layout>
</parameter>
<parameter>
<parameterName value="@Category" />
<dbType value="String" />
<size value="50" />
<layout type="Log4NetToDatabase.CustomLayout">
<conversionPattern value="%Category" />
</layout>
</parameter>
</appender>
</log4net>
</configuration>
配置文件說明:該配置文件在應用程序項目中的App.config配置文件中編寫。配置文件中的Log4NetToDatabase.CustomLayout爲自定義類的名稱,具體實現請關注編寫代碼。配置文件中如果將<root>節點的注釋打開則會產生兩條同樣的信息,因爲在<root>節點中有一個appender-ref子節點,它也引用了ADONetAppender附着器。解決該問題只要將<Root>節點注釋,或將<root>節點中的<appender-ref>子節點注釋就解決了。
4:編寫後臺代碼
(1):編寫自定義PatternLayoutConverter類
internal sealed class UserNamePatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) {
LogMessage logMessage = loggingEvent.MessageObject as LogMessage;
if (logMessage != null)
// 將UserName作爲日誌信息輸出
writer.Write(logMessage.UserName);
}
}
internal sealed class CategoryPatternConverter : PatternLayoutConverter
{
override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
{
LogMessage logMessage = loggingEvent.MessageObject as LogMessage;
if (logMessage != null)
writer.Write(logMessage.Category);
}
}
(2):編寫自定義日誌輸出類
public class LogMessage
{
private string m_UserName;
private string m_Category;
public LogMessage(){}
public LogMessage(string userName, string category)
{
m_UserName = userName;
m_Category = category;
}
public string UserName
{
get{ return m_UserName; }
Set{m_UserName = value; }
}
public string Category
{
Get{return m_Category; }
Set{ m_Category = value; }
}
}
public class CustomLayout : log4net.Layout.PatternLayout
{
public CustomLayout ()
{
this.AddConverter("UserName", typeof(UserNamePatternConverter));
this.AddConverter("Category", typeof(CategoryPatternConverter));
}
}
(4):加在配置文件並記錄日誌
在AssemblyInfo.cs文件中添加[assembly: XmlConfigurator()]。它的作用同於log4net.Config.XmlConfigurator.Configure();用來讀取配置文件信息。
在form1中添加下列代碼:
private static int count = 0;
log4net.ILog log;
public Form1()
{// 如果配置文件中存在名稱爲AA的logger,則加載
log = LogManager.Exists("AA");
}
private void button1_Click(object sender, EventArgs e)
{
++count;
LogMessage message = new LogMessage();
message.UserName = "xds"+count.ToString();
message.Category = count.ToString();
// 輸出日誌信息
log.Error(message);
}