这几天在学习Log4Net的使用,以下为学习笔记:
1. log4net 的下载和安装
官网或者度娘下载源文件编译,或者直接下载DLL,引入工程即可。
2.log4Net的配置
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> </configSections> <!--log4net日志配置部分--> <log4net> <root> <!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF--> <!--比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录--> <!--如果没有定义LEVEL的值,则缺省为DEBUG--> <level value="ERROR"/> <appender-ref ref="RollingFileAppender"/> </root> <logger name="Program.A"> <level value="DEBUG" /> <appender-ref ref="RollingFileAppender" /> </logger> <logger name="Program.B"> <level value="DEBUG" /> <appender-ref ref="RollingFileAppender" /> </logger> <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> <!--日志文件名开头--> <file value="D:LogTestLog4net.TXT"/> <!--多线程时采用最小锁定--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/> <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置--> <datePattern value="(yyyyMMdd)"/> <!--是否追加到文件,默认为true,通常无需设置--> <appendToFile value="true"/> <!--变换的形式为日期,这种情况下每天只有一个日志--> <!--此时MaxSizeRollBackups和maximumFileSize的节点设置没有意义--> <!--<rollingStyle value="Date"/>--> <!--变换的形式为日志大小--> <!--这种情况下MaxSizeRollBackups和maximumFileSize的节点设置才有意义--> <RollingStyle value="Size"/> <!--每天记录的日志文件个数,与maximumFileSize配合使用--> <MaxSizeRollBackups value="10"/> <!--每个日志文件的最大大小--> <!--可用的单位:KB|MB|GB--> <!--不要使用小数,否则会一直写入当前日志--> <maximumFileSize value="2MB"/> <!--日志格式--> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%t]%-5p %c - %m%n"/> </layout> </appender> </log4net> </configuration>
3.测试代码:
[assembly: log4net.Config.XmlConfigurator(Watch = true)] namespace Log4NetStu { class Program { static void Main(string[] args) { Console.WriteLine("BEGIN"); //ILog m_log = LogManager.GetLogger("sss"); //m_log.Error("这是一个Error日志"); Thread t1 = new Thread(start); t1.Name = "A"; t1.Start(); Thread t2 = new Thread(start); t2.Name = "B"; t2.Start(); Console.ReadLine(); } public static void start() { string name = "Program." + Thread.CurrentThread.Name; ILog m_log = LogManager.GetLogger(name); Console.WriteLine(name + " start"); for (int i = 0; i <= 1000; i++) { m_log.Debug("这是一个Debug日志"); Thread.Sleep(300); } Console.WriteLine(name + " end"); } } }
4.测试结果:
2015-12-15 09:59:45,790 [A]DEBUG Program.A - 这是一个Debug日志
2015-12-15 09:59:45,790 [B]DEBUG Program.B - 这是一个Debug日志
2015-12-15 09:59:45,790 [B]DEBUG Program.B - 这是一个Debug日志
2015-12-15 09:59:45,790 [A]DEBUG Program.A - 这是一个Debug日志
2015-12-15 09:59:48,974 [B]DEBUG Program.B - 这是一个Debug日志
2015-12-15 09:59:48,974 [B]DEBUG Program.B - 这是一个Debug日志
2015-12-15 09:59:48,974 [A]DEBUG Program.A - 这是一个Debug日志
5.配置详细说明(学习到哪更新到哪....)
layout输出格式:
轉換字符 |
效果 |
a |
等同於 appdomain |
appdomain |
Used to output the friendly name of the AppDomain where the logging event was generated. 用於輸出日誌事件發生的AppDomain的一個友好的名字 |
c |
等同於logger |
C |
等同於type |
class |
等同於type |
d |
等同於date |
date |
用於輸出日誌事件在當前時區中的日期.若要輸出通用時間,請使用%utcdate模式.日期轉換指定符後可以跟隨一對閉合的花括號, 花括號裡面為日期格式指定符.例如:%date{HH:mm:ss,fff}或%date{dd MMM yyyy HH:mm:ss,fff},若沒有指定任何格式,默認為ISO8601(Iso8601DateFormatter). 格式指定符和TOString的語法一樣. 為了達到較好的效果,建議使用log4net日期格式化器.他們可以使用以下一個字符串”ABSOLUTE”,”DATE”,”ISO8601”來分別指定AbsoluteTimeDateFormatter,DateTimeDateFormatter和Iso8601DateFormatter.例如: %date{ISO8601} or %date{ABSOLUTE}. 這些專用的日期格式化器效果比ToString好很多. |
exception |
用於輸出連同日誌信息一起傳入的異常. 如果一個異常對象被儲存在日誌記錄事件中,他將會被帶有trailing newline的模式輸出.否則,不會. |
F |
等同於 file |
file |
用於輸出引發日誌記錄請求的文件名稱. 例如: c:inetpubwwwrootlogtestwebform1.aspx.cs 警告:產生呼叫者的位置信息相當慢.盡量避免使用,除非執行速度不是問題. |
identity |
用於輸出當前用戶的用戶名(Principal.Identity.Name). 警告:產生呼叫者的位置信息相當慢.盡量避免使用,除非執行速度不是問題. |
l |
等同於location |
L |
等同於line |
location |
用於輸出產生日誌記錄事件的呼叫者的位置信息. 此位置信息依賴於CLI的實現,但是他通常為命名空間限制的方法且後用跟用圓括號括起來的呼叫者文件名和行號. 例如:LogTest.WebForm1.Button3_Click(c:inetpubwwwrootlogtestwebform1.aspx.cs:93) 位置信息非常有用.然而,他的產生相當慢. 盡量避免使用,除非執行速度不是問題. |
level |
用於輸入記錄事件的等級. |
line |
用於輸出引發日誌記錄請求的行號. 警告:產生呼叫者的位置信息相當慢.盡量避免使用,除非執行速度不是問題. |
logger |
用於輸出日誌記錄事件的日誌名字.這個日誌轉換符後面可以跟精度,精度是十進制常量,用花括號括起來.如果指定了精度符,則只會輸出從右向左的相應數目的名字,默認為輸入全部. 如下:日誌記錄器的名字為”a.b.c”, %logger{2}將會輸出”b.c” |
m |
等同於message |
M |
等同於 method |
message |
用於輸出應用程式提供給日誌記錄事件的信息. |
mdc |
MDC(舊名: ThreadContext.Properties)是聯合事件屬性的一部份.這個模式支持兼容性,但是等同於property. |
method |
用於輸出引發日誌記錄請求的方法的名字. 警告:產生呼叫者的位置信息相當慢.盡量避免使用,除非執行速度不是問題. |
n |
等同於 newline |
newline |
換行,等同於” ”或” ” |
p |
等同於 level |
P |
等同於 property |
properties |
等同於 property |
property |
用於輸出一個事件的指定的屬性.屬性名字要以花括號括起來並且直接放到property後面.例如:%property{user}.日誌中的每一個屬性指都需要單獨指定.Properties是日誌記錄器或追加器添加到事件中的.默認屬性為log4net:HostName,它是引發產生記錄事件的機器名字. 若果沒有指定關鍵字,比如: %property ,將會將鍵值以逗號分格列表 |
r |
等同於 timestamp |
t |
等同於thread |
timestamp |
用於輸出從程式啟動到日誌記錄事件建立的時間,以毫秒記. |
thread |
用於輸出引發日誌記錄事件的線程的名字,若無線程名,則用線程號. |
type |
所用同logger 警告:產生呼叫者的位置信息相當慢.盡量避免使用,除非執行速度不是問題. |
u |
等同於 identity |
username |
用於輸出當前用戶的WindowsIdentity 警告:產生呼叫者的位置信息相當慢.盡量避免使用,除非執行速度不是問題. |
utcdate |
使用同date |
w |
等同於 username |
x |
等同於 ndc |
X |
等同於 mdc |
% |
%%輸出一個% |
6.常见问题
1) 引入后配置正确但无法写日志。
原因可能是在表空间前面缺少这段代码 [assembly: log4net.Config.XmlConfigurator(Watch = true)]
2) 上面的程序中会重复打印日志
原因是为根logger(root)和它的子logger(Program.A和Program.B)都指定了appender。在调用子logger时父logger的行为依然会生效,所以root与Program.A和Program.B 输出了同样的日志