log4net使用(保存日志分别 到文本文件,smtp发送邮件,mssql数据库,mysql数据库)

我们自带的MemcachedCacheProviders自带的log4net是 1.2.10版本,所以就拿这个版本说吧

下面是一个演示的效果,以及日志分别表达的意思

image 

表示时间 2011-09-20 14:17:03,312  (312代表的是毫秒)

[4] 表示线程编号,暂时不需要管

DeBUG 表示我们用的是debug模式

Log4NetTest.Test1 表示我们是在哪个类里面

-我的第一条日志  表示详细信息

 

下面开始配置:(我们配置一个能自动生成月份+天数的日志文件,并且,如果报错,则发送邮件)

image

image

 

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);

image

建议写成一个通用类

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> 结束的下面一行)

image

 
<log4net>
        <!--这里是第一个附加器   RollingFileAppender  滚动日志文件附加器-->
        <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">

            <file value="Log\\"/>
            <!--日志文件夹及文件名开头,文件名后面加上.log后缀,必须使用转义字符-->
            <DatePattern value="yyyyMM\\yyyy-MM-dd&quot;.log&quot;"/>
            <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) NULL
10:  )

然后需要在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到项目下;

image
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 NULL
 9:  )
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,那么每次报错数据库都会有新的数据(缺点显而易见,频繁的访问数据库··)

posted @ 2012-12-14 16:34  梨花驿路  阅读(1034)  评论(0编辑  收藏  举报