ExtAspNet应用技巧(八) - log4net配置与使用

来源:互联网 发布:数据库管理需要会什么 编辑:程序博客网 时间:2024/06/05 17:44
前言

为了实践项目驱动的ExtAspNet开发过程,最近我启动了另外一个开源项目 - AppBox。
AppBox项目使用ExtAspNet作为前台展现层,SubSonic作为ORM层,SqlServer2005作为数据库,在Asp.Net2.0基础之上实现一个企业综合管理系统所必须的基础组件。
包括用户管理,菜单管理,权限管理,组织结构管理等各个部分,虽然AppBox不是给最终用户使用的,但是可以作为开发人员搭建网站的一个框架,同时在项目中遇到的控件会优先在ExtAspNet中实现。

由于在AppBox中使用了log4net作为日志记录组件,所以这篇文章就来分享一下log4net的配置和使用。

log4net配置

1. 首先到 http://logging.apache.org/ 下载最新的log4net v1.2.10。

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    )    


3. 在网站根目录添加log4net.config文件
        <log4net>      <root>        <level value="ALL"/>        <appender-ref ref="AdoNetAppender"/>        <appender-ref ref="RollingFileAppender"/>      </root>      <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender,log4net">        <param name="File" value="log\log.config"/>        <param name="AppendToFile" value="true"/>        <param name="MaxSizeRollBackups" value="10"/>        <param name="MaximumFileSize" value="5MB"/>        <param name="RollingStyle" value="Size"/>        <param name="StaticLogFileName" value="true"/>        <layout type="log4net.Layout.PatternLayout,log4net">          <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n"/>        </layout>      </appender>      <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">        <bufferSize value="0"/>        <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089"/>        <connectionString value="Password=sa;Persist Security Info=True;User ID=sa;Initial Catalog=AppBox;Data Source=."/>        <commandText value="insert into X_Log(DATETIME,THREAD,LOG_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"/>          </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>    


注:这里我们使用了两种类型的日志记录方式,文件和数据库。
文件保存在网站根目录下的 log\log.config ,必须保证Asp.Net服务进程对此文件夹有写权限,否则不能写入文件并且没有任何提示。
比如在WindowXP下需要设置 ASPNET (Windows2003不是这个名称,可以Google一下) 对此文件夹的写权限。
同时注意我们使用log.config而不是log.txt,是为了防止匿名用户非法下载系统日志。

在数据库配置上也有个小技巧,我们设置了 bufferSize value="0",也就是说产生一条日志就写到数据库。
我刚开始也是在这个地方遇到麻烦,设置bufferSize为10,刚开始怎么也观察不到日志插入数据库,后来才知道被缓存了。


不要在多处定义数据库连接字符串

因为我们已经在Web.config中定义了数据库连接字符串:
    <connectionStrings>        <clear/>        <add name="Default" connectionString="Password=sa;Persist Security Info=True;User ID=sa;Initial Catalog=AppBox;Data Source=."/>    </connectionStrings>    

因此如果在log4net.config中再定义数据库连接字符串,总觉得不爽。

经过在网上一番搜索,居然发现log4net v1.2.10不支持这个Asp.Net2.0的特性,不过这篇文章给出了一个解决方法。
我们需要在AppBox中添加一个CS文件:
    using System;    using System.Collections.Generic;    using System.Web;    using log4net;    using log4net.Appender;    using System.Configuration;    namespace AppBox    {        /// <summary>        /// http://issues.apache.org/jira/browse/LOG4NET-88        /// An appender for Log4Net that uses a database based on the connection string name.        /// </summary>        public class Log4NetConnectionStringNameAdoNetAppender : AdoNetAppender        {            private static ILog _Log;            /// <summary>            /// Gets the log.            /// </summary>            /// <value>The log.</value>            protected static ILog Log            {                get                {                    if (_Log == null)                        _Log = LogManager.GetLogger(typeof(Log4NetConnectionStringNameAdoNetAppender));                    return _Log;                }            }            private string _ConnectionStringName;            /// <summary>            /// Initialize the appender based on the options set            /// </summary>            /// <remarks>            /// <para>            /// This is part of the <see cref="T:log4net.Core.IOptionHandler"/> delayed object            /// activation scheme. The <see cref="M:log4net.Appender.AdoNetAppender.ActivateOptions"/> method must            /// be called on this object after the configuration properties have            /// been set. Until <see cref="M:log4net.Appender.AdoNetAppender.ActivateOptions"/> is called this            /// object is in an undefined state and must not be used.            /// </para>            /// <para>            /// If any of the configuration properties are modified then            /// <see cref="M:log4net.Appender.AdoNetAppender.ActivateOptions"/> must be called again.            /// </para>            /// </remarks>            public override void ActivateOptions()            {                PopulateConnectionString();                base.ActivateOptions();            }            /// <summary>            /// Populates the connection string.            /// </summary>            private void PopulateConnectionString()            {                // if connection string already defined, do nothing                if (!String.IsNullOrEmpty(ConnectionString)) return;                // if connection string name is not available, do nothing                if (String.IsNullOrEmpty(ConnectionStringName)) return;                // grab connection string settings                ConnectionStringSettings settings = ConfigurationManager                    .ConnectionStrings[ConnectionStringName];                // if connection string name was not found in settings                if (settings == null)                {                    // log error                    if (Log.IsErrorEnabled)                        Log.ErrorFormat("Connection String Name not found in Configuration: {0}",                            ConnectionStringName);                    // do nothing more                    return;                }                // retrieve connection string from the name                ConnectionString = settings.ConnectionString;            }            /// <summary>            /// Gets or sets the name of the connection string.            /// </summary>            /// <value>The name of the connection string.</value>            public string ConnectionStringName            {                get { return _ConnectionStringName; }                set { _ConnectionStringName = value; }            }        }    }    


然后修改log4net.config文件:
    <appender name="AdoNetAppender" type="AppBox.Log4NetConnectionStringNameAdoNetAppender">    <bufferSize value="0"/>    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089"/>    <connectionStringName value="Default"></connectionStringName>    ........    ........    </appender>    


注意,在log4net.config中我们指定使用名为 Default 的连接字符串。

使用log4net

调用方法倒很简单,比如在登录页面:
    private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);    protected void btnSubmit_Click(object sender, EventArgs e)    {        // ....        logger.Info(String.Format("用户 - {0} - 登录成功", tbxUserName.Text));    }    

生成log记录类似:
    2009-08-19 18:05:37,932 [11] INFO  AppBox._default [(null)] - 用户 - admin - 登录成功    





原创粉丝点击