zoukankan      html  css  js  c++  java
  • log4net使用

    log4net解决的问题是提供一个记录日志的框架,它提供了向多种目标写入的实现,比如利用log4net可以方便地将日志信息记录到文件、控制台、Windows事件日志和数据库(包括MS SQL Server, Access, Oracle9i,Oracle8i,DB2,SQLite)中,一般来说我们只需要提供一个描述性的字符串,然后log4net就会自动提供有关运行时的一些信息。
    Log4Net的版本仍是1.2.10(2008年我写博文的时候也是这个版本),有.NET1.0和.NET1.1和.NET2.0版本,如果有正在使用高于.NET2.0开发的也不用担心,可以直接引用这个类库,像在.NET2.0中开发一样,它的网址是:http://logging.apache.org/log4net
     
    关于在Web中支持的问题
    在我们开发项目时都会使用到config文件,可以在config文件中配置log4net。这一点Web项目和WinForm项目都是一样的。需要注意的是,因为在Web项目中一般以较低权限的角色来运行Web项目的,所以在使用文件型日志时要注意不要放在本项目根文件夹之外。
    在config文件中的配置
    要使用log4net,首先要在config文件的<configSections>节点中增加配置(如果没有这个节点请手动增加),如下:
     
    1. <configSections> 
    2.   <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>(注意这段代码节点在configSections下,如果在sectionGroup下会认不到)
    3. </configSections> 
    除此之外,还要在顶级节点<configuration>下增加<log4net>子节点。
     

     <log4net>
        <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
          <file value="LogFile.txt" />
          <appendToFile value="true" />
          <maximumFileSize value="100KB" />
          <maxSizeRollBackups value="2" />
          <layout type="log4net.Layout.PatternLayout">
            <!--<param name="Header" value="◇" />
            <param name="Footer" value="◆" />-->
            <param name="ConversionPattern" value="记录时间:%date 线程ID:[%thread] 日志级别:文件:所在行%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline"/>
          </layout>
        </appender>
        <root>
          <level value="ALL" />
          <appender-ref ref="RollingLogFileAppender" />
        </root>

        <logger name="WebService">
          <level value="ALL" />
        </logger>
      </log4net>

    在<log4net>节点下就可以增加<appender>子节点,每个<appender>子节点代表一种记录日志的方式(仅在这里配置了不代表启用了)。
    具体说来有如下Appender:
    AdoNetAppender:利用ADO.NET记录到数据库的日志。
    AnsiColorTerminalAppender:在ANSI 窗口终端写下高亮度的日志事件。
    AspNetTraceAppender:能用asp.net中Trace的方式查看记录的日志。
    BufferingForwardingAppender:在输出到子Appenders之前先缓存日志事件。
    ConsoleAppender:将日志输出到控制台。
    EventLogAppender:将日志写到Windows Event Log.
    FileAppender:将日志写到文件中。
    LocalSyslogAppender:将日志写到local syslog service (仅用于UNIX环境下).
    MemoryAppender:将日志存到内存缓冲区。
    NetSendAppender:将日志输出到Windows Messenger service.这些日志信息将在用户终端的对话框中显示。
    RemoteSyslogAppender:通过UDP网络协议将日志写到Remote syslog service。
    RemotingAppender:通过.NET Remoting将日志写到远程接收端。
    RollingFileAppender:将日志以回滚文件的形式写到文件中。
    SmtpAppender:将日志写到邮件中。
    TraceAppender:将日志写到.NET trace 系统。
    UdpAppender:将日志connectionless UDP datagrams的形式送到远程宿主或以UdpClient的形式广播。
    关于使用log4net中可能会使用到的一些参数
    %m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息
    %n(new line):换行
    %d(datetime):输出当前语句运行的时刻
    %r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数
    %t(thread id):当前语句所在的线程ID
    %p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等
    %c(class):当前日志对象的名称,例如:
    %f(file):输出语句所在的文件名。
    %l(line):输出语句所在的行号。
    %数字:表示该项的最小长度,如果不够,则用空格填充,如“%-5level”表示level的最小宽度是5个字符,如果实际长度不够5个字符则以空格填充。
    下面以一个实际的例子来说明问题,比如在配置中有“%date [%thread] (%file:%line) %-5level %logger [%property{NDC}] - %message%newline”,那么实际的日志中会是如下格式:
    “记录时间:2010-11-17 16:16:36,561 线程ID:[9] 日志级别:文件:所在行ERROR 出错类:Log4NetDemo.Program property:[(null)] - 错误描述:error
    System.Exception: 在这里发生了一个异常,Error Number:2036084948”
    关于对数据库的支持
    前面已经说过,log4net是支持包括MS SQL Server, Access, Oracle9i,Oracle8i,DB2,SQLite在内的数据库的,如果是文件型数据库(如Access或SQLite)的话就需要指定数据库文件的位置(在Web中最好指定在有读写权限的文件夹下,并且实现创建好表),如果是网络数据库就需要指定正确的数据库连接字符串。
    比如要记录到Oracle数据库中,在配置文件中可以增加一个< appender>节点,配置如下:
     
    1. <appender name="AdoNetAppender_Oracle" type="log4net.Appender.AdoNetAppender"> 
    2.       <connectionType value="System.Data.OracleClient.OracleConnection, System.Data.OracleClient" /> 
    3.       <connectionString value="data source=[mydatabase];User ID=[user];Password=[password]" /> 
    4.       <commandText value="INSERT INTO Log (Datetime,Thread,Log_Level,Logger,Message) VALUES (:log_date, :thread, :log_level, :logger, :message)" /> 
    5.       <bufferSize value="128" /> 
    6.       <parameter> 
    7.         <parameterName value=":log_date" /> 
    8.         <dbType value="DateTime" /> 
    9.         <layout type="log4net.Layout.RawTimeStampLayout" /> 
    10.       </parameter> 
    11.       <parameter> 
    12.         <parameterName value=":thread" /> 
    13.         <dbType value="String" /> 
    14.         <size value="255" /> 
    15.         <layout type="log4net.Layout.PatternLayout"> 
    16.           <conversionPattern value="%thread" /> 
    17.         </layout> 
    18.       </parameter> 
    19.       <parameter> 
    20.         <parameterName value=":log_level" /> 
    21.         <dbType value="String" /> 
    22.         <size value="50" /> 
    23.         <layout type="log4net.Layout.PatternLayout"> 
    24.           <conversionPattern value="%level" /> 
    25.         </layout> 
    26.       </parameter> 
    27.       <parameter> 
    28.         <parameterName value=":logger" /> 
    29.         <dbType value="String" /> 
    30.         <size value="255" /> 
    31.         <layout type="log4net.Layout.PatternLayout"> 
    32.           <conversionPattern value="%logger" /> 
    33.         </layout> 
    34.       </parameter> 
    35.       <parameter> 
    36.         <parameterName value=":message" /> 
    37.         <dbType value="String" /> 
    38.         <size value="4000" /> 
    39.         <layout type="log4net.Layout.PatternLayout"> 
    40.           <conversionPattern value="%message" /> 
    41.         </layout> 
    42.       </parameter> 
    43.     </appender> 
    当然从上面的配置中的SQL语句中可以看得出这个表的参数,日志表的创建语句如下:
     
    1. create table log (  
    2.    Datetime timestamp(3),  
    3.    Thread varchar2(255),  
    4.    Log_Level varchar2(255),  
    5.    Logger varchar2(255),  
    6.    Message varchar2(4000)  
    7.    ); 
     

    在本例中周公采用了将日志记录到SQLite这个单机数据库的方式,并且还将记录记录日志时的文件名和行号,创建SQLite的SQL语句如下:

    1. CREATE TABLE Log (  
    2.     LogId        INTEGER PRIMARY KEY,  
    3.     Date        DATETIME NOT NULL,  
    4.     Level        VARCHAR(50) NOT NULL,  
    5.     Logger        VARCHAR(255) NOT NULL,  
    6.     Source        VARCHAR(255) NOT NULL,  
    7.     Message        TEXT DEFAULT NULL 
    8.     ); 

    增加的< appender>节点配置如下:

    1. <appender name="AdoNetAppender_SQLite" type="log4net.Appender.AdoNetAppender"> 
    2.   <bufferSize value="100" /> 
    3.   <connectionType value="System.Data.SQLite.SQLiteConnection, System.Data.SQLite, Version=1.0.66.0, Culture=neutral" /> 
    4.   <!--SQLite连接字符串--> 
    5.   <connectionString value="Data Source=c:\\log4net.db;Version=3;" /> 
    6.   <commandText value="INSERT INTO Log (Date, Level, Logger,Source, Message) VALUES (@Date, @Level, @Logger, @Source, @Message)" /> 
    7.   <parameter> 
    8.     <parameterName value="@Date" /> 
    9.     <dbType value="DateTime" /> 
    10.     <layout type="log4net.Layout.RawTimeStampLayout" /> 
    11.   </parameter> 
    12.   <parameter> 
    13.     <parameterName value="@Level" /> 
    14.     <dbType value="String" /> 
    15.     <layout type="log4net.Layout.PatternLayout"> 
    16.       <conversionPattern value="%level" /> 
    17.     </layout> 
    18.   </parameter> 
    19.   <parameter> 
    20.     <parameterName value="@Logger" /> 
    21.     <dbType value="String" /> 
    22.     <layout type="log4net.Layout.PatternLayout"> 
    23.       <conversionPattern value="%logger" /> 
    24.     </layout> 
    25.   </parameter> 
    26.   <parameter> 
    27.     <parameterName value="@Source" /> 
    28.     <dbType value="String" /> 
    29.     <layout type="log4net.Layout.PatternLayout"> 
    30.       <conversionPattern value="%file:%line" /> 
    31.     </layout> 
    32.   </parameter> 
    33.   <parameter> 
    34.     <parameterName value="@Message" /> 
    35.     <dbType value="String" /> 
    36.     <layout type="log4net.Layout.PatternLayout"> 
    37.       <conversionPattern value="%message" /> 
    38.     </layout> 
    39.   </parameter> 
    40. </appender> 
    从上面的配置中可以看出插入数据的SQL语句及参数信息,下面的<parameter>节点就是指定插入的数据,比如我们指定SQL语句中的"@Source"参数来源于log4net中的"%file:%line"参数,也就是这两个参数用“:”用连接起来。
    控制日志文件大小的问题
    对于一个长时间使用并且有大量业务日志的系统来说,如果使用FileAppender将日志一直记录到一个文件中会引起性能低下的问题,我曾见过有个系统的日志文件达到了800多M,最后系统无法及时响应了,在这种情况下可考虑使用RollingFileAppender循环记录日志,一种是指定文件的最大长度,如果超过了就重新生成一个文件,如下面的配置:
     
    1. <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> 
    2.   <file value="RollingFileAppender_log.txt" /> 
    3.   <appendToFile value="true" /> 
    4.   <rollingStyle value="Size" /> 
    5.   <maxSizeRollBackups value="10" /> 
    6.   <maximumFileSize value="100KB" /> 
    7.   <staticLogFileName value="true" /> 
    8.   <layout type="log4net.Layout.PatternLayout"> 
    9.     <conversionPattern value="%date [%thread] (%file:%line) %-5level %logger [%property{NDC}] - %message%newline" /> 
    10.   </layout> 
    11. </appender> 
    在上面的配置中,每个日志文件最大100KB,最大日志文件个数是10生成的日志文件名会是RollingFileAppender_log.txt.1, RollingFileAppender_log.txt.2 ... RollingFileAppender_log.txt.10,如果记录的日志超过10个,会从RollingFileAppender_log.txt.1开始覆盖。
    还有一种方式就是按照日期记录日志,它的配置如下:
     
    1. <appender name="RollingLogFileAppender_DateFormat" type="log4net.Appender.RollingFileAppender"> 
    2.   <file value="RollingLogFileAppender_DateFormat_log.txt" /> 
    3.   <appendToFile value="true" /> 
    4.   <rollingStyle value="Date" /> 
    5.   <!--<datePattern value="yyyyMMdd-HHmm" />--> 
    6.   <datePattern value="yyyyMMdd" /> 
    7.   <layout type="log4net.Layout.PatternLayout"> 
    8.     <conversionPattern value="%date [%thread](%file:%line) %-5level %logger [%property{NDC}] - %message%newline" /> 
    9.   </layout> 
    10. </appender> 
    这样一来,每天的日志都写入到一个文件中,当天的日志文件名为“RollingLogFileAppender_DateFormat_log.txt”,非当天的日志都会带上当天的日期,如“RollingLogFileAppender_DateFormat_log.txt20101117”表示2010年11月17日的日志,这样就可以很方便地区分每天的日志了,将来查找起来也相当方便。
    在配置中启用和关闭日志
    在config文件中可以很方便地关闭和启用日志,就是在<root>进行配置,如下就是一个例子:
     
    1. <root> 
    2.   <!--文件形式记录日志--> 
    3.   <appender-ref ref="LogFileAppender" /> 
    4.   <!--控制台控制显示日志--> 
    5.   <appender-ref ref="ConsoleAppender" /> 
    6.   <!--Windows事件日志--> 
    7.   <!--<appender-ref ref="EventLogAppender" />--> 
    8.   <!--SQLite事件日志--> 
    9.   <appender-ref ref="AdoNetAppender_SQLite" /> 
    10.   <!--RollingFileAppender事件日志--> 
    11.   <appender-ref ref="RollingFileAppender" /> 
    12.   <!--RollingFileAppender事件日志,每天一个日志--> 
    13.   <appender-ref ref="RollingLogFileAppender_DateFormat" /> 
    14.   <!-- 如果不启用相应的日志记录,可以通过这种方式注释掉  
    15.   <appender-ref ref="AdoNetAppender_Access" /> 
    16.   --> 
    17. </root> 
    在上面的例子中可以看出,如果想增加日志输出目的地,增加<appender-ref>节点就是了,注意后面的ref是在config中配置的appender name,如果想要取消,删除或者注释掉这行就可以了。
    Log4Net的使用
    首先要添加config文件,在类库项目、命令行程序及WinForm中添加的是app.config,在WebForm中添加的是web.config。
    下面是一个在WinForm项目中的使用Log4Net的例子:
     
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Text;  
    4. using log4net;  
    5. using System.Reflection;  
    6.  
    7. //注意下面的语句一定要加上,指定log4net使用.config文件来读取配置信息  
    8. //如果是WinForm(假定程序为MyDemo.exe,则需要一个MyDemo.exe.config文件)  
    9. //如果是WebForm,则从web.config中读取相关信息  
    10. [assembly: log4net.Config.DOMConfigurator()](这句要加在AssemblyInfo.cs,不然log4net不起作用)
    11. namespace Log4NetDemo  
    12. {  
    13.     class Program  
    14.     {  
    15.         static void Main(string[] args)  
    16.         {  
    17.             Random random = new Random();  
    18.             for (int i = 0; i < 1; i++)  
    19.             {  
    20.                 //创建日志记录组件实例  
    21.                 //ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);  
    22.  
    23.                 ILog log=log4net.LogManager.GetLogger(typeof(Program));  
    24.                 //记录错误日志  
    25.                 //log.Error("error", new Exception("在这里发生了一个异常,Error Number:"+random.Next()));  
    26.                 //记录严重错误  
    27.                 //log.Fatal("fatal", new Exception("在发生了一个致命错误,Exception Id:"+random.Next()));  
    28.                 //记录一般信息  
    29.                 //log.Info("提示:系统正在运行");  
    30.                 //记录调试信息  
    31.                 //log.Debug("调试信息:debug");  
    32.                 //记录警告信息  
    33.                 //log.Warn("警告:warn");  
    34.             }  
    35.             Console.WriteLine("日志记录完毕。");  
    36.             Console.Read();  
    37.  
    38.         }  
    39.     }  
    在WebForm中也可以使用Log4net,下面是一个在ASP.NET中使用Log4Net的例子:
     
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Web;  
    4. using System.Web.UI;  
    5. using System.Web.UI.WebControls;  
    6. using log4net;  
    7. using System.Reflection;  
    8.  
    9. [assembly: log4net.Config.XmlConfigurator(Watch = true)]  
    10. public partial class _Default : System.Web.UI.Page   
    11. {  
    12.     protected void Page_Load(object sender, EventArgs e)  
    13.     {  
    14.         if (!Page.IsPostBack)  
    15.         {  
    16.             Random random = new Random();  
    17.             for (int i = 0; i < 1; i++)  
    18.             {  
    19.                 //创建日志记录组件实例  
    20.                 ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);  
    21.  
    22.                 //ILog log = log4net.LogManager.GetLogger(typeof(Program));  
    23.                 //记录错误日志  
    24.                 //log.Error("error", new Exception("在这里发生了一个异常,Error Number:"+random.Next()));  
    25.                 //记录严重错误  
    26.                 //log.Fatal("fatal", new Exception("在发生了一个致命错误,Exception Id:"+random.Next()));  
    27.                 //记录一般信息  
    28.                 //log.Info("提示:系统正在运行");  
    29.                 //记录调试信息  
    30.                 //log.Debug("调试信息:debug");  
    31.                 //记录警告信息  
    32.                 log.Warn("警告:warn");  
    33.                 Response.Write("日志记录完毕。");  
    34.             }  
    35.         }  
    36.     }  

    可以看出它们的代码基本没有区别。

    下面是一个在WinForm下的config文件的完整配置,该配置文件所使用的代码就是在上面所使用到的代码,使用LogFileAppender、ConsoleAppender、EventLogAppender、AdoNetAppender_SQLite、RollingFileAppender、RollingLogFileAppender_DateFormat方式记录日志都在本地通过测试。

    当然,为了简便,通常的做法是把调用方法写在一个通用类里面,然后调用类的方法,如下:

         public class LogHelper
    {
        public static readonly log4net.ILog InfoLog = log4net.LogManager.GetLogger("InfoLog");
        public static readonly log4net.ILog ErrorLog = log4net.LogManager.GetLogger("ErrorLog");
        public LogHelper()
        {
            //
            //TODO: 在此处添加构造函数逻辑
            //
        }
        /// <summary>
        /// 写普通信息
        /// </summary>
        /// <param name="infoMsg"></param>
        public static void WriteLog(string infoMsg)
        {
            //log4net.ILog InfoLog = log4net.LogManager.GetLogger("InfoLog");
            string msg = "";
            if (InfoLog.IsInfoEnabled)
            {
                InfoLog.Info(msg + infoMsg);
            }
        }
        /// <summary>
        /// 写错误信息
        /// </summary>
        /// <param name="infoMsg"></param>
        /// <param name="e"></param>
        public static void WriteLog(string infoMsg, Exception e)
        {
            string msg = "异常信息:";
            if (ErrorLog.IsErrorEnabled)
            {
                ErrorLog.Error(msg + infoMsg, e);
            }
        }
    }

    在需要使用的页面,直接调用,如:LogHelper.WriteLog("--------Start--------");

  • 相关阅读:
    接口运用实例
    C# Lambda表达式运用
    图片转换图片流方法(二进制流)
    简单的winform编辑器
    C# OO(初级思想)。
    MVC知识点
    提高sql查询效率
    DataRead 和DataSet区别
    JavaScript内置对象与原生对象【转】
    Cookie,Sesstion,Application 缓存。
  • 原文地址:https://www.cnblogs.com/martin1009/p/2219961.html
Copyright © 2011-2022 走看看