Log4Net 开源日志控件

  利用log4net可以方便地将日志信息记录到文件、控制台、Windows事件日志和数据库,并且我们还可以记载要控制的日志级别,可以记载的日志级别包括:FATAL(致命错误)、ERROR(一般错误)、WARN(警告)、INFO(一般信息)、DEBUG(调试信息)。log4net有四种重要组建,分别为Logger(记录器),Repository(仓储、库),Appender(附着器)以及Layout(布局)。

  log4net.dll下载地址:http://logging.apache.org/log4net/download_log4net.cgi。

  选择下载文件log4net-1.2.13-bin-newkey.zip。解压选择对应的net版本找到log4net.dll。bin->net->4.0。

  项目添加log4net.dll引用。

  在项目中创建一个文件夹(Log4NetConfig)。把有关log4net的一些配置文件和类都放在这个文件夹里面。

  WEB网站为例,在项目Log4NetConfig文件夹中创建Log4Net.config配置文件。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!--添加自定义节点:log4net  type:解析类名,程序集名(log4net.dll)-->
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>

  <log4net>
    <!--定义输出到文件中-->
    <appender name="Log4Net_INFO" type="log4net.Appender.RollingFileAppender">
      <!--定义文件存放位置-->
      <file value="C:/log4net/"/>
      <!--是否追加到文件,默认为true,通常无需设置-->
      <appendToFile value="true"/>
      <RollingStyle value="Date"/>
      <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置-->
      <DatePattern value="INFO_yyyyMMdd&quot;.log&quot;" />
      <!--日志文件名是否为静态-->
      <StaticLogFileName value="false"/>
      <!--多线程时采用最小锁定-->
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <!--布局(向用户显示最后经过格式化的输出信息)-->
      <layout type="log4net.Layout.PatternLayout">
        <!--
           %m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息 
           %n(new line):换行 
           %d(datetime):输出当前语句运行的时刻 
           %r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数 
           %t(thread id):当前语句所在的线程ID 
           %p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等 
           %c(class):当前日志对象的名称,例如:
           %L:输出语句所在的行号 
           %F:输出语句所在的文件名 
           %-数字:表示该项的最小长度,如果不够,则用空格填充
          -->
        <Header value="[Header]&#13;&#10;"/>
        <Footer value="[Footer]&#13;&#10;"/>
        <!--正文-->
        <ConversionPattern value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline"  />
      </layout>
    </appender>

    <appender name="Log4Net_ERROR" type="log4net.Appender.RollingFileAppender">
      <file value="C:/log4net/"/>
      <appendToFile value="true"/>
      <RollingStyle value="Date"/>
      <DatePattern value="ERROR_yyyyMMdd&quot;.log&quot;" />
      <StaticLogFileName value="false"/>
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <layout type="log4net.Layout.PatternLayout">
        <Header value="[Header]&#13;&#10;"/>
        <Footer value="[Footer]&#13;&#10;"/>
        <!--正文-->
        <ConversionPattern value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline"  />
      </layout>
    </appender>

    <root>
      <level value="DEBUG"/>
      <appender-ref ref="Log4Net_ERROR" />

      <level value="INFO"/>
      <appender-ref ref="Log4Net_INFO" />
    </root>

  </log4net>

</configuration>
Log4Net.config

  配置文件写完后我们再来写一个Helper类。同样在项目中创建一个名为LogHelper.cs的类文件。

  

using log4net;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;

//指定log4net使用的config文件来读取配置信息
[assembly: log4net.Config.XmlConfigurator(ConfigFile = @"LogConfig\Log4Net.config", Watch = true)]
namespace Project.Log4.Net.LogConfig
{
    /// <summary>
    /// 日志帮助类
    /// </summary>
    public class LogHelper
    {
        private static readonly ConcurrentDictionary<Type, ILog> _loggers = new ConcurrentDictionary<Type, ILog>();

        /// <summary>
        /// 获取记录器
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        private static ILog GetLogger(Type source)
        {
            if (_loggers.ContainsKey(source))
            {
                return _loggers[source];
            }
            else
            {
                ILog logger = LogManager.GetLogger(source);
                _loggers.TryAdd(source, logger);
                return logger;
            }
        }

        /* Log a message object */

        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        public static void Debug(object source, string message)
        {
            Debug(source.GetType(), message);
        }

        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        /// <param name="ps"></param>
        public static void Debug(object source, string message, params object[] ps)
        {
            Debug(source.GetType(), string.Format(message, ps));
        }

        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        public static void Debug(Type source, string message)
        {
            ILog logger = GetLogger(source);
            if (logger.IsDebugEnabled)
                logger.Debug(message);
        }

        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        public static void Info(object source, object message)
        {
            Info(source.GetType(), message);
        }

        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        public static void Info(Type source, object message)
        {
            ILog logger = GetLogger(source);
            if (logger.IsInfoEnabled)
                logger.Info(message);
        }

        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        public static void Warn(object source, object message)
        {
            Warn(source.GetType(), message);
        }

        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        public static void Warn(Type source, object message)
        {
            ILog logger = GetLogger(source);
            if (logger.IsWarnEnabled)
                logger.Warn(message);
        }

        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        public static void Error(object source, object message)
        {
            Error(source.GetType(), message);
        }

        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        public static void Error(Type source, object message)
        {
            ILog logger = GetLogger(source);
            if (logger.IsErrorEnabled)
                logger.Error(message);
        }

        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        public static void Fatal(object source, object message)
        {
            Fatal(source.GetType(), message);
        }

        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        public static void Fatal(Type source, object message)
        {
            ILog logger = GetLogger(source);
            if (logger.IsFatalEnabled)
                logger.Fatal(message);
        }

        /* Log a message object and exception */

        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        public static void Debug(object source, object message, Exception exception)
        {
            Debug(source.GetType(), message, exception);
        }

        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        public static void Debug(Type source, object message, Exception exception)
        {
            GetLogger(source).Debug(message, exception);
        }

        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        public static void Info(object source, object message, Exception exception)
        {
            Info(source.GetType(), message, exception);
        }

        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        public static void Info(Type source, object message, Exception exception)
        {
            GetLogger(source).Info(message, exception);
        }

        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        public static void Warn(object source, object message, Exception exception)
        {
            Warn(source.GetType(), message, exception);
        }

        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        public static void Warn(Type source, object message, Exception exception)
        {
            GetLogger(source).Warn(message, exception);
        }

        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        public static void Error(object source, object message, Exception exception)
        {
            Error(source.GetType(), message, exception);
        }

        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        public static void Error(Type source, object message, Exception exception)
        {
            GetLogger(source).Error(message, exception);
        }

        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        public static void Fatal(object source, object message, Exception exception)
        {
            Fatal(source.GetType(), message, exception);
        }

        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        public static void Fatal(Type source, object message, Exception exception)
        {
            GetLogger(source).Fatal(message, exception);
        }
    }

}
LogHelper

  配置和Helper类都有了..现在来看看调用方法。

  

LogHelper.Debug(this, "Debug");
LogHelper.Error(this, "Error");
LogHelper.Fatal(this, "Fatal");
LogHelper.Info(this, "Info");
LogHelper.Warn(this, "Warn");

  

  日志生成格式[每天一个文件]:
  
  

参数说明

  

Log4Net.config是配置日志输出参数文件。在这个文件中可以到看很多配置节点,大体可以分为二个大 类<configSections>...</configSections> 和 <log4net>...</log4net>。我们来看看这些节点都是啥意思。

1:<configSections>..</configSections>:申明自定义节点log4net解析的类名和程序集名(log4net.dll)。

2:<log4net>..</log4net>:使用log4net的配置信息都在这里设置。来重点看看都有那些设置信息,这个大节点整体也可以分为二类。

2.1:定义输出信息设置节点<appender></appender>。

2.2:定义日志的输出媒介<root></root>。

配置的总体结构就是这样,下面来看一些详细内容。

 

appender:决定日志输出的方式(可设置多个节点,如对INFO,ERROR等设置不同的输出方式)。

主要包括已下几种:

1 AnsiColorTerminalAppender:在ANSI 窗口终端写下高亮度的日志事件。
2 AspNetTraceAppender:能用asp.net中Trace的方式查看记录的日志。
3 BufferingForwardingAppender:在输出到子Appenders之前先缓存日志事件。
4 ConsoleAppender:将日志输出到控制台。
5 EventLogAppender:将日志写到Windows Event Log.
6 FileAppender:将日志写到文件中。
7 LocalSyslogAppender:将日志写到local syslog service (仅用于UNIX环境下).
8 MemoryAppender:将日志存到内存缓冲区。
9 NetSendAppender:将日志输出到Windows Messenger service.这些日志信息将在用户终端的对话框中显示。
10 RemoteSyslogAppender:通过UDP网络协议将日志写到Remote syslog service。
11 RemotingAppender:通过.NET Remoting将日志写到远程接收端。
12 RollingFileAppender:将日志以回滚文件的形式写到文件中。(实例代码中使用的是此类型)
13 SmtpAppender:将日志写到邮件中。
14 TraceAppender:将日志写到.NET trace 系统。
15 UdpAppender:将日志connectionless UDP datagrams的形式送到远程宿主或以UdpClient的形式广播。

从上面提供的方式中可以看出能输出文件、控制台、Windows事件日志和数据库。这个可根据实际情况选择。

<appender name="Log4Net_INFO" type="log4net.Appender.RollingFileAppender">
...
</appender>

这里配置的name(“Log4Net_INFO”)会在定义日志的输出媒介中使用到。name可任意设置。

在appender 节点中还会配置一些文件存放的地址,日志个数等信息。这些在实例代码中都在体现,这里不做说明。我们在来看看日志最后输出呈现的布局设置信息。

<layout type="log4net.Layout.PatternLayout">
     <!--头-->
     <Header value="[Header]"/>
     <!--脚注-->
     <Footer value="[Footer]"/>
     <!--正文-->
     <ConversionPattern value="%d [%t] %-5p %c [%x]  - %m%n" />
</layout>

 这里配置的信息最终是日志打印出来的样式。我们可以看到这里可以设置内容头Header和尾Footer。正文ConversionPattern。在正文中有出现有 %d  [%t]这些都是啥意思了表示什么。这里有一个对照表可提供参考:

%m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息
%n(new line):换行
%d(datetime):输出当前语句运行的时刻
%r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数
%t(thread id):当前语句所在的线程ID
%p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等
%c(class):当前日志对象的名称,例如:
%L:输出语句所在的行号
%F:输出语句所在的文件名
%-数字:表示该项的最小长度,如果不够,则用空格填充

配置的基本也就这些。下就是root的配置说明 。

root

对设置输出的方式进行指定。

复制代码

<root>
  <!--批定DEBUG输出的文件形式记录日志-->
  <level value="DEBUG"/>
  <appender-ref ref="Log4Net_ERROR" />

  <!--批定INFO输出的文件形式记录日志-->
  <level value="INFO"/>
  <appender-ref ref="Log4Net_INFO" />
</root>

复制代码

控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF
比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录
如果没有定义LEVEL的值,则缺省为DEBUG

 

<!-- 错误日志附加介质-->
  <appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">  <!-- name属性指定其名称,type则是log4net.Appender命名空间的一个类的名称,意思是,指定使用哪种介质-->
    <param name="File" value="Log\\LogError\\" /> <!-- 输出到什么目录-->
    <param name="AppendToFile" value="true" /><!-- 是否覆写到文件中-->
    <param name="MaxSizeRollBackups" value="100" /><!-- 备份文件的个数-->
    <param name="MaxFileSize" value="10MB" /><!-- 单个日志文件最大的大小-->
    <param name="StaticLogFileName" value="false" /><!-- 是否使用静态文件名-->
    <param name="DatePattern" value="yyyyMMdd&quot;.htm&quot;" /><!-- 日志文件名-->
    <param name="RollingStyle" value="Date" />
    <!--布局-->
    <layout type="log4net.Layout.PatternLayout">
      <param name="ConversionPattern" value="&lt;HR COLOR=red&gt;%n异常时间:%d [%t] &lt;BR&gt;%n异常级别:%-5p &lt;BR&gt;%n异 常 类:%c [%x] &lt;BR&gt;%n%m &lt;BR&gt;%n &lt;HR Size=1&gt;"  />
    </layout>
  </appender>

 

<log4net>
    <!--定义输出到文件中-->
    <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
      <!--定义文件存放位置-->
      <file value="D:\123.txt" />
      <!--是否追加到文件-->
      <appendToFile value="true" />
      <!--变换的形式为日期-->
      <rollingStyle value="Date" />
      <!--日期的格式-->
      <datePattern value="yyyyMMdd-HH:mm:ss" />
      <!--以日志文件大小变换文件名-->
      <rollingStyle value="Size" />
      <!--最大变换数量,-1为不限制-->
      <maxSizeRollBackups value="-1" />
      <!--最大文件大小(1G切换)-->
      <maximumFileSize value="1GB" />
      <layout type="log4net.Layout.PatternLayout">
        <!--每条日志末尾的文字说明-->
        <footer value="by Mr.Jun" />
        <!--输出格式-->
        <conversionPattern value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline" />
      </layout>
    </appender>
    <root>
      <!--文件形式记录日志(仅仅输出文件形式)-->
      <appender-ref ref="LogFileAppender" />
    </root>
  </log4net>
<log4net>
    <!--根据logger获取ILog对象-->
    <logger name="logger">
      <!--control log level: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
      <!--如果没有定义LEVEL的值,则缺省为DEBUG-->
      <level value="ALL" />
      <appender-ref ref="LogSmtpAppender" />
      <appender-ref ref="LogFileAppender" />
    </logger>
    <!--定义输出到文件中-->
    <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
      <!--定义文件存放位置-->
      <file value="D:\123.txt" />
      <appendToFile value="true" />
      <rollingStyle value="Date" />
      <datePattern value="yyyyMMdd-HH:mm:ss" />
      <layout type="log4net.Layout.PatternLayout">
        <!--输出格式-->
        <conversionPattern value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline" />
      </layout>
    </appender>
    <!--定义邮件发送-->
    <appender name="LogSmtpAppender" type="log4net.Appender.SmtpAppender">
      <authentication value="Basic" />
      <to value="xxx@qq.com" />
      <from value="xxx@163.com" />
      <username value="xxx@163.com" />
      <password value="xxx" />
      <subject value="XXX应用错误日志消息" />
      <smtpHost value="smtp.163.com" />
      <bufferSize value="2048" />
      <!--超长部分是否丢弃-->
      <lossy value="true" />
      <!--日志级别 大于 WARN 的才发邮件-->
      <evaluator type="log4net.Core.LevelEvaluator">
        <threshold value="ERROR"/>
      </evaluator>
      <!--定义邮件的格式-->
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%property{log4net:HostName} :: %level :: %message %newlineLogger: %logger%newlineThread: %thread%newlineDate: %date%newlineNDC: %property{NDC}%newline%newline" />
      </layout>
    </appender>
  </log4net>

 

posted @ 2015-09-21 16:26  jinbao.wang  阅读(583)  评论(0)    收藏  举报