zoukankan      html  css  js  c++  java
  • ExtAspNet应用技巧(八) log4net配置与使用

    前言

    为了实践项目驱动的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 - 登录成功
        





  • 相关阅读:
    hibernate的核心配置
    hibernate的映射配置
    数据库的维护
    索引
    数据库规范化设计
    数据控制DCL
    触发器
    SQL存储过程简介
    Transact-SQL简介
    sysdatabaes表与sysobjects表
  • 原文地址:https://www.cnblogs.com/sanshi/p/1550092.html
Copyright © 2011-2022 走看看