• Log4Net使用指南之用log4net记录日志到数据库(含有自定义属性)------附Demo例子源代码


    Log4NET简介

         log4net库是Apache log4j框架在Microsoft .NET平台的实现,是一个帮助程序员将日志信息输出到各种目标(控制台、文件、数据库等)的工具。

    前提

       最近做项目需要记录系统日志和用户操作日志,就想起来了log4net,但是业务需要需要加入自定义属性,并把自定义属性日志数据插入到数据库中,看好趁这个机会学习总结下。

    详细步骤

        一、首先下载:log4net.dll  下载地址:http://logging.apache.org/log4net/download_log4net.cgi

        二、在项目中进行引用。这个不多说了,相信大家都很熟悉这个过程。

        三、在web.config,加入以下代码:         

    1  <configSections>
    2     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
    3   </configSections>

         四、然后在与web.config同目录下面新建个配置文件,我这建了个log4net.config,如下图

          

        五、在log4net.config加入以下代码,里面注释和详细 ,大家可以看如下代码:

          

      1 <?xml version="1.0" encoding="utf-8"?>
      2 <configuration>
      3   <configSections>
      4     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
      5   </configSections>
      6 
      7   <log4net>
      8     <logger name="myLogger">
      9       <level value="INFO"/>
     10       <appender-ref ref="AdoNetAppender_SqlServer"/>
     11       <!--sql server数据库1-->
     12       <appender-ref ref="AdoNetAppender_SqlServer1"/>
     13       <!--sql server数据库2-->
     14       <appender-ref ref="AdoNetAppender_Sqllite"/>
     15       <!--sqlite数据库-->
     16       <appender-ref ref="InfoAppender"/>
     17       <!--记录到文件-->
     18     </logger>
     19 
     20     <!--sql server数据库1-->
     21     <appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">
     22       <!-- BufferSize 为缓冲区大小,只有日志记录超5 条才会一块写入到数据库 -->
     23       <!-- 或写为<param name="BufferSize" value="10" /> -->
     24       <bufferSize value="0"/>
     25       <!-- 引用 -->
     26       <!--2.0这是对应sql2008 如是2000或2005另外配置-->
     27       <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089"/>
     28 
     29       <!-- 连接数据库字符串 --> 
     30       <connectionString value="Data Source=.;Initial Catalog=Log;User ID=sa;Password=sa123;" />
     31       <!-- 插入到表Log -->
     32       <commandText value = "INSERT INTO Mylogger ([EVENTTYPE],[TIMESTAMP],[EVENTCATEGORY],[EVENT_ID],[COMPUTERNAME],[MAC_ADDRESS],[USERNAME],[SOURCETYPE],[SOURCE],[DESCRIPTION],[COLLECTDATE]) VALUES (@Event_Type,@log_date, @EventCategory, @Event_ID, @ComputerName,@Mac_Address,@UserName,@SourceType,@Source,@Description,@CollectDate) "/>
     33 
     34       <!-- 日志类型,这里均为3 -->
     35       <parameter>
     36         <parameterName value = "@Event_Type"/>
     37         <dbType value = "Int32"/>
     38         <!--<dbType value = "String"/>
     39         <size value = "50"/>-->
     40         <!-- LogComponent 是类所在的命名空间,MyLayout 是自定义属性所在的类,这是我们自己要写的部分,将在下面介绍。 -->
     41         <layout type = "Log4netExpand.MyLayout,log4nettest">
     42           <!-- 当用到property 时,就表明这是用户自定义的字段属性啦,是log4net 中所没有提供的字段。 -->
     43           <conversionPattern value = "%property{Event_Type} "/>
     44         </layout>
     45       </parameter>
     46 
     47       <!-- 日志记录时间,RawTimeStampLayout 为默认的时间输出格式 -->
     48       <parameter>
     49         <parameterName value = "@log_date"/>
     50         <dbType value = "DateTime"/>
     51         <layout type = "log4net.Layout.RawTimeStampLayout"/>
     52         <!-- /这里呢是获取log4net 中提供的日志时间 -->
     53       </parameter>
     54 
     55       <!-- 日志分类描述 -->
     56       <parameter>
     57         <parameterName value = "@EventCategory"/>
     58         <dbType value = "String"/>
     59         <size value = "50"/>
     60         <layout type = "Log4netExpand.MyLayout,log4nettest">
     61           <conversionPattern value = "%property{EventCategory}"/>
     62         </layout>
     63       </parameter>
     64 
     65       <!-- 日志分类号 -->
     66       <parameter>
     67         <parameterName value = "@Event_ID"/>
     68         <dbType value = "Int32"/>
     69         <layout type = "Log4netExpand.MyLayout,log4nettest">
     70           <conversionPattern value = "%property{Event_ID}"/>
     71         </layout>
     72       </parameter>
     73 
     74       <!-- 计算机IP -->
     75       <parameter>
     76         <parameterName value = "@ComputerName"/>
     77         <dbType value = "String"/>
     78         <size value = "50"/>
     79         <layout type = "Log4netExpand.MyLayout,log4nettest">
     80           <conversionPattern value = "%property{ComputerName}"/>
     81         </layout>
     82       </parameter>
     83 
     84       <!-- 计算机Mac 信息 -->
     85       <parameter>
     86         <parameterName value = "@Mac_Address"/>
     87         <dbType value = "String"/>
     88         <size value = "50 "/>
     89         <layout type = "Log4netExpand.MyLayout, log4nettest">
     90           <conversionPattern value = "%property{Mac_Address}"/>
     91         </layout>
     92       </parameter>
     93 
     94       <!-- 登陆系统用户名 -->
     95       <parameter>
     96         <parameterName value = "@UserName"/>
     97         <dbType value = "String"/>
     98         <size value = "50"/>
     99         <layout type = "Log4netExpand.MyLayout,log4nettest">
    100           <conversionPattern value = "%property{UserName}"/>
    101         </layout>
    102       </parameter>
    103 
    104       <!-- 事件来源类型,这里默认为Rier -->
    105       <parameter>
    106         <parameterName value = "@SourceType"/>
    107         <dbType value = "String"/>
    108         <size value = "20"/>
    109         <layout type = "Log4netExpand.MyLayout,log4nettest">
    110           <conversionPattern value = "%property{SourceType}"/>
    111         </layout>
    112       </parameter>
    113 
    114       <!-- 事件来源 -->
    115       <parameter>
    116         <parameterName value = "@Source "/>
    117         <dbType value = "String"/>
    118         <size value = "50"/>
    119         <layout type = "Log4netExpand.MyLayout,log4nettest">
    120           <conversionPattern value = "%property{Source}"/>
    121         </layout>
    122       </parameter>
    123 
    124       <!-- 事件描述 -->
    125       <parameter>
    126         <parameterName value = "@Description "/>
    127         <dbType value = "String"/>
    128         <size value = "4000"/>
    129         <layout type = "Log4netExpand.MyLayout, log4nettest">
    130           <conversionPattern value = "%property{Description}"/>
    131         </layout>
    132       </parameter>
    133 
    134       <!-- 日志收集时间 -->
    135       <parameter>
    136         <parameterName value = "@CollectDate"/>
    137         <dbType value = "DateTime"/>
    138         <layout type="log4net.Layout.RawTimeStampLayout" />
    139       </parameter>
    140     </appender>
    141 
    142     <!--记录到文件-->
    143     <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
    144       <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    145 
    146       <param name="File" value="Log\INFO\"/>
    147       <param name="AppendToFile" value="true"/>
    148       <param name="MaxFileSize" value="10240" />
    149       <param name="MaxSizeRollBackups" value="100"/>
    150       <param name="StaticLogFileName" value="false"/>
    151       <param name="DatePattern" value="yyyyMMdd&quot;.txt&quot;"/>
    152       <param name="RollingStyle" value="Date"/>
    153       <layout type="log4net.Layout.PatternLayout">
    154         <param name="ConversionPattern" value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 记录类:%logger 操作者ID:%property{Operator} 操作类型:%property{Action}%n 当前机器名:%property%n当前机器名及登录用户:%username %n               记录位置:%location%n 消息描述:%property{Message}%n 异常:%exception%n 消息:%message%newline%n%n" />
    155       </layout>
    156     </appender>
    157 
    158     <!--sql server数据库2-->
    159     <appender name="AdoNetAppender_SqlServer1" type="log4net.Appender.AdoNetAppender">
    160       <bufferSize value="0"/>
    161       <!--2.0这是对应sql2008 如是2000或2005另外配置-->
    162       <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089"/>
    163 
    164       <!-- 连接数据库字符串 -->
    165       <connectionString value="Data Source=.;Initial Catalog=Log;User ID=sa;Password=sa123;" />
    166 
    167       <!-- 插入到表Log -->
    168       <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message,@exception)"/>
    169 
    170       <parameter>
    171         <parameterName value="@log_date"/>
    172         <dbType value="DateTime"/>
    173 
    174         <layout type="log4net.Layout.PatternLayout">
    175           <conversionPattern value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />
    176         </layout>
    177         <!-- <layout type="log4net.Layout.RawTimeStampLayout"/>-->
    178       </parameter>
    179       <parameter>
    180         <parameterName value="@thread"/>
    181         <dbType value="String"/>
    182         <size value="255"/>
    183         <!-- LogComponent 是类所在的命名空间,MyLayout 是自定义属性所在的类,这是我们自己要写的部分,将在下面介绍。 -->
    184         <layout type="log4net.Layout.PatternLayout">
    185           <conversionPattern value="%thread"/>
    186         </layout>
    187       </parameter>
    188       <parameter>
    189         <parameterName value="@log_level"/>
    190         <dbType value="String"/>
    191         <size value="50"/>
    192         <layout type="log4net.Layout.PatternLayout">
    193           <conversionPattern value="%level"/>
    194         </layout>
    195       </parameter>
    196       <parameter>
    197         <parameterName value="@logger"/>
    198         <dbType value="String"/>
    199         <size value="255"/>
    200         <layout type="log4net.Layout.PatternLayout">
    201           <conversionPattern value="%logger"/>
    202         </layout>
    203       </parameter>
    204       <parameter>
    205         <parameterName value="@message"/>
    206         <dbType value="String"/>
    207         <size value="4000"/>
    208         <layout type="log4net.Layout.PatternLayout">
    209           <conversionPattern value="%message"/>
    210         </layout>
    211       </parameter>
    212       <parameter>
    213         <parameterName value="@exception" />
    214         <dbType value="String" />
    215         <size value="2000" />
    216         <layout type="log4net.Layout.ExceptionLayout" />
    217       </parameter>
    218     </appender>
    219 
    220     <!--sqlite数据库-->
    221     <appender name="AdoNetAppender_Sqllite" type="log4net.Appender.AdoNetAppender">
    222       <bufferSize value="0"/>
    223       <!--2.0这是对应sql2008 如是2000或2005另外配置-->
    224       <!--<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089"/>-->
    225       <connectionType value="System.Data.SQLite.SQLiteConnection, System.Data.SQLite, Version=1.0.66.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
    226       <!-- 连接数据库字符串 -->
    227       <!--<connectionString value="Data Source=.;Initial Catalog=Log;User ID=sa;Password=123;" />-->
    228       <connectionString value="C:\Users\Administrator\Desktop\log4net\Log4netExpand\Test.db3;" />
    229       <!-- 插入到表Log -->
    230       <commandText value="INSERT INTO MAIN.[Log] ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message,@exception)"/>
    231 
    232       <parameter>
    233         <parameterName value="@log_date"/>
    234         <dbType value="DateTime"/>
    235 
    236         <layout type="log4net.Layout.PatternLayout">
    237           <conversionPattern value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />
    238         </layout>
    239         <!-- <layout type="log4net.Layout.RawTimeStampLayout"/>-->
    240       </parameter>
    241       <parameter>
    242         <parameterName value="@thread"/>
    243         <dbType value="String"/>
    244         <!--<size value="255"/>-->
    245         <!-- LogComponent 是类所在的命名空间,MyLayout 是自定义属性所在的类,这是我们自己要写的部分,将在下面介绍。 -->
    246         <layout type="log4net.Layout.PatternLayout">
    247           <conversionPattern value="%thread"/>
    248         </layout>
    249       </parameter>
    250       <parameter>
    251         <parameterName value="@log_level"/>
    252         <dbType value="String"/>
    253         <!--<size value="50"/>-->
    254         <layout type="log4net.Layout.PatternLayout">
    255           <conversionPattern value="%level"/>
    256         </layout>
    257       </parameter>
    258       <parameter>
    259         <parameterName value="@logger"/>
    260         <dbType value="String"/>
    261         <!--<size value="255"/>-->
    262         <layout type="log4net.Layout.PatternLayout">
    263           <conversionPattern value="%logger"/>
    264         </layout>
    265       </parameter>
    266       <parameter>
    267         <parameterName value="@message"/>
    268         <dbType value="String"/>
    269         <!--<size value="4000"/>-->
    270         <layout type="log4net.Layout.PatternLayout">
    271           <conversionPattern value="%message"/>
    272         </layout>
    273       </parameter>
    274       <parameter>
    275         <parameterName value="@exception" />
    276         <dbType value="String" />
    277         <!--<size value="2000" />-->
    278         <layout type="log4net.Layout.ExceptionLayout" />
    279       </parameter>
    280     </appender>
    281   </log4net>
    282 
    283   <system.web>
    284     <compilation debug="true" targetFramework="4.0" />
    285   </system.web>
    286 
    287 </configuration>

           我主要说下里面自定义属性的代码的分别代表意义:

     <parameter>
     96         <parameterName value = "@UserName"/>
     97         <dbType value = "String"/>
     98         <size value = "50"/>
     99         <layout type = "Log4netExpand.MyLayout,log4nettest">
    100           <conversionPattern value = "%property{UserName}"/>
    101         </layout>
    102       </parameter>
    

               其中MyLayout,是我们自己定义的类,下面有介绍;Log4netExpand是这个类的命名空间;log4nettest这个代表是aspx页面的命名空间。注意在此区分。

          六、自定义类,这些类呢包含将要插入数据库中的自定义字段

                 命名空间为 Log4netExpand包含3个类:LogContent.cs、 MyLayout.cs 、MyMessagePatternConverter .cs

            1)第一个LogContent类如下:

                

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace Log4netExpand
    {
        /// <summary>
        /// 包含了所有的自定字段属性
        /// </summary>
        public class LogContent
        {
            /// <summary>
            /// 时间类型 均为3
            /// </summary>
            public int Event_Type { get; set; }
    
            /// <summary>
            /// 日志分类描述,自定义
            /// </summary>
            public string EventCategory { get; set; }
    
    
            /// <summary>
            /// 日志分类号
            /// </summary>
            public int Event_ID { get; set; }
    
            /// <summary>
            /// 计算机IP
            /// </summary>
            public string ComputerName { get; set; }
    
            /// <summary>
            /// 计算机Mac 地址
            /// </summary>
            public string Mac_Address { get; set; }
    
            /// <summary>
            /// 系统登陆用户
            /// </summary>
            public string UserName { get; set; }
    
            /// <summary>
            /// Rier
            /// </summary>
            public string SourceType { get; set; }
    
            /// <summary>
            /// Rier Recorder audit
            /// </summary>
            public string Source { get; set; }
    
            /// <summary>
            /// 日志描述信息
            /// </summary>
            public string Description { get; set; }
    
        }
    }

         2)第二个类MyLayout代码如下:

           

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Web;
     5 using log4net.Layout;
     6 
     7 namespace Log4netExpand
     8 {
     9     class MyLayout : PatternLayout
    10     {
    11         public MyLayout()
    12         {
    13             this.AddConverter("property", typeof(MyMessagePatternConverter));
    14         }
    15     }
    16 }

          3)第三个类MyMessagePatternConverter 代码如下:

            

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Web;
     5 using System.Reflection;
     6 using log4net.Layout.Pattern;
     7 
     8 namespace Log4netExpand
     9 {
    10     public class MyMessagePatternConverter : PatternLayoutConverter
    11     {
    12 
    13         protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent)
    14         {
    15 
    16             if (Option != null)
    17             {
    18 
    19                 // Write the value for the specified key
    20 
    21                 WriteObject(writer, loggingEvent.Repository, LookupProperty(Option, loggingEvent));
    22 
    23             }
    24 
    25             else
    26             {
    27 
    28                 // Write all the key value pairs
    29 
    30                 WriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties());
    31 
    32             }
    33 
    34             //if (Option != null)
    35 
    36             //{
    37 
    38             //    // Write the value for the specified key
    39 
    40             //    WriteObject(writer, loggingEvent.Repository, loggingEvent.LookupProperty(Option));
    41 
    42             //}
    43 
    44             //else
    45 
    46             //{
    47 
    48             //    // Write all the key value pairs
    49 
    50             //    WriteDictionary(writer, loggingEvent.Repository, loggingEvent.GetProperties());
    51 
    52             //}
    53 
    54         }
    55 
    56 
    57 
    58         /// <summary>
    59 
    60         /// 通过反射获取传入的日志对象的某个属性的值
    61 
    62         /// </summary>
    63 
    64         /// <param name="property"></param>
    65 
    66         /// <returns></returns>
    67 
    68         private object LookupProperty(string property, log4net.Core.LoggingEvent loggingEvent)
    69         {
    70 
    71             object propertyValue = string.Empty;
    72 
    73 
    74 
    75             PropertyInfo propertyInfo = loggingEvent.MessageObject.GetType().GetProperty(property);
    76 
    77             if (propertyInfo != null)
    78 
    79                 propertyValue = propertyInfo.GetValue(loggingEvent.MessageObject, null);
    80 
    81 
    82 
    83             return propertyValue;
    84 
    85         }
    86 
    87     }
    88 }

          七、代码页,实现通过log4net把日志(含自定一生属性)添加到数据库

          

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Web;
     5 using System.Web.UI;
     6 using System.Web.UI.WebControls;
     7 
     8 using System.Management;
     9 using Log4netExpand;
    10 
    11 namespace Log4netExpand
    12 {
    13     public partial class test : System.Web.UI.Page
    14     {
    15         protected void Page_Load(object sender, EventArgs e)
    16         {
    17 
    18         }
    19         protected void Button1_Click(object sender, EventArgs e)
    20         {
    21             log4net.ILog log = log4net.LogManager.GetLogger("myLogger");
    22 
    23             LogContent logmodel = new LogContent();
    24             logmodel.Event_Type = 3;
    25             logmodel.EventCategory = "登陆系统";
    26             logmodel.Event_ID = 1;
    27             logmodel.ComputerName = Request.UserHostAddress;
    28             logmodel.Mac_Address = GetMacAddress();
    29             logmodel.Source = "SS";
    30             logmodel.SourceType = "1";
    31             logmodel.UserName = "ADMIN";
    32             logmodel.Description = "TEST";//在记录数据库操作时,可以在petapoco底层将sql语句放入其中。          
    33             LogHelper.WriteLog(logmodel);
    34 
    35             lbMsg.Text = "数据记录成功!";
    36         }
    37 
    38         public string GetMacAddress()
    39         {
    40             string mac = "";
    41             try
    42             {
    43                 //获取网卡硬件地址 
    44                 ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
    45                 ManagementObjectCollection moc = mc.GetInstances();
    46 
    47                 List<string> list = new List<string>();
    48 
    49                 foreach (ManagementObject mo in moc)
    50                 {
    51                     if ((bool)mo["IPEnabled"] == true)
    52                     {
    53                         mac = mo["MacAddress"].ToString();
    54 
    55                         list.Add(mac);
    56                     }
    57                 }
    58                 moc = null;
    59                 mc = null;
    60 
    61                 mac = list[list.Count - 1];
    62 
    63                 return mac;
    64             }
    65             catch
    66             {
    67                 return "unknow";
    68             }
    69         }
    70     }
    71 }

     代码例子源代码: Demo下载

  • 相关阅读:
    Java基础00-模块36
    Java基础00-反射35
    Java基础00-Stream流34
    Java基础00-函数式接口33
    Java基础00-方法引用32
    运用龙格库塔法解大雷洛数平板绕流问题
    LB 学习日记
    Numba学习日记 —— 2019-12-5
    文件的操作及相关异常的处理
    time模块的两个函数time.clock()和time.time()的区别
  • 原文地址:https://www.cnblogs.com/dyhdream/p/4838647.html
Copyright © 2020-2023  润新知