Log4net的配置學習與總結
1 Log4net的結構
Log4net 有四種主要的元件,分別是logger(記錄器)、Repository(庫)、Appender(附著器)以及Layout(佈局)。
1.1 Logger
Logger是應用程式需要互動的主要元件,它用來產生日誌訊息。產生的日誌訊息並不直接顯示,還要預先經過Layout的格式化出來後才會輸出。
Logger提供了多種方式來記錄一個日誌訊息,你可以在你的應用程式裡建立多個Logger,每個例項化的Logger物件都被log4net框架作為一個命名實體(named entity)來維護。這就意味著為了重用Logger物件,你不必將它在不同的類或物件之間傳遞,只需要用它的名字作為引數呼叫就可以了。Log4net框架使用繼承體系,繼承體系類似於.NET中的名字空間,也就是說,如果哦有兩個logger,分別被定義為a.b.c 和a.b,那麼我就說a.b是a.b.c的祖先。每一個Logger都集成了祖先的屬性。
Logger框架定義了一個ILog介面,所有的logger類都必須實現這個介面。如果哦你想實現一個自定義的logger,你必須首先實現這個介面。
ILog介面的定義如下:
public interface Ilog
{
void Debug(object message);
void Info(object message);
void Warn(object message);
void Error(object message);
void Fatal(object message);
//以上每個方法都有一個過載的方法,用來支援異常處理。過載方法如下所示:
void Debug(object message,Except ex);
void Info(object message,Except ex);
void Warn(object message,Except ex);
void Error(object message,Except ex);
void Fatal(object message,Except ex);
//Boolean屬性用來檢查Logger的日誌級別,如下所示:
bool isDebugEnabled;
bool isInfoEnabled;
bool isWarngEnabled;
bool isErrorEnabled;
bool isFatalEnabled;
}
Log4net框架定義一個叫LogManager的類,用來管理所有的logger物件。他有一個GetLogger()靜態方法,用我們提供的名字引數來檢索已經存在Logger物件(儲存在配置檔案中)。如果框架裡面不存在該Logger物件,它也會為我們建立一個Logger物件。程式碼如下所示:
Log4net.Ilog log = log4net.LogManager.GetLogger(LoggerName);
通常來說,我們會為類的型別為引數呼叫GetLogger(),以便跟蹤我們在進行日誌記錄的類,傳遞類的型別可以用typeof(ClassName)方法來獲得,或者可以用如下的反射方法來獲得:
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType,儘管符號長了一些,但是後者可以用於一些場合,比如獲去呼叫方法的類的型別。
1.1.1 日誌級別
正如在ILog的介面中看到的一樣,有五中不同的方法可以跟蹤一個應用程式。事實上這五中方法是運作在Logger物件設定的不通日誌優先級別上。這幾種不通的級別是作為常量定義在log4net.spi.Level類中。你可以在程式中使用任何一種方法。但是在最後的釋出中,你也許不想讓所有的程式碼來浪費你的cpu週期,因此,框架提供了7中級別和物件的Boolean屬性來控制日誌的記錄的型別。
表1-1 Logger的日誌級別
級別 |
允許方法 |
Boolean屬性 |
優先級別 |
OFF |
拒絕所有 |
Height |
|
FATAL |
Void Fatal(…); |
bool isFatalEnabled |
|
ERROR |
VoidError(…); |
bool isErrorEnabled |
|
WARN |
Void Warn (…); |
bool isWarnEnabled |
|
INFO |
Void Info(…); |
bool is InfoEnabled |
|
DEBUG |
VoidDebug(…); |
bool isDebugEnabled |
|
ALL |
允許所以 |
Lowest |
在log4net框架裡,通過設定配置檔案,每個日誌物件都被分配一個日誌優先級別,如沒有給一個日誌物件顯式地分配一個級別,那麼改物件會試圖從他的祖先繼承一個級別的。
ILog介面的每個方法都有一個預先定義好了的界別。正如表1-1看到的,ILog的Info()方法具有INFO級別。同樣的,以此類推,Error()方法具有ERROR級別。當我們使用以上任何一種方法時,log4net框架會檢查日誌物件logger的級別和方法的級別。只有當方法的級別高於日誌級別時,日誌請求才會被接受並執行。
1.2 Respository
Respository主要用於負責日誌物件組織結構的維護。在log4net的以前版本中,框架僅支援分等級的組織結構(hierarchical organization)。這種等級結構本質上是庫的一個實現,並且定義在log4net.Respository.Hierarchy名字空間中。要實現一個Respository,需要
實現log4net.Respository.ILoggerRespository介面。但是通常並不是直接實現該介面,而是以log4net.Respository.LoggerRespositorySkeleton為基類繼承體系庫(hierarchical respository)則由log4net.Respository.Hierarchy.Hierarchy類實現。
如果你是log4net框架的使用者,而非擴充套件者,那麼你幾乎不會在你的程式碼中用到Respository的類。相反的,你需要用到LogManager類來自動管理庫和日誌物件。
1.3 Appender
一個好的日誌框架應該能夠產生許多目的地的輸出。如輸出控制檯,儲存檔案,或者存入資料庫等。Log4net能夠很好的滿足這些要求。它是使用一個叫做Appender的元件來定義輸出介質。正如名字所示,這些元件把他們附加到Logger日誌元件上並將輸出傳遞到輸出流中。你可以把多個Appender元件附加到一個日誌物件上。Log4net框架提供了幾個Appender元件。
1.4 Appender Filters
一個Appender物件預設地將所有的日誌時間傳遞到輸出流。Appender的過濾器(Appender Filters)可以按照不同的標準過濾日誌事件。在log4net.Filter的名字控制元件下已經有幾個預定義的過濾器。使用這些過濾器,你可以按照日誌級別範圍過濾日誌時間,或者按照某個特殊的字串進行過濾。你可以在API的幫助檔案中發現更多有關Filter的資訊。
1.5 Layout
Layout元件用於向用戶顯示最後經過格式化的輸出資訊。輸出資訊可以一多種格式顯示,主要依賴與我們採用的layout元件的型別。可以是線性的或者XML檔案。Layout元件和一個Appender元件一起工作哦。API幫助手冊中有關於不通Layout元件的列表。一個Appender物件,只能物件一個Layout物件。要實現你自己的Layout類,你需要從log4net.Layout.LayoutSkeleton類繼承,它實現了ILayout介面。
2 定義配置檔案
配置資訊可以放在如下幾中形式檔案的一種中。
1.在程式的配置檔案裡,如AssemblyName.Config 或 web.config.
2.在自己的檔案裡,檔名可以自取。
Log4net框架會在相對於AppDomain.CurrentDomain.Base.Directory屬性定義的目錄路徑下查詢配置檔案。框架在配置檔案裡要查詢的唯一表示是<log4net>標籤。一個完整的配置檔案(命名為:Log.config)的例子如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name ="log4net" type ="log4net.Config.Log4NetConfigurationSectionHandler,log4net-net-1.0"/>
</configSections>
<log4net>
<logger name="ManagerLog">
<level value="ALL"/>
<appender-ref ref ="LogFileAppender"/>
<appender-ref ref ="ADONetAppender"/>
</logger>
<!--<root>
<level value="ALL" />
<appender-ref ref="ADONetAppender"/>
</root>-->
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log.log"/>
<appenderToFile value="true"/>
<rollingstyle value="Date"/>
<datePattern value="yyyyMMdd"/>
<encoding value="utf-8"/>
<param name="MaxSizeRollBackups" value="5" />
<param name="MaximumFileSize" value="10MB" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%-5level]: %m%n" />
</layout>
<!--<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value ="OFF"/>
<levelMax value ="ALL"/>
</filter>-->
</appender>
<appender name ="ADONetAppender" type="log4net.Appender.ADONetAppender">
<bufferSize value ="10"/>
<connectionType value ="System.Data.SqlClient.SqlConnection,System.Data,Version=1.0.3300.0,Culture=neutral,publicKeyToken=b77a5c561934e089"/>
<connectionString value="server=SUNLIKE\SQLEXPRESS;database=blank;user id = sa;password = sa;timeout=300;"/>
<commandText value="INSERT INTO [Log] ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception);"/>
<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"/>
<!--<conversionPattern value ="%t"/>-->
</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>
</appender>
</log4net>
</configuration>
如果Log.config存放在debug目錄下,需要在Assembly.cs 末尾新增程式碼:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = @"Log.config", Watch = true)]
如果Log.config存放在其他目錄下,則需要在Assembly.cs 末尾新增程式碼:
[assembly: log4net.Config.XmlConfigurator(Watch = true)](注:如果在app.config 或者web.config 只要寫這行程式碼即可)
還需要在Program.cs中新增程式碼(確保找到配置檔案):
string path = @" ";//存放Log.config的路徑
FileInfo file = new FileInfo(path+ @"Log.config");
if (File.Exists(file.ToString()))
{
log4net.Config.XmlConfigurator.Configure(file);
}
else
{
throw new Exception("log4net日誌配置檔案未找到");
}
在程式中自定定義一個類ManagerLog類,對log4net的方法進行重寫。
public class ManageLog
{
#region 欄位定義
private static ILog logEntry = LogManager.GetLogger("ManagerLog");
//ManagerLog 與配置檔案中的Logger節中name屬性的值保持一致
// private static object objectMultx = new object();
//private static string logname = "log";
#endregion
#region 公共介面
/// <summary>
/// 輸出程式除錯資訊
/// </summary>
/// <param name="message">輸出資訊</param>
public static void Debug(string message)
{
logEntry.Debug(message);
}
/// <summary>
/// 輸出程式錯誤資訊
/// </summary>
/// <param name="message">輸出資訊</param>
public static void Info(string message)
{
logEntry.Info(message);
}
/// <summary>
/// 輸出程式錯誤資訊
/// </summary>
/// <param name="message">輸出資訊</param>
public static void Warn(string message)
{
logEntry.Warn(message);
}
/// <summary>
/// 輸出程式警告資訊
/// </summary>
/// <param name="message">輸出資訊</param>
public static void Error(string message)
{
logEntry.Error(message);
}
/// <summary>
/// 輸出程式致命錯誤資訊
/// </summary>
/// <param name="message">輸出資訊</param>
public static void Fatal(string message)
{
logEntry.Fatal(message);
}
#endregion
}
在需要寫日誌的地方加上相應的呼叫語句,如:
ManageLog.Debug("記錄時間……");
2.1 佈局樣式:
Class |
Description |
ExceptionLayout |
只呈現日誌事件中異常的文字資訊 |
Layout2RawLayoutAdapter |
適應於Ilayout介面到IRawLayout |
LayoutSkeleton |
擴充套件這個抽象類來建立自定義的佈局格式 |
PatternLayout |
可以通過型別字串來配置的佈局 |
PatternLayout.ConverterInfo |
把轉換器名字對映為轉換器型別的包裝類 |
RawLayoutConverter |
IrawLayout介面的型別轉換器 |
RawPropertyLayout |
從日誌事件中提取屬性值 |
RawTimeStampLayout |
從日誌事件中提取日期 |
RawUtcTimeStampLayout |
從日誌事件中提取日期 |
SimpleLayout |
很簡單的佈局 |
XmlLayout |
把日誌事件格式化為XML元素的佈局 |
XmlLayoutBase |
把日誌事件格式化為XML元素的佈局 |
XmlLayoutSchemalLog4j |
把日誌事件格式化為與log4j結構相容的XML元素佈局 |
2.2 一些說明
(一)log4配置說明
log4net的配置可以放在應用程式的預設配置檔案中(app.config或web.config),也可以再你自己的配置檔案中。(如果log4net的配置不是放在應用程式的配置檔案裡,而是在自己定義的檔案裡,<configSection>節點裡的<section>節點是不需要的。
(二)節點分析
在配置章節中,定義section節點。節點名稱為:須為log4net,且大小寫敏感。
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler" />
</configSections>
(三)Log4net章節內容
debug 可選,取值是true或false,預設是false。設定為true,開啟log4net的內部除錯。
update 可選,取值是Merge(合併)或Overwrite(覆蓋),預設值是Merge。設定為Overwrite,在提交配置的時候會重置已經配置過的庫。
threshold 可選,取值是repository(庫)中註冊的level,預設值是ALL。
支援的子元素:
·appender 0或多個
·logger 0或多個
·renderer 0或多個
·root 最多一個
·param 0或多個
(四)兩個Appenders(輸出源)
定義日誌的輸出方式,只能作為 log4net 的子元素。name屬性必須唯一,type屬性必須指定
支援的屬性:
name 必須的,Appender物件的名稱
type 必須的,Appender物件的輸出型別
支援的子元素:
·appender-ref 0個或多個,允許此appender引用其他appender,並不是所以appender型別都支援。
·filter 0個或多個,定義此app使用的過濾器。
·layout 最多一個。定義appender使用的輸出格式。
·param 0個或多個, 設定Appender類中對應的屬性的值。
·LogFileAppender
節點日誌檔案輸出。type="log4net.Appender.FileAppender"
·ConsoleAppender
節點控制檯輸出。type="log4net.Appender.ConsoleAppender"
(五)一個root
根logger,所有其它logger都預設繼承它。root元素沒有屬性。
支援的子元素:
·appender-ref 0個或多個,要引用的appender的名字。
·level 最多一個。 只有在這個級別或之上的事件才會被記錄。
·param 0個或多個, 設定一些引數。
<root>
<level value="WARN" />
<appender-ref ref="LogFileAppender" />
<appender-ref ref="ConsoleAppender" />
</root>
(六)Logger
支援的屬性:
name 必須的,logger的名稱
additivity 可選,取值是true或false,預設值是true。設定為false時將阻止父logger中的appender。
支援的子元素:
·appender-ref 0個或多個,要引用的appender的名字。
·level 最多一個。 只有在這個級別或之上的事件才會被記錄。
·param 0個或多個, 設定一些引數。
<logger name="testApp.Logging">
<level value="DEBUG"/>
</logger>
(七)Layout
佈局,只能作為<appender>的子元素。
支援的屬性:
type 必須的,Layout的型別
支援的子元素:param 0個或多個, 設定一些引數。
(八)Filter
過濾器,只能作為<appender>的子元素。
支援的屬性:
type 必須的,Filter的型別
支援的子元素:param 0個或多個, 設定一些引數。
(九)Param
<param>元素可以是如何元素的子元素。
支援的屬性:
name 必須的,取值是父物件的引數名。
value 可選的,value和type中,必須有一個屬性被指定。value是一個能被轉化為引數值的字串。
type 可選的,value和type中,必須有一個屬性被指定。type是一個型別名,如果type不是在log4net程式集中定義的,就需要使用全名。
支援的子元素:param 0個或多個, 設定一些引數
2.3 模式轉化
%m(message)輸出日誌訊息
%n(newline)換行
%d(datetime)輸出當前語句執行的時刻
%r(runtime)輸出當前語句的執行時刻
%t(thread id)當前語句所在的執行緒ID
%p(priority)日誌的當前優先級別,DEBUG INFO ……
%c(class)當前日誌物件的名稱
%L 輸出語句所在的行號
%F 輸出語句所在的檔名
%-數字 表示該項的最小長度,如果不夠,用空格填充
結束語
通過這兩天的學習對log4net元件的配置有了一定的瞭解,能進行簡單的日誌輸出,不僅能夠在console顯示,也可以匯入到文字檔案裡,還可以匯入到資料庫中。方便簡單,在開發中是一個很不錯的助手。在學習的過程中也發現不少問題,比如做一個控制元件,該控制元件有寫日誌的功能,日誌寫入到sql server 2005中,僅當該控制元件銷燬之後,才能一次寫入資料庫,即如果該控制元件還在活動,在資料庫中是查不出剛剛新增的日誌記錄。具體原因不太清楚,也沒有深究,我估計日誌是當成一個事物來處理了。另外還有一個問題,就是目前還沒有找到一種行之有效的方法寫入oracle10g 或oracle 11g的方法。如果有朋友看到該疑問,請幫忙指正和賜教。網上也有很多資料,本篇篇文章寫的比較膚淺,是參照百度文庫的一篇文章和csdn一些n人的部落格,結合自己的實際開發,總結而成,如有文章中有什麼不妥之處,還請指正。不勝感激。
相關推薦
Log4net的配置學習與總結
1 Log4net的結構 Log4net 有四種主要的元件,分別是logger(記錄器)、Repository(庫)、Appender(附著器)以及Layout(佈局)。 1.1 Logger Logger是應用程式需要互動的主要元件,它用來產生日誌訊
Java Web 學習與總結(二)Servlet核心介面+Servlet3.0配置
Servlet3.0版本對Servlet配置進行了重大變革,Servlet類不需要再麻煩的去編輯web.xml檔案了,只需要在類上面進行註釋就可以了,獲得了 Java 社群的一片讚譽之聲,以下是新增的註解支援。 @WebServlet @WebServlet 用於將一個類宣告為 Servlet,該註解
Java多執行緒學習與總結(Join)
join()方法的用法: join()是主執行緒 等待子執行緒的終止。也就是在子執行緒呼叫了 join() 方法後面的程式碼,只有等到子執行緒結束了才能執行。 例子如下: Java程式碼 p
Java多執行緒學習與總結(ThreadGroup)
在Java中每個執行緒都屬於某個執行緒組(ThreadGroup)。例如,如果在main()中產生一個執行緒,則這個執行緒屬於main執行緒組管理的一員,您可以使用下面的指令來獲得目前執行緒所屬的執行緒組名稱: Java程式碼
多執行緒的學習與總結
單執行緒: 只有一個順序執行流 例如:單執行緒的程式如同只僱傭一個服務員的餐廳,他必須做完一件事情後才可以做下一件事情; 多執行緒: 可以
Android UI之底部彈框的學習與總結
1、簡介 本文將介紹的是從底部彈出窗體以供使用者進行互動的例子,本文將介紹使用Dialog,View和DialogFragment的方式分別來進行實現。也是仿製了58同城的彈出喜好的UI顯示和互動。彈出框真的是很常見的,在安卓中有廣泛的用途,故而有必要對其進行好好的梳理,後
Rxjava2的學習與總結
Rxjava2基礎認知 形式正確的有限Observable 呼叫觀察者的onCompleted正好一次或者它的onError正好一次,而且此後不能再呼叫觀察者的任何其它方法。如果onComplete 或者 onError 走任何一個 都會 主動解除訂閱關
nginx 301 302跳轉配置方法 與 總結
首先看一個完整程式碼示例,關於nginx 301 302跳轉的。 301跳轉設定: server { listen 80; server_name 123.com; rewrite ^/(.*) http://456.com/$1 permanent; access_log
iOS幾種常用執行緒鎖學習與總結。
開始前,先建立3個執行緒執行的任務。- (void)method1 { NSLog(@"%@", @"執行緒1"); } - (void)method2 { NSLog(@"%@", @"執行緒2"); } - (void)method3 { NS
Hbase學習與總結
一.Hbase簡介: Hbase是bigtable的開源山寨版本。它利用HadoopHDFS作為其檔案儲存系統,利用Hadoop MapReduce來處理HBase中的海量資料,利用Zookeeper作為協同服務。提供高可靠性、高效能、列儲存、可伸縮、實時讀寫的資
Java EE 之 過濾器入門學習與總結(1)
ret oct 入門 全局 err throws () XML view 使用Filter技術來配合開發會使得開發變得簡單起來。簡單的一個例子就表現在“亂碼問題”上。不使用Filter的話,我們有可能需要為每一個網頁設置字符編碼集,如request.setCharacte
java中集合的學習與總結
集合與陣列:陣列:長度固定,可以儲存基本型別。集合:長度可變,不能儲存基本型別(只能儲存物件)。集合類框架圖: Collection介面是集合類的根介面,Java中沒有提供這個介面的直接的實現類。但是卻讓其被繼承產生了兩個介面,就是Set和List。Set中不能包含重複的元素
Redis學習與總結
vnr vid idl master 總結 config 核心 climb www 前言 本文為學習Redis的一個總結,包含了資料的整理,Redis的介紹,常用數據類型,常用命令,多數據庫與事務的特性以及持久化的概述;如何在Linux上部署,以及使用Java客戶端開發工具
log4net配置學習 之 日誌等級
Logger hierarchy(層次級別) Logger都是已經命名的實體。 Logger的名稱區分大小寫並遵循以下規則: 1、如果A logger的名稱如果是B logger名稱的字首(通過“.”連線),則說A logger是B logger的祖父級。 2、如果
字串最小/最大表示法 學習與總結
迴圈字串的最小表示法的問題可以這樣描述:對於一個字串S,求S的迴圈的同構字串S’中字典序最小的一個。由於語言能力有限,還是用實際例子來解釋比較容易:設S=bcad,且S’是S的迴圈同構的串。S’可以是bcad或者cadb,adbc,dbca。而且最小表示的S’是adbc。對於
二分圖學習與總結筆記
sca 匈牙利 算法 連續 總結 bubuko clu head con 二分圖也就是給定關系,劃分成兩個集合,使得各自集合的元素沒有關系連接! 在這裏不深刻探討如何實現,而是通過算法來進行學習,二分圖是一類非常簡單的問題 但是最重要的還是圖論中匹配模型的構造,要註
MyBatis學習總結(二)——MyBatis核心配置檔案與輸入輸出對映
在上一章中我們學習了《MyBatis學習總結(一)——ORM概要與MyBatis快速起步》,這一章主要是介紹MyBatis核心配置檔案、使用介面+XML實現完整資料訪問、輸入引數對映與輸出結果對映等內容。 一、MyBatis配置檔案概要 MyBatis核心配置檔案在初始化時會被引用,在配置檔案中定義了一些
Apache Shiro學習----配置(與SpringMVC集成)
async 匹配 過濾 -i fig hit http struct 找到 1.web.xml文件中配置 <!--將shiro的配置文件交給Spring監聽器初始化--> <context-param> <param
【前端】react學習階段總結,學習react、react-router與redux的這些事兒
行程 clas 目前 webpack body src 控制 return 體驗 前言 借用阮一峰的一句話:真正學會 React 是一個漫長的過程。 這句話在我接觸react深入以後,更有感觸了。整個react體系都是全新的,最初做簡單的應用,僅僅使用react-to
基礎LINUX學習與配置
src enable 小寫字母 gcc 中文 conf 個數字 man命令 zxvf 1.別名,內部命令,哈希表,外部命令,運行命令時的優先級別,以pwd為例 1.首先比較別名和內部命令的優先級 運行alias enable=‘pwd‘,enable是一個內部命令,現在我