log4net使用(保存日志分别 到文本文件,smtp发送邮件,mssql数据库,mysql数据库)
我们自带的MemcachedCacheProviders自带的log4net是 1.2.10版本,所以就拿这个版本说吧
下面是一个演示的效果,以及日志分别表达的意思
表示时间 2011-09-20 14:17:03,312 (312代表的是毫秒)
[4] 表示线程编号,暂时不需要管
DeBUG 表示我们用的是debug模式
Log4NetTest.Test1 表示我们是在哪个类里面
-我的第一条日志 表示详细信息
下面开始配置:(我们配置一个能自动生成月份+天数的日志文件,并且,如果报错,则发送邮件)
log4net的配置,跟你的程序是 B/S 还是C/S是没有区别的
要想获取最新版本的log4net组件库,可以到官方网站http://logging.apache.org/log4net/下载。现在的最新版本是1.2.10.
在程序中我们只需要log4net.dll文件就行了,添加对log4net.dll的引用,就可以在程序中使用了。
1:在web.config里面的 configSections里面加入 log4net,而且必须是 configSections的第一个元素
<configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
2:
如果是CS程序,在根目录的Program.cs中的Main方法中添加:
log4net.Config.XmlConfigurator.Configure();
如果是BS程序,在根目录的Global.asax.cs(没有新建一个)中的Application_Start方法中添加:
private static readonly ILog Logger = LogManager.GetLogger(typeof(Global)); protected void Application_Start(object sender, EventArgs e) { { log4net.Config.XmlConfigurator.Configure(); } } protected void Application_Error(object sender, EventArgs e) { Logger.Error("程序发生未捕获的异常\t\t\t" + HttpContext.Current.Error.Message, HttpContext.Current.Error); }
无论BS还是CS程序都可直接在项目的AssemblyInfo.cs文件里添加以下的语句:
[assembly: log4net.Config .XmlConfigurator()]
3:
前台代码的调用
LogManager.GetLogger(typeof(_Default)).Error(ex.Message); //或者是 //ILog logger = LogManager.GetLogger(typeof (_Default)); //logger.Error(ex.Message);
建议写成一个通用类
public class LogHelper { public static void WriteLog(string strTxt, Exception ex, Type type) { ILog log = log4net.LogManager.GetLogger(type); log.Error(strTxt, ex); } }调用如下
LogHelper.WriteLog("运行错误", ex, this.GetType());
4:继续在web.config节点里面的 configuration 里面 (一般是在 </configSections> 结束的下面一行)
<log4net> <!--这里是第一个附加器 RollingFileAppender 滚动日志文件附加器--> <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="Log\\"/> <!--日志文件夹及文件名开头,文件名后面加上.log后缀,必须使用转义字符--> <DatePattern value="yyyyMM\\yyyy-MM-dd".log""/> <appendToFile value="true"/> <!--最多产生的日志文件数,超过则只保留最新的n个。设定值value="-1"为不限文件数--> <maxSizeRollBackups value="10"/> <!--日志文件的最大大小--> <maximumFileSize value="1024KB"/> <staticLogFileName value="false"/> <!--允许多个进程可以写入同一个文件--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%n%n=============================================记录时间:%date===========================================%n%n 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - %n错误描述:%message%newline%n%n%exception% %n =============================================End===========================================%n" /> </layout> </appender> <!--这里是第二个附加器 用来发送邮件--> <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender"> <authentication value="Basic" /> <to value="发送的目标邮箱 例如 to@qq.com" /> <from value="从哪里发出的邮箱 例如 from123456@qq.com" /> <username value="邮箱账号 例如 from123456" /> <password value="邮箱密码" /> <subject value="网站报错" /> <smtpHost value="smtp.qq.com" /> <bufferSize value="512" /> <lossy value="true" /> <evaluator type="log4net.Core.LevelEvaluator"> <threshold value="Error"/> </evaluator> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%n记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - %n错误描述:%message%newline%n%exception% %n" /> </layout> </appender> <!--这里是第三个附加器,用来发送到 Mssql数据库--> <appender name="AdoNetAppender_MsSql2005" type="log4net.Appender.AdoNetAppender"> <bufferSize value="1" /> <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <connectionString value="server=.\SQL2005;database=eftest;integrated security=false;persist security info=True;UID=sa;PWD=tiantang" /> <!--这里可以是参数化的查询语句,也可以是存储过程--> <commandText value="INSERT INTO Log ([LogDate],[Thread],[LogLevel],[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" /> </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> <!--这里是第四个附加器,用来发送日志到 Mysql数据库,记得要在项目中引用 MySql.Data.dll--> <appender name="AdoNetAppender_MySql" type="log4net.Appender.AdoNetAppender"> <!--千万注意这里的name不能为AdoNetAppender,或者说是与后面Type的类型相同,就因为这个问题,我花了少功夫找问题.最后终于在某人blog中看到这样的提示.改名后就OK了.--> <bufferSize value="1"/> <param name="ConnectionType" value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" /> <param name="ConnectionString" value="database=edt_date;Password=123456;uid=root;server=localhost;Port=3306"/> <param name="CommandText" value="insert into `log`(LogDate,Thread,LogLevel,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" /> </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> <root> <level value="Error"/> <!--如果这里还写了 DEBUG,那么凡是你DEBUG的时候的信息,都会记录下来--> <!--<level value="DEBUG"/>--> <!--定义日志的输出媒介,这里的ref就是根据上面你有多少个appender附加器。--> <appender-ref ref="RollingLogFileAppender"/> <appender-ref ref="SmtpAppender"/> <appender-ref ref="AdoNetAppender_MsSql2005"/> <appender-ref ref="AdoNetAppender_MySql"/> </root> </log4net>
log4net 有四种主要的组件,分别是Logger(记录器), Repository(库), Appender(附着器)以及 Layout(布局).
log4net定义了日志内容的不同级别,从高到低依次是FATAL(致命错误)、ERROR(一般错误)、WARN(警告)、INFO(一般信息)、DEBUG(调试信息)。
可以在配置文件中设置日志级别。上面的例子中看到我们在root中定义了<level value="Error" />,表示凡是级别等于高于Error的都可以输出至日志中。
但是如果你的附加器的配置更低一些,则附加器里面的也会被保存
在上面的配置中,每个日志文件最大1024KB,最大日志文件个数是10生成的日志文件名会是当前的年份月份 加上, 2012-12-13.log 2012-12-13.log.1 ... 2012-12-13.log.10,
如果记录的日志超过10个,会从2012-12-13.log.1开始覆盖。
【写日志的原则】
Ⅰ.在catch后,把异常写入日志.
Ⅱ.在调用第三方控件的开始和结束处.
Ⅲ.在连接数据库的开始结束处.
Ⅳ.除非必要,不要在循环体中加入日志,否则一旦出问题可能导致日志暴增.
Ⅴ.在自己认为很重要的逻辑处写入日志.
如果是想用Mssql数据库呢?如果我们想用mysql数据库呢?
表结构的定义稍微有一点不一样,sqlserver数据库如下(我用的是sql2005)
1: CREATE TABLE [dbo].[LOG]2: (3: [LogId] [INT] IDENTITY (1, 1) NOT NULL,4: [LogDate] [DATETIME] NOT NULL,5: [Thread] [VARCHAR] (255) NOT NULL,6: [LogLevel] [VARCHAR] (50) NOT NULL,7: [Logger] [VARCHAR] (255) NOT NULL,8: [Message] [VARCHAR] (4000) NOT NULL,9: [Exception] [VARCHAR] (2000) NULL10: )然后需要在Append和Root里面增加代码
1: <!--这里是第三个附加器,用来发送到 Mssql数据库-->2: <appender name="AdoNetAppender_MsSql2005" type="log4net.Appender.AdoNetAppender">3: <bufferSize value="2" />4: <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />5: <connectionString value="server=.\SQL2005;database=eftest;integrated security=false;persist security info=True;UID=sa;PWD=tiantang" />6: <!--这里可以是参数化的查询语句,也可以是存储过程-->7: <commandText value="INSERT INTO Log ([LogDate],[Thread],[LogLevel],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />8: <parameter>9: <parameterName value="@log_date" />10: <dbType value="DateTime" />11: <layout type="log4net.Layout.RawTimeStampLayout" />12: </parameter>13: <parameter>14: <parameterName value="@thread" />15: <dbType value="String" />16: <size value="255" />17: <layout type="log4net.Layout.PatternLayout">18: <conversionPattern value="%thread" />19: </layout>20: </parameter>21: <parameter>22: <parameterName value="@log_level" />23: <dbType value="String" />24: <size value="50" />25: <layout type="log4net.Layout.PatternLayout">26: <conversionPattern value="%level" />27: </layout>28: </parameter>29: <parameter>30: <parameterName value="@logger" />31: <dbType value="String" />32: <size value="255" />33: <layout type="log4net.Layout.PatternLayout">34: <conversionPattern value="%logger" />35: </layout>36: </parameter>37: <parameter>38: <parameterName value="@message" />39: <dbType value="String" />40: <size value="4000" />41: <layout type="log4net.Layout.PatternLayout">42: <conversionPattern value="%message" />43: </layout>44: </parameter>45: <parameter>46: <parameterName value="@exception" />47: <dbType value="String" />48: <size value="2000" />49: <layout type="log4net.Layout.ExceptionLayout" />50: </parameter>51: </appender>52:
Root里面增加
1: <appender-ref ref="AdoNetAppender_MsSql2005"/>2:
如果是mysql数据库,
1)首先需要到mysql的官方网站(www.mysql.com)下载驱动,网站上提供了两个驱动,这里我使用的mysql-connector-net连接器,版本越新越好,我这里用的是6.5.4 。复制MySql.Data.dll到项目下;
2)在项目中添加引用,选择MySql.Data.dll,最好是直接放在bin文件夹;
3)在本机的mysql上使用test数据库,使用一下sql创建表:
创建表如下
1: CREATE TABLE LOG(2: LogId INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,3: LogDate DATETIME NOT NULL,4: Thread VARCHAR (255) DEFAULT NULL,5: LogLevel VARCHAR (50) DEFAULT NULL,6: Logger VARCHAR (255) DEFAULT NULL,7: Message VARCHAR (4000) DEFAULT NULL,8: Exception VARCHAR (2000) DEFAULT NULL9: )
10:
然后需要在Append增加代码1: <!--这里是第四个附加器,用来发送日志到 Mysql数据库,记得要在项目中引用 MySql.Data.dll-->2: <appender name="AdoNetAppender_MySql" type="log4net.Appender.AdoNetAppender">3:
4: <!--千万注意这里的name不能为AdoNetAppender,或者说是与后面Type的类型相同,就因为这个问题,我花了少功夫找问题.最后终于在某人blog中看到这样的提示.改名后就OK了.-->5:
6: <bufferSize value="2"/>7: <param name="ConnectionType" value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" />8: <param name="ConnectionString" value="database=date;Password=xxxxx;uid=root;server=localhost;Port=3306"/>9: <param name="CommandText" value="insert into `log`(LogDate,Thread,LogLevel,Logger,Message,Exception) values(@log_date, @thread , @log_level, @logger, @message,@exception)" />10:
11: <parameter>12: <parameterName value="@log_date" />13: <dbType value="DateTime" />14: <layout type="log4net.Layout.RawTimeStampLayout" />15: </parameter>16: <parameter>17: <parameterName value="@thread" />18: <dbType value="String" />19: <size value="255" />20: <layout type="log4net.Layout.PatternLayout">21: <conversionPattern value="%thread" />22: </layout>23: </parameter>24: <parameter>25: <parameterName value="@log_level" />26: <dbType value="String" />27: <size value="50" />28: <layout type="log4net.Layout.PatternLayout">29: <conversionPattern value="%level" />30: </layout>31: </parameter>32: <parameter>33: <parameterName value="@logger" />34: <dbType value="String" />35: <size value="255" />36: <layout type="log4net.Layout.PatternLayout">37: <conversionPattern value="%logger" />38: </layout>39: </parameter>40: <parameter>41: <parameterName value="@message" />42: <dbType value="String" />43: <size value="4000" />44: <layout type="log4net.Layout.PatternLayout">45: <conversionPattern value="%message" />46: </layout>47: </parameter>48: <parameter>49: <parameterName value="@exception" />50: <dbType value="String" />51: <size value="2000" />52: <layout type="log4net.Layout.ExceptionLayout" />53: </parameter>54: </appender>55:
然后是Root里面添加
1: <appender-ref ref="AdoNetAppender_MySql"/>2:
如果append里面的配置都是有<bufferSize value="2" />的时候,数据库插入数据是会延迟的(输入不会丢,但是可能有很多秒都没有数据,然后一下子又全部出来了)。bufferSize 表示批处理的日志事件,可以避免每次日志事件都访问数据库;ConnectionType指定了要使用的IDbConnection的完全限定类型名称;connectionString表示连接字符串;CommandText是SQL语句或存储过程;最后一组parameter节点描述了SQL语句或存储过程需要的参数。如果觉得批处理会丢失数据(如果遇到突然停电之类,而且你的bufferSize又设置的特别大的话),可以将bufferSize设置为1,那么每次报错数据库都会有新的数据(缺点显而易见,频繁的访问数据库··)