• 程序的记事本--log4net


     你是否在遇到程序执行问题时常常百度?你是否在遇到执行错误时常常去询问别人?假设有那么是时候改变啦,对于一个Developer来说那是不专业的表现,专业的Developer都会首先查看程序的执行日志。先从日志下手。分析问题发生的原因,然后修复它。这里面最重要的就是日志,那么你也就会非常好奇,这些日志是怎样记录的呢,偷偷的告诉你通常使用的是日志管理框架。那么是不是也想在开发程序时开发出一个日志管理的模块呢,不用着急以下就来介绍下怎样做日志管理。

            就我所知如今日志管理框架有多种如 Enterprise、NLog、CLog、Log4net。当中Log4net功能强大适用于中大型的项目日志管理,NLog尽管功能较少可是它使用简单,并且支持智能感应,另外Enterprise更是强大的没的说,针对于大型系统开发。当然使用也比較困难。可是考虑到它们的使用资源及功能的强大,最后我们的项目确定了使用Log4net,所以接下来将会主要讨论Log4net的主要用法。

    一、Log4net组成及配置


            从Log4net的API文档中不难看出,事实上Log4net的开发过程还是蛮简单的,并没有想象中的那么复杂,并且在使用时仅仅须要加入对应的配置节信息然后调用存储方法就可以实现日志的存储,详细的结构例如以下图



      1.1 组成具体解释

            上图显示了Log4net的主要由五个部分组成,分别为Logger,Appenders, Filters, Layouts 和Object Renders,当中最基本的Appender命名空间中封装了日志的存储方式。也就是说通过配置Appender可以将日志输出到运行的类型中。Layout事实上是封装了数据显示的格式,通过配置Layout可以输出指定模板的数据信息,它还可以控制数据的输出类型(输出xml还是文本类型)。Object Renders非常重要,它可以控制数据的自己定义输出,log4net将会依照用户定义的标准输出日志。


      1.2 配置方法

            在使用log4net时首先须要配置日志存储方式,然后在代码中调用LogManager类的静态方法GetLog保存对象的对象的信息。

    当中配置信息能够写到config文件内,也能够自己定义一个xml文档,把详细的配置节信息写到xml文件就可以。



    二、用法


           log4net有多重存储级别,依照日志信息的情况大致分为了5类,它们各自是Error错误日志、Fatal严重错误日志、Info一般信息日志、Debug调试信息日志和Warn警告信息日志,在日志管理时能够依照日志的级别来考虑存放的方式,对于严重日志往往是系统的重大问题,此时能够考虑存到server数据库中,其他的一些日志能够考虑存储到文件里,能够提高server性能。接下来将会介绍它的几种用法。


        2.1 日志输出到DataBase

            把日志输出到数据库中也是非常多系统常常使用的日志存储方法,在小数据量的处理过程中将日志保存到数据库中是可行的,可是假设须要处理的日志数据量较大那么这样的存储方法就会减少数据库的性能。所以在存储日志时谨慎使用这样的方式,建议涉及到系统重大问题时採用此种存储方式,这样会提升数据库的性能。

    详细配置例如以下:

    1. <appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">  
    2.   <bufferSize value="1"></bufferSize>  
    3.   <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />  
    4.   <connectionString value="Data Source=.;Initial Catalog=Test;Integrated Security=True;Pooling=False" />  
    5.   <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)" />  
    6.   <parameter>  
    7.     <parameterName value="@log_date" />  
    8.     <dbType value="DateTime" />  
    9.     <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />  
    10.   </parameter>  
    11.   <parameter>  
    12.     <parameterName value="@thread" />  
    13.     <dbType value="String" />  
    14.     <size value="255" />  
    15.     <layout type="log4net.Layout.PatternLayout" value="%thread" />  
    16.   </parameter>  
    17.   <parameter>  
    18.     <parameterName value="@log_level" />  
    19.     <dbType value="String" />  
    20.     <size value="50" />  
    21.     <layout type="log4net.Layout.PatternLayout" value="%level" />  
    22.   </parameter>  
    23.   <parameter>  
    24.     <parameterName value="@logger" />  
    25.     <dbType value="String" />  
    26.     <size value="255" />  
    27.     <layout type="log4net.Layout.PatternLayout" value="%logger" />  
    28.   </parameter>  
    29.   <parameter>  
    30.     <parameterName value="@message" />  
    31.     <dbType value="String" />  
    32.     <size value="4000" />  
    33.     <layout type="log4net.Layout.PatternLayout" value="%message" />  
    34.   </parameter>  
    35. </appender>  

           另外刚開始学习的人在写入数据库时可能会有非常多问题,最基本的是不能写入数据,这主要是因为connectionType和connectionString的原因,要又一次检查改动才干够。尤其是connectionType中sqlconnection的版本号问题,假设不能成功写入数据往往就是它造成的。

       2.2 日志输出到File

          另外我们也能够将数据输出到文件里,用户能够自己定义文件输出的类型,通过datePattern标签来设置存储文件的类型及文件名称,详细例如以下配置所看到的:
    1. <log4net>  
    2.   <!--定义输出到文件里-->  
    3.     <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">  
    4.       <file value="D:" />  
    5.       <appendToFile value="true" />  
    6.       <rollingStyle value="Date" />  
    7.       <maxSizeRollBackups value="30" />  
    8.       <datePattern value="yyyy-MM-dd'.log'" />  
    9.       <staticLogFileName value="false" />  
    10.       <layout type="log4net.Layout.PatternLayout">  
    11.         <conversionPattern value="{%level}%date{MM/dd HH:mm:ss} - %message%newline" />  
    12.       </layout>  
    13.     </appender>  
    14.   <root>  
    15.     <!--文件形式记录日志-->  
    16.     <appender-ref ref="RollingLogFileAppender" />        
    17.   </root>  
    18.   
    19. </log4net>  


           此种方式在指定的文件夹下创建指定的文件,并将日志信息写入创建的文件里。


       2.3 日志输出到Console

           输出到控制台中已经不陌生,在windows操作系统中常常可以看到错误信息,这样的方式可以非常直观的告诉用户错误的情况及原因,可是这样的方式仅仅是缓存级别的。系统又一次启动时错误信息就会被删除,所以在使用此种方法时应配合着上面说到的方法来综合存储日志,增强系统的健壮性。


    1. <log4net>  
    2.   <!--定义输出到控制台命令行中-->  
    3.   <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">  
    4.     <layout type="log4net.Layout.PatternLayout">  
    5.       <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />  
    6.     </layout>  
    7.   </appender>  
    8.    <root>  
    9.        <!--控制台控制显示日志-->  
    10.     <appender-ref ref="ConsoleAppender" />      
    11.   </root>  
    12.   
    13. </log4net>  



        2.4 日志输出到Event

           上面介绍了几种经常使用的输出方式,当然log4net还有很多其它的输出方式,这里再介绍一种输出到WindowsEvent的方法。这样的方法将会把错误信息输出到Windows事件中,尽管不经常使用,但也能够作为一种日志的存储方式。
    1. <log4net>  
    2.   <!--定义输出到windows事件中-->  
    3.   <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">  
    4.     <layout type="log4net.Layout.PatternLayout">  
    5.       <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />  
    6.     </layout>  
    7.   </appender>  
    8.    <!--定义日志的输出媒介。以下定义日志以四种方式输出。也能够以下的依照一种类型或其它类型输出。-->  
    9.   <root>  
    10.     <!--Windows事件日志-->  
    11.     <appender-ref ref="EventLogAppender" />  
    12.         
    13.   </root>  
    14.   
    15. </log4net>  

     通过使用上面的配置文件可以将日志输出到指定的类型中,可是想要输出日志并不仅仅是使用上面的配置,另外须要在代码中调用方法来记录日志,详细例如以下:
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Reflection;  
    5. using System.Text;  
    6. using System.Threading.Tasks;  
    7. using log4net;  
    8. using log4net.Appender;  
    9.   
    10. [assembly: log4net.Config.XmlConfigurator(Watch = true)]  
    11. namespace ConsoleApplication1  
    12. {  
    13.     class Program  
    14.     {  
    15.         static void Main(string[] args)  
    16.         {  
    17.             ILog log = log4net.LogManager.GetLogger(typeof(Program));  
    18.             //记录错误日志  
    19.             log.Error("error"new Exception("发生了一个异常"));  
    20.             //记录严重错误  
    21.             log.Fatal("fatal"new Exception("发生了一个致命错误"));  
    22.             //记录一般信息  
    23.             log.Info("info");  
    24.             //记录调试信息  
    25.             log.Debug("debug");  
    26.             //记录警告信息  
    27.             log.Warn("warn");  
    28.             Console.WriteLine("日志记录完成。");  
    29.             Console.Read();  
    30.         }  
    31.     }  
    32. }  

          在測试时上面的全部形式的配置输出都能够使用GetLogger方法来存储存储日志信息。

       Note:代码中有这么一句:[assembly: log4net.Config.XmlConfigurator(Watch = true)](在须要使用log4net的类的namespace处)。假设没有这句就会在调试时得到例如以下留言中所说的“程序调试起来时isDebugEnable"的情况。

    三、log4net保存NHibernate日志信息

           在使用NHibernate时经常须要分析SQL语句,可是NHibernate默认的是不输出SQL Script的。那么如何才干查看它生成的SQL呢?最好还是使用下log4net吧。log4net能够输出NHibernate的执行情况,能够通过配置来实现输出全部Level的NHibernate的日志信息,详细的配置方法例如以下,这里将配置文件放到了外置的xml中。
    1. <?xml version="1.0" encoding="utf-8" ?>  
    2. <log4net debug="true">  
    3.   <appender name="rollingFile" type="log4net.Appender.RollingFileAppender,log4net">  
    4.     <param name="File" value="D:loglog.txt"/>  
    5.     <param name="AppendToFile" value="false"/>  
    6.     <param name="RollingStyle" value="Date"/>  
    7.     <param name="StaticLogFileName" value="true"/>  
    8.     <layout type="log4net.Layout.PatternLayout">  
    9.       <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />  
    10.     </layout>  
    11.   </appender>  
    12.   
    13.   <logger name="NHibernate" additivity="true">  
    14.     <level value="ERROR"/>  
    15.     <appender-ref ref="DebugAppender" />  
    16.   </logger>  
    17.   <logger name="NHibernate.SQL" additivity="true">  
    18.     <level value="DEBUG"/>  
    19.     <appender-ref ref="DebugAppender" />  
    20.   </logger>  
    21.   
    22.   <logger name="NHibernate.AdoNet.AbstractBatcher" additivity="true">  
    23.     <level value="DEBUG"/>  
    24.     <appender-ref ref="DebugAppender" />  
    25.   </logger>  
    26.   
    27.   <root>  
    28.     <!-- levels: DEBUG, INFO, WARN, ERROR, FATAL -->  
    29.     <level value="DEBUG"/>  
    30.     <level value="INFO"/>  
    31.     <level value="WARN"/>  
    32.     <level value="ERROR"/>  
    33.     <level value="FATAL "/>  
    34.     <appender-ref ref="rollingFile"/>  
    35.   </root>  
    36. </log4net>  

        这里将log4net的配置信息放到了一个单独的xml文件里。所以须要在执行时将配置信息加入到log4net的配置类中,它的配置往往在Global文件的Application_Start事件中加入配置,例如以下代码:

    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Web;  
    5. using System.Web.Security;  
    6. using System.Web.SessionState;  
    7. using Medici.Etam.Data.NHibernateSessionManagement;  
    8. using NHibernate;  
    9. using NHibernate.Context;  
    10.   
    11. namespace Medici.Etam.WebService  
    12. {  
    13.     public class Global : System.Web.HttpApplication  
    14.     {  
    15.         private static log4net.ILog logger = log4net.LogManager.GetLogger("Logger");  
    16.   
    17.         protected void Application_Start(object sender, EventArgs e)  
    18.         {  
    19.     //if the log4net is a lone file then it should be config  
    20.             log4net.XmlConfigurator.Configure(new FileInfo("D:\Code\Etam\ETAM\ETAM_Webservice_T16_V1.1\Data\log4net.cfg.xml"));          
    21.        }  
    22.   
    23.     }  
    24. }  

       

    结语

        log4net的日志存储功能非常强大。它对日志信息做了具体的分类。总共划分为5类。在存储日志的时候能够依据情况来选择性的存储,并依据级别选择存储方式。另外类似的这样的日志框架还有NLog、CLog等。能够依据具体的日志情况来选择使用日志存储的框架。

  • 相关阅读:
    写在博客前面
    JavaAPI学习(一):API && String类 && Stringbuffer && StringBuilder
    Java面向对象(七):Object类 & 内部类 & 单例模式
    Java面向对象(六):抽象方法 & 接口 & 递归
    Java面向对象(五):OOP三大特性之多态 — final 关键字
    Java面向对象(四):OOP三大特性之封装与继承
    Java面向对象(三):Java权限修饰符—static关键字
    Java面向对象(二):成员变量—OOP中的内存管理—构造函数
    Java面向对象(一):方法—初识面向对象
    JavaSE学习(六):随机数—简单的排序算法
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7285737.html
Copyright © 2020-2023  润新知