zoukankan      html  css  js  c++  java
  • Log4Net添加自定义日志信息到数据库 [转帖]

    一、     前言

    该文章是针对在Log4Net中添加自定义日志信息。我们在写日志的时候并不是只写消息(Message,有些情况需要记录自定义的日志信息等。下面将说明在Log4Net中增加自定义字段UserName(用户名),Category(类别)这两个字段。

    二、     建立数据库
    CREATE TABLE [dbo].[Log] (
        [Id] [int] IDENTITY (11) 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 ,
        [User] [varchar] (50) NULL ,
        [Category] [varchar] (50)  NULL 

    其中Date,Thread,Level,Logger,Message,Exceptionlog4net内置的信息。UserCategory是自定义的字段。

    三、     编写配置文件

    <configuration>
        <configSections>
            <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
        </configSections>
        <log4net>
            <logger name="AA">
                <level value="All" />
                <appender-ref ref="ADONetAppender" />
            </logger>
        <!--<root>
                <level value="All" />
          <appender-ref ref="ADONetAppender" /> 
            </root>-->
            <appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
                <!--BufferSize为缓冲区大小-->
                <param name="BufferSize" value="1" />
          <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
          <connectionString value="database=aa;server=(local);User ID=sa;Password=;" />
          <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception],[User],[Category]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception,@User,@Category)" />
          <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>
          <parameter>
            <parameterName value="@User" />
            <dbType value="String" />
            <size value="50" />
            <layout type="Log4NetToDatabase.CustomLayout">
              <conversionPattern value="%UserName" />
            </layout>
          </parameter>
          <parameter>
            <parameterName value="@Category" />
            <dbType value="String" />
            <size value="50" />
            <layout type="Log4NetToDatabase.CustomLayout">
              <conversionPattern value="%Category" />
            </layout>
          </parameter>
        </appender>
      </log4net>
    </configuration>

    配置文件说明:该配置文件在应用程序项目中的App.config配置文件中编写。配置文件中的Log4NetToDatabase.CustomLayout为自定义类的名称,具体实现请关注编写代码。配置文件中如果将<root>节点的注释打开则会产生两条同样的信息,因为在<root>节点中有一个appender-ref子节点,它也引用了ADONetAppender附着器。由于<logger>节点已经引用了ADONetAppender附着器,并且加载它。我个人怀疑<root>节点的内容为自动加载,所以会连续产生两条同样的信息。解决该问题只要将<Root>节点注释,或将<root>节点中的<appender-ref>子节点注释就解决了。

    一、     编写代码

    1.     编写自定义PatternLayoutConverter

    View Code
     1 internal sealed class UserNamePatternConverter : PatternLayoutConverter 
     2 {
     3     override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
     4     {
     5         LogMessage logMessage = loggingEvent.MessageObject as LogMessage;
     6         if (logMessage != null)
     7             // 将UserName作为日志信息输出
     8             writer.Write(logMessage.UserName);
     9    }
    10 }
    11 internal sealed class CategoryPatternConverter : PatternLayoutConverter
    12 {
    13     override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
    14     {
    15         LogMessage logMessage = loggingEvent.MessageObject as LogMessage;
    16         if (logMessage != null)
    17             writer.Write(logMessage.Category);
    18     }
    19 }

    2.     编写自定义日志输出类

    View Code
     1 public class LogMessage
     2     {
     3         private string m_UserName;
     4         private string m_Category;
     5         public LogMessage()
     6         {
     7         }
     8         public LogMessage(string userName, string category)
     9         {
    10             m_UserName = userName;
    11             m_Category = category;
    12         }
    13         public string UserName
    14         {
    15             get
    16             {
    17                 return m_UserName;
    18             }
    19             set
    20             {
    21                 m_UserName = value;
    22             }
    23         }
    24         public string Category
    25         {
    26             get
    27             {
    28                 return m_Category;
    29             }
    30             set
    31             {
    32                 m_Category = value;
    33             }
    34         }
    35     }


     

    3.     编写由log4net.Layout.LayoutSkeleton继承的类CustomLayout

    由于内容过多,将在附件中给出源代码。

    在此对该类做一些说明:

    如果要添加自定义的字段,可以在静态构造函数static CustomLayout()中加入s_globalRulesRegistry.Add("UserName", typeof(UserNamePatternConverter));其中UserNamePatternConverter是继承于PatternLayoutConverter的类。注册完之后就可以在配置文件中使用%UserName使用了。在此只要做这些修改就能使用了,其它的代码如果有趣,可以一起交流。

    4.     加载配置文件并记录日志

    AssemblyInfo.cs文件中添加[assembly: XmlConfigurator()]。它的作用同于log4net.Config.XmlConfigurator.Configure();用来读取配置文件信息。

    log4net.ILog log;

    form1中添加下列代码:

    View Code
    private static int count = 0;
            public Form1()
            {
                InitializeComponent();
                    // 如果配置文件中存在名称为AA的logger,则加载
                log = LogManager.Exists("AA");        
    }
            private void button1_Click(object sender, EventArgs e)
            {
                ++count;
                LogMessage message = new LogMessage();
                message.UserName = "xds"+count.ToString();
                message.Category = count.ToString();
                    // 输出日志信息
                log.Error(message);
            }

    解决方案二:

    与上面的方案只需做以下的更改:将CustomLayout类继承自log4net.Layout.PatternLayout并在构造函数中调用AddConverter()方法。该方法将占用较多的系统内存,但它代码简单易于理解。它的代码如下:

    View Code
    1 public class CustomLayout : log4net.Layout.PatternLayout
    2     {
    3         public CustomLayout2()
    4         {
    5             this.AddConverter("UserName"typeof(UserNamePatternConverter));
    6             this.AddConverter("Category"typeof(CategoryPatternConverter));
    7         }
    8 }


    转自:http://www.cnblogs.com/xds/archive/2007/03/06/665124.html

  • 相关阅读:
    php面向对象三大特性
    php面向对象的重写与重载
    一组成对的数字,找出不成对的数字
    如何创建dll以及使用
    常见运行时错误
    连续数的和
    绕圆圈取球
    第一章 概述
    错误2038
    一个简单的环境光shader
  • 原文地址:https://www.cnblogs.com/yourancao520/p/2249846.html
Copyright © 2011-2022 走看看