欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Log4Net 日志配置[附带源码下载]

程序员文章站 2023-01-22 12:51:37
前述   园子里有许多人对log4net这款开源的日志记录控件有很多介绍。在这里个人再做一次总结,希望对以后有所帮助,需要的时候可以直接使用,减少查阅资料的时间。利用lo...

前述

  园子里有许多人对log4net这款开源的日志记录控件有很多介绍。在这里个人再做一次总结,希望对以后有所帮助,需要的时候可以直接使用,减少查阅资料的时间。利用log4net可以方便地将日志信息记录到文件、控制台、windows事件日志和数据库,并且我们还可以记载控制要记载的日志级别,可以记载的日志类别包括:fatal(致命错误)、error(一般错误)、warn(警告)、info(一般信息)、debug(调试信息)。log4net 有四种主要的组件,分别是logger(记录器), repository(库), appender(附着器)以及 layout(布局).

准备工作:

1.下载log4net.dll 下载地址[]

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

Log4Net 日志配置[附带源码下载]

2.在项目中引用log4net.dll。

Log4Net 日志配置[附带源码下载]

实例代码

准备工作完成后我们来看下实例代码 ,首先在项目中创建一个文件夹logconfig。把有关log4net的一些配置文件和类都放在这个文件夹里面。

web网站为例,在项目logconfig文件夹中创建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".log"" />
   <!--日志文件名是否为静态-->
   <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]
"/>
    <footer value="[footer]
"/>
    <!--正文-->
    <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".log"" />
   <staticlogfilename value="false"/>
   <lockingmodel type="log4net.appender.fileappender+minimallock" />
   <layout type="log4net.layout.patternlayout">
    <header value="[header]
"/>
    <footer value="[footer]
"/>
    <!--正文-->
    <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>

配置文件写完后我们在来写一个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);
    }
  }

}

配置和helper类都有了..现在来看看调用方法。在项目中创建一个index.aspx页面

loghelper.debug(this, "debug");
loghelper.error(this, "error");
loghelper.fatal(this, "fatal");
loghelper.info(this, "info");
loghelper.warn(this, "warn");

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

Log4Net 日志配置[附带源码下载]


参数说明

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

附带源码:代码