转 Log4net详细说明

转自:http://www.cnblogs.com/zhangchenliang/p/4546352.html

1、概述

        log4net.Net下一个非常秀的开源日志记录组件。log4net记录日志的功能非常大。它可以将日志分不同的等,以不同的格式,出到不同的媒介。本文主要是介如何在Visual Studio2008中使用log4net快速建系日志,如何展以出自定字段。

2、一个简单的使用

第一步:目中添加log4net.dll的引用,里引用版本是1.2.10.0

第二步:程序启动时读log4net的配置文件。

如果是CS程序,在根目Program.cs中的Main方法中添加:

log4net.Config.XmlConfigurator.Configure();

如果是BS程序,在根目Global.asax.cs(没有新建一个)中的Application_Start方法中添加:

log4net.Config.XmlConfigurator.Configure();

BSCS程序都可直接在目的AssemblyInfo.cs文件里添加以下的句:

[assembly: log4net.Config .XmlConfigurator()]

也可以使用自定的配置文件,具体4.4 配置文件。

第三步:修改配置文件。如果是CS程序,在默App.config文件(没有新建一个)中添加内容;如果是BS程序,添加到Web.config文件中,添加内容一里不再列出。

App.config文件添加内容如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
  </configSections>
  <log4net>
    <root>
      <level value="WARN" />
      <appender-ref ref="LogFileAppender" />
      <appender-ref ref="ConsoleAppender" />
    </root>

    <logger name="testApp.Logging">
      <level value="DEBUG"/>
    </logger>

    <appender name="LogFileAppender" type="log4net.Appender.FileAppender" >
      <param name="File" value="log-file.txt" />
      <param name="AppendToFile" value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <param name="Header" value="[Header] "/>
        <param name="Footer" value="[Footer] "/>
        <param name="ConversionPattern" value="%d[%t] %-5p %c [%x]  - %m%n" />
      </layout>
      <filter type="log4net.Filter.LevelRangeFilter">
        <param name="LevelMin" value="DEBUG" />
        <param name="LevelMax" value="WARN" />
      </filter>
    </appender>
    <appender name="ConsoleAppender"  type="log4net.Appender.ConsoleAppender" >
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern"  value="%d[%t] %-5p %c [%x] - %m%n" />
      </layout>
    </appender>
  </log4net>
</configuration>

第四步:在程序使用。

log4net.ILog log =log4net.LogManager.GetLogger("testApp.Logging");//获取一个日志记录器

log.Info(DateTime.Now.ToString()+ ": login success");//写入一条新log

这样就将信息同时输出到控制台和写入到文件名“log-file.txt”的文件中,其中“log-file.txt”文件的路径是当前程序运行所在目;也可以定义为绝对路径,配置如:

<param name="File" value="C:/log-file.txt" />就写入C根目log-file.txt文件中,具体使用技巧参4.2.1

本例的实现请8.6附件。

3Log4net的主要成部分

3.1Appenders

Appenders用来定日志的出方式,即日志要写到那种介上去。常用的Log4net经实现好了,直接在配置文件中用即可,可参上面配置文件例子;当然也可以自己写一个,需要从log4net.Appender.AppenderSkeleton类继承。可以通配置FiltersLayout实现日志的过滤出格式。

经实现出方式有:

AdoNetAppender 将日志记录到数据中。可以采用SQL和存储过程两种方式。

AnsiColorTerminalAppender 将日志高亮出到ANSI端。

AspNetTraceAppender  能用asp.netTrace的方式记录的日志。

BufferingForwardingAppender 出到子Appenders之前先存日志事件。

ConsoleAppender 将日志出到用程序控制台。

EventLogAppender 将日志写到Windows Event Log

FileAppender 将日志出到文件。

ForwardingAppender 送日志事件到子Appenders

LocalSyslogAppender 将日志写到local syslog service (用于UNIX境下)

MemoryAppender 将日志存到内存冲区。

NetSendAppender 将日志出到Windows Messenger service.些日志信息将在用户终端的对话框中示。

OutputDebugStringAppender 将日志出到Debuger,如果程序没有Debuger,就出到系Debuger。如果系Debuger也不可用,将忽略消息。

RemoteSyslogAppender UDP络协议将日志写到Remote syslog service

RemotingAppender .NET Remoting将日志写到程接收端。

RollingFileAppender 将日志以回文件的形式写到文件中。

SmtpAppender 将日志写到件中。

SmtpPickupDirAppender 将消息以文件的方式放入一个目中,像IISSMTP agent这样SMTP代理就可以阅读送它

TelnetAppender 端通Telnet来接受日志事件。

TraceAppender 将日志写到.NET trace 

UdpAppender 将日志以无UDP数据的形式送到程宿主或用UdpClient的形式广播。

3.2 Filters

使用过滤器可以过滤Appender出的内容。过滤器通常有以下几种:

DenyAllFilter 阻止所有的日志事件被记录

LevelMatchFilter 只有指定等的日志事件才被记录

LevelRangeFilter 日志等在指定范内的事件才被记录

LoggerMatchFilter Logger名称匹配,才记录

PropertyFilter 消息匹配指定的属性值时才被记录

StringMathFilter 消息匹配指定的字符串才被记录

3.3 Layouts

Layout用于控制Appender出格式,可以是线性的也可以是XML

一个Appender只能有一个Layout

最常用的Layout应该典格式的PatternLayout,其次是SimpleLayoutRawTimeStampLayoutExceptionLayout。然后IRawLayoutXMLLayout等几个,使用少。Layout可以自己实现,需要从log4net.Layout.LayoutSkeleton类继承,来出一些特殊需要的格式,在后面就重新实现了一个Layout

SimpleLayout简单输出格式,只出日志级别与消息内容。

RawTimeStampLayout 用来格式化时间,在向数据库输会用到。

式如“yyyy-MM-ddHH:mm:ss“

ExceptionLayout需要Logger的方法Exception象作参数才起作用,否就什么也不出。出的候会包含MessageTrace

PatterLayout使用最多的一个Layout,能出的信息很多,使用方式可参上面例子中的配置文件。PatterLayout的格式化字符串文后附注8.1

3.4 Loggers

Logger是直接和用程序交互的件。Logger只是生日志,然后由它引用的Appender记录到指定的媒介,并由Layout控制格式。

Logger提供了多种方式来记录一个日志消息,也可以有多个Logger存在。每个例化的Loggerlog4net命名体(Named Entity)来维护log4net使用承体系,也就是假如存在两个Logger,名字分别为a.b.ca.b。那么a.b就是a.b.c的祖先。每个Logger承了它祖先的属性。所有的Logger都从Root,Root本身也是一个Logger

日志的等,它由高到底分别为

OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL 

高于等级设方法(如何置参配置文件)都能写入日志, Off所有的写入方法都不写到日志里,ALL相反。例如当我们设Infologger.Debug就会被忽略而不写入文件,但是FATAL,ERROR,WARN,INFO会被写入,因高于INFO

在具体写日志,一般可以这样理解日志等

FATAL(致命错误):记录中出的能使用系完全失去功能,服停止,系等使系无法继续运行下去的错误。例如,数据无法接,系死循

ERROR(一般错误):记录中出致系定,部分功能出混乱或部分功能失效一错误。例如,数据字段空,数据操作不可完成,操作出异常等。

WARN(警告):记录中不影响系统继续运行,但不符合系运行正常条件,有可能引起系统错误的信息。例如,记录内容空,数据内容不正确等。

INFO(一般信息):记录运行中应该让知道的基本信息。例如,服开始运行,功能已等。

DEBUG 调试信息):记录用于调试的一切信息,内容或者是一些关数据内容的出。

Logger实现ILog接口,ILog5个方法(Debug,Inof,Warn,Error,Fatal)分别对不同的日志等级记录日志。5个方法5个重。以Debug明一下,其它的和它差不多。

ILogDebug方法的定如下:

void Debug(object message);

void Debug(object message, Exception ex);

有一个布属性:

bool IsDebugEnabled{ get; }

如果使用Debug(object message, Exception ex)Layout中是否定%exception,默配置下日志都会Exception。包括ExceptionMessageTrace。如果使用Debug(objectmessage)日志是不会Exception

最后一个LogManager,它用来管理所有的Logger。它的GetLogger方法,可以得配置文件中相Logger

log4net.ILog log =log4net.LogManager.GetLogger("logger-name");

3.5 ObjectRenders

它将告logger如何把一个一个字符串记录到日志里。(ILog中定的接口接收的参数是Object,而不是String。)

例如你想把Orange记录到日志中,但此logger只会OrangeToString方法而已。所以要定一个OrangeRender类实现log4net.ObjectRender.IObjectRender接口,然后注册它(我在本文中的展不使用种方法,而是直接实现一个自定Layout)。这时logger就会知道如何把Orange记录到日志中了。

3.6Repository

Repository主要用于日志组织结构的维护

4、配置文件

4.1 配置文件构成

主要有两大部分,一是申明一个名“log4net“的自定配置,如下所示:

  <configSections>

<section name="log4net"

type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />

  </configSections>

二是<log4net>的具体配置,是下面要重点明的。

4.1.1<log4net>

所有的配置都要在<log4net>元素里定

支持的属性:

debug

可选,取值是true或false,默认是false。设置为true,开启log4net的内部调试。

update

可选,取值是Merge(合并)或Overwrite(覆盖),默认值是Merge。设置为Overwrite,在提交配置的时候会重置已经配置过的库。

threshold

可选,取值是repository(库)中注册的level,默认值是ALL。

支持的子元素:

appender

0或多个

logger

0或多个

renderer

0或多个

root

最多一个

param

0或多个

 

4.1.2 <root>

实际上就是一个根logger,所有其它logger都默认继承它,如果配置文件里没有式定框架使用根日志中定的属性。root元素没有属性。

支持的子元素:

appender-ref

0个或多个,要引用的appender的名字。

level

最多一个。 只有在这个级别或之上的事件才会被记录。

param

0个或多个, 设置一些参数。

 

4.1.3 <logger>

支持的属性:

name

必须的,logger的名称

additivity

可选,取值是true或false,默认值是true。设置为false时将阻止父logger中的appender。

支持的子元素:

appender-ref

0个或多个,要引用的appender的名字。

level

最多一个。 只有在这个级别或之上的事件才会被记录。

param

0个或多个, 设置一些参数。

 

4.1.4 <appender>

日志的出方式,只能作 log4net 的子元素。name属性必唯一,type属性必指定。

支持的属性:

name

必须的,Appender对象的名称

type

必须的,Appender对象的输出类型

支持的子元素:

appender-ref

0个或多个,允许此appender引用其他appender,并不是所以appender类型都支持。

filter

0个或多个,定义此app使用的过滤器。

layout

最多一个。定义appender使用的输出格式。

param

0个或多个, 设置Appender类中对应的属性的值。

实际<appender>所能包含的子元素不止上面4个。

 

4.1.5 <layout>

布局,只能作<appender>的子元素。

支持的属性:

type

必须的,Layout的类型

支持的子元素:

param

0个或多个, 设置一些参数。

 

4.1.6 <filter>

过滤器,只能作<appender>的子元素。

支持的属性:

type

必须的,Filter的类型

支持的子元素:

param

0个或多个, 设置一些参数。

 

4.1.7 <param>

<param>元素可以是任何元素的子元素。

支持的属性:

name

必须的,取值是父对象的参数名。

value

可选的,value和type中,必须有一个属性被指定。value是一个能被转化为参数值的字符串。

type

可选的,value和type中,必须有一个属性被指定。type是一个类型名,如果type不是在log4net程序集中定义的,就需要使用全名。

支持的子元素:

param

0个或多个, 设置一些参数。

 

4.2<appender>配置

   <appender>在配置文件中至少有一个,也可以有多个,有些<appender>可以引用其他<appender>型,具体参数可参上表。

下面只写入回文件与出到数据里使用SQL数据)配置体会一下,其他配置可参考官方网站:http://logging.apache.org/log4net/release/config-examples.html

4.2.1写入回文件    

    <appender name="ReflectionLayout" type="log4net.Appender.RollingFileAppender,log4net">
      <!--日志文件路径,“/”与“/”作用相同,到达的目录相同,文件夹不存在则新建 -->
      <!--按文件大小方式输出时在这里指定文件名,并且当天的日志在下一天时在文件名后自动追加当天日期形成新文件。-->
      <!—按照日期形式输出时,直接连接元素DatePattern的value形成文件路径。此处使用这种方式 -->
      <!--param的名称,可以直接查对应的appender类的属性名即可,这里要查的就是RollingFileAppender类的属性 -->
      <param name="File" value="D:/Log/" />
      <!--是否追加到文件-->
      <param name="AppendToFile" value="true" />
      <!--记录日志写入文件时,不锁定文本文件,防止多线程时不能写Log,官方说线程非安全-->
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <!--使用Unicode编码-->
      <Encoding value="UTF-8" />
      <!--最多产生的日志文件数,超过则只保留最新的n个。设定值value="-1"为不限文件数-->
      <param name="MaxSizeRollBackups" value="10" />
      <!--是否只写到一个文件中-->
      <param name="StaticLogFileName" value="false" />
      <!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
      <param name="RollingStyle" value="Composite" />
      <!--按日期产生文件夹和文件名[在日期方式与混合方式下使用]-->
      <!--此处按日期产生文件夹,文件名固定。注意" 的位置-->
      <param name="DatePattern" value="yyyy-MM-dd/"ReflectionLayout.log""  />
      <!--这是按日期产生文件夹,并在文件名前也加上日期-->
      <param name="DatePattern"value="yyyyMMdd/yyyyMMdd"-TimerServer.log""  />
      <!--这是先按日期产生文件夹,再形成下一级固定的文件夹-->
      <param name="DatePattern"value="yyyyMMdd/"TimerServer/TimerServer.log""  />
      <!--每个文件的大小。只在混合方式与文件大小方式下使用。
        超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。
        可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志-->
      <param name="maximumFileSize" value="500KB" />
      <!--计数类型为1,2,3…-->
      <param name="CountDirection" value="1"/>
      <!--过滤设置,LevelRangeFilter为使用的过滤器。 -->
      <filter type="log4net.Filter.LevelRangeFilter">
        <param name="LevelMin" value="DEBUG" />
        <param name="LevelMax" value="WARN" />
      </filter>
      <!--记录的格式。一般用log4net.Layout.PatternLayout布局-->
      <!--此处用继承了log4net.Layout.PatternLayout的自定义布局,TGLog.ExpandLayout2
        为命名空间。%property{Operator}、%property{Action}是自定义的输出-->
      <layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">
        <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" />
      </layout>
</appender>

注意些配置属性有些是可的,如果需要,一定要写正确,否要么出的不是自己想要的果,要么干脆不出任何信息。

4.2.1写入SQL数据

需要在相的数据中准好一表,句如下:

CREATE TABLE [Log] (

[ID] [int] IDENTITY (1, 1) NOTNULL ,

[Date] [datetime] NOT NULL ,

[Thread] [varchar] (100) COLLATEChinese_PRC_CI_AS NULL ,

[Level] [varchar] (100) COLLATEChinese_PRC_CI_AS NULL ,

[Logger] [varchar] (200) COLLATEChinese_PRC_CI_AS NULL ,

[Operator] [int] NULL ,

[Message] [text] COLLATEChinese_PRC_CI_AS NULL ,

[ActionType] [int] NULL ,

[Operand] [varchar] (300)COLLATE Chinese_PRC_CI_AS NULL ,

[IP] [varchar] (20) COLLATEChinese_PRC_CI_AS NULL ,

[MachineName] [varchar] (100)COLLATE Chinese_PRC_CI_AS NULL ,

[Browser] [varchar] (50) COLLATEChinese_PRC_CI_AS NULL ,

[Location] [text] COLLATEChinese_PRC_CI_AS NULL ,

[Exception] [text] COLLATE Chinese_PRC_CI_ASNULL

)

<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender,log4net">

<!--BufferSize为缓冲区大小,只有日志记录超设定值才会一块写入到数据库-->

<bufferSize value="10" /><!—或写为<paramname="BufferSize" value="10" />-->

 

<!--引用-->
<connectionType value="System.Data.SqlClient.SqlConnection,System.Data, Version=1.0.3300.0, Culture=neutral,PublicKeyToken=b77a5c561934e089" />

<!--连接数据库字符串-->
<connectionString value="datasource=.;initial catalog=Test;integrated security=false;persist securityinfo=True;User ID=sa;Password=;" />

<!--插入到表Log-->
<commandText value="INSERTINTO Log([Date],[Thread],[Level],[Logger],[Operator],[Message],[ActionType],[Operand],[IP],[MachineName],[Browser],[Location],[Exception])VALUES (@log_date, @thread, @log_level, @logger,@operator,@message,@action_type,@operand,@ip,@machineName,@browser,@location,@exception)" />

<!--日志记录时间,RawTimeStampLayout为默认的时间输出格式 -->

      <parameter>
        <parameterName value="@log_date" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.RawTimeStampLayout" />
      </parameter>

      <!--线程号-->
      <parameter>
        <parameterName value="@thread" />
        <dbType value="String" />
<!--长度不可以省略,否则不会输出-->
        <size value="100" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%thread" />
        </layout>
      </parameter>

      <!--日志等级-->
      <parameter>
        <parameterName value="@log_level" />
        <dbType value="String" />
        <size value="100" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%level" />
        </layout>
      </parameter>

      <!--日志记录类名称-->
      <parameter>
        <parameterName value="@logger" />
        <dbType value="String" />
        <size value="200" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%logger" />
        </layout>
      </parameter>

      <!--操作者。这个是自定义的输出字段,使用重新实现的布局器ReflectionLayout-->
      <parameter>
        <parameterName value="@operator" />
<!--设置为Int32时只有bufferSize的 value<="1"才正确输出,没有找出原因。-->
        <dbType value="Int16" />
        <layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">
          <conversionPattern value="%property{Operator}" />
        </layout>
      </parameter>

      <!--操作对象-->
      <parameter>
        <parameterName value="@operand" />
        <dbType value="String" />
        <size value="300" />
        <layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">
          <conversionPattern value="%property{Operand}" />
        </layout>
      </parameter>

 

      <!--IP地址-->
      <parameter>
        <parameterName value="@ip" />
        <dbType value="String" />
        <size value="20" />
        <layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">
          <conversionPattern value="%property{IP}" />
        </layout>
      </parameter>

      <!--机器名-->
      <parameter>
        <parameterName value="@machineName" />
        <dbType value="String" />
        <size value="100" />
        <layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">
          <conversionPattern value="%property{MachineName}" />
        </layout>
      </parameter>

      <!--浏览器-->

      <parameter>
        <parameterName value="@browser" />
        <dbType value="String" />
        <size value="50" />
        <layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">
          <conversionPattern value="%property{Browser}" />
        </layout>
      </parameter>
     
      <!--日志消息-->
      <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="3000" />
        <layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">
          <conversionPattern value="%property{Message}" />
        </layout>
      </parameter>

      <!--动作类型-->
      <parameter>
        <parameterName value="@action_type" />
        <dbType value="Int16" />
        <layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">
          <conversionPattern value="%property{ActionType}" />
        </layout>
      </parameter>

      <!--记录日志的位置-->
      <parameter>
        <parameterName value="@location" />
        <dbType value="String" />
        <size value="2000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%location" />
        </layout>
      </parameter>

      <!--异常信息。ExceptionLayout 为异常输出的默认格式-->
      <parameter>
        <parameterName value="@exception" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.ExceptionLayout" />
      </parameter>

</appender>

注意:

向表中出的字段不能多于数据表本身字段,而反之可以,但些多余字段一定使其可以空,否便写不到数据

出字段的型一定是对应数据表字段数据型可以转换的,而且度也不能超,否也不能写入;

数据表字段置尽量可以空,这样可以避免一条日志记录存在空数据致后面的日志都记录不了。

4.3<logger>的配置

在配置文件<appender>中的配置好了出的介,格式,过滤方式,要定日志<logger>

在框架的体系里,所有的日志象都是根日志(rootlogger)的后代。 因此如果一个日志象没有在配置文件里式定框架使用根日志中定的属性。在<root>标签里,可以定level级别值Appender的列表。如果没有定LEVEL缺省DEBUG。可以通<appender-ref>标签日志象使用的Appender象。<appender-ref>声明了在其他地方定Appender象的一个引用。在一个logger象中的置会覆盖根日志的置。而Appender属性来,子日志承父日志象的Appender列表。种缺省的行方式也可以通过显式地<logger>标签additivity属性false而改

<root>式申明使用默的配置。我得在使用不定<root>,自定多个<logger>,在程序中记录日志直接使用<logger>name找相<logger>这样更灵活一些。例如:

<!--写两个文件和数据-->

<logger name="ReflectionLayout">

      <level value="DEBUG"/>

      <appender-ref ref="HashtableLayout"/>

      <appender-ref ref="ReflectionLayout"/>

      <appender-ref ref="ADONetAppender"/>

</logger>

4.4配置文件

log4net的是用程序的配置文件App.config(BS程序是Web.config),可以使用程序集自定属性来置。下面来介一下个自定属性:

log4net.Config.XmlConifguratorAttribute

 

XmlConfiguratorAttribute3个属性:

ConfigFile 配置文件的名字,文件路径相用程序目

(AppDomain.CurrentDomain.BaseDirectory)ConfigFile属性不能和ConfigFileExtension属性一起使用。

ConfigFileExtension 配置文件的展名,文件路径相用程序的目ConfigFileExtension属性不能和ConfigFile属性一起使用。

Watch 如果将Watch属性true,就会监视配置文件。当配置文件化的候,就会重新加

如果ConfigFileConfigFileExtension都没有置,使用用程序的配置文件App.configWeb.config)。

 可以在目的AssemblyInfo.cs文件里添加以下的句:

 //监视默认的配置文件,App.exe.config   
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
 
//监视配置文件,App.exe.log4net。
[assembly: log4net. Config.XmlConfigurator(ConfigFileExtension = "log4net", Watch = true)]
 
//使用配置文件log4net.config,不监视改变。注意log4net.config文件的目录,BS程序在站点目录//下,CS则在应用程序启动目录下,如调试时在/bin/Debug下,一般将文件属性的文件输出目录调为//始终复制即可
[assembly: log4net. Config.XmlConfigurator(ConfigFile = "log4net.config")]
 
//使用配置文件log4net.config,不监视改变
[assembly: log4net. Config.XmlConfigurator()]

也可以在Global.asaxApplication_Start里或者是Program.cs中的Main方法中添加,注意里一定是绝对路径,如下所示:

//是在BS程序下,使用自定的配置文件log4net.xml,使用Server.MapPath("~")+ //@"/log4net.xml”来取得路径。/log4net.xml于站点的路径

// ConfigureAndWatch()相当于Configure(Watch= true)

log4net.Config.XmlConfigurator.ConfigureAndWatch(

new System.IO.FileInfo(Server.MapPath("~")+ @"/log4net.xml"));

//是在CS程序下,可以用以下方法得:

string assemblyFilePath= Assembly.GetExecutingAssembly().Location;

string assemblyDirPath= Path.GetDirectoryName(assemblyFilePath);

string configFilePath =assemblyDirPath + " //log4net.xml";

log4net.Config.XmlConfigurator.ConfigureAndWatch(

new FileInfo(configFilePath));

或直接使用绝对路径:

//使用自定的配置文件,直接绝对路径c:/log4net.config

log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(@"c:/log4net.config"));

 5、如何记录日志

Log4net使用很方便,先申明一个封装ILog 象,如下:

log4net.ILog log =log4net.LogManager.GetLogger("ReflectionLayout");

其中"ReflectionLayout"便是我自定的日志<logger>name

对应5个日志级别log个方法,每个方法都有两个重,使用如下:

try

            {

                log.Debug("是一个测试");

            }

            catch(Exception ec)

            {

                log.Error("现错误", ec);

         }

如果我需要出的消息是要区开来,不按一个字符串全部出,就需要行一些展了。

6Log4net简单扩

6.1重写布局Layout入的 message象的属性

6.1.1重写Layout

过继log4net.Layout.PatternLayout,使用log4net.Core.LoggingEvent的方法得到了要出的message的名称,然后通反射得到各个属性的,使用PatternLayoutAddConverter方法入得到的里注意要引用用到的的命名空

码见附注8.2

 

6.1.2配置相的配置文件

配置文件其他地方不用改,只是需要改<appender>中的<layout>。例如:

<layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">

        <param name="ConversionPattern"

 value="记录时间%date    操作者ID%property{Operator}             

操作型:%property{Action}%n  消息描述:%property{Message}%n                    异常:%exception%n " />

      </layout>

其中<layout>type由原来的log4net.Layout.PatternLayout换为自定TGLog.ExpandLayout2.ReflectionLayoutTGLog.ExpandLayout2命名空)。%property{Operator}出的即message类对象的属性Operator数据配置同,相的字段如果是自定的,则输用自定<layout>。例:

<!---->

  <parameter>

      <parameterName value="@action_type" />

      <dbType value="Int16" />

      <layout type="TGLog.ExpandLayout2.ReflectionLayout,TGLog">

         <conversionPattern value="%property{ActionType}" />

      </layout>

  </parameter>

6.1.3程序中如何使用

和一般使用方法基本相同,只是入的参数是一个自定的属性和配置文件中<layout>所有的%property{属性}是一致的,即%property{属性}出的候就message中有无对应的属性,如果有就,没有则输null。例:

log4net.ILog log =log4net.LogManager.GetLogger("ReflectionLayout");

try

            {

                log.Debug(new LogMessage(

1,

"操作象:0",

 (int)TGLog.ActionType.Other,

 "是四个参数测试")

);

            }

            catch(Exception ec)

            {

                log.Error(new LogMessage(

                                    1,

                                    "操作象:0",

                                    (int)TGLog.ActionType.Other,

                                    "是全部参数测试",

                                    "192.168.1.1",

                                    "MyComputer",

                                    "Maxthon(MyIE2)Fans"),

                         ec

);

      }

LogMessage的全部属性的构造方法如下:

public LogMessage(

            int operatorID,

            string operand,

            int ActionType,

            string message,

            string ip,

            string machineName,

            string browser

            )

     {

            this.ActionType= ActionType;

            this.Operator= operatorID;

            this.Message= message;

            this.Operand= operand;

            this.IP= ip;

            this.Browser= browser;

            this.MachineName= machineName;

}

6.2重新实现ILog接口来增加入的参数

6.2.1重写LogImplLogManager实现ILog接口

种方式是通构造一个名IMyLog接口,是Ilog接口而来,然后分MyLogImplMyLogManager重新实现IMyLog接口,增加了每种方法的参数。MyLogImplMyLogManager别继LogImplLogManager而来。

别见8.38.48.5

6.2.2配置相的配置文件

配置文件其他地方不用改,只是需要改<appender>中的<layout>元素nameConversionPatternvalue出格式。例如:

<layout type=" log4net.Layout.PatternLayout ">

        <param name="ConversionPattern"

 value="记录时间%date    操作者ID%property{Operator}             

操作型:%property{Action}%n  消息描述:%property{Message}%n                    异常:%exception%n " />

      </layout>

%property{参数}中的参数在MyLogImpl中定,如句:

loggingEvent.Properties["Operator"]= operatorID;

就定Operator出参数,即%property{Operator}出的即IMyLog中的参数operatorID

数据配置同。例:

<!---->

  <parameter>

      <parameterName value="@action_type" />

      <dbType value="Int16" />

      <layout type=" log4net.Layout.PatternLayout ">

         <conversionPattern value="%property{ActionType}" />

      </layout>

  </parameter>

6.2.3程序中如何使用

先引用IMyLog MyLogManager所在的命名空建一个IMyLog象,myLog个方法,每个方法都有四个重,增加了多参数的重。例:

IMyLog myLog= MyLogManager.GetLogger("ExpandILog");

try

            {

myLog.Debug("是一个参数重载测试!");          

}

            catch(Exception ec)

            {

                log.Error(

                          1,

                          "操作象:0",

                          (int)TGLog.ActionType.Other,

                          "是全部参数测试",

                          "192.168.1.1",

                          "MyComputer",

                          "Maxthon(MyIE2)Fans",

                          ec

);

      }

7总结

Log4net 功能很多,里只是经尝试的功能总结一下,普通写日志已需要注意的是:

1.            Log4net本身也有一些缺陷,比如一个记录引起了log4net本身的异常,就会使后面的日志无法记录下来,尤其是在写入数据库时。例如使用6.1展后,int型的属性在<appender >的元素<bufferSize>置不1<dbType value="Int32" />,就不能出到数据,而<dbType value="Int16" />没任何问题

2.            Log4net本身出了异常,比如配置文件出现错误,有些日志出方式会记录些异常,例如用程序控制台;有些不会错误,如数据与文件。

3.            也会留下一些问题。例如在使用6.1出字段就会出,在log.debug(object message)中,如果message是一个自定,属性与配置文件中置也一致,构造函数也只构造一个参数的例,写文件与写数据都成功,而将message按没有展的方式直接入一个字符串,log.debug(“信息内容”)使用只能写入文件,而数据库则没写入。自定Layout 就是承默PatternLayout,本来不应该,但出问题。原因分析是自定messageint的属性,作一个在默认值0,而直接使用字符串int型的字段得不到默认值,引异常。所以建在有展存在,最好多几个<logger>,区分清楚,按照一的形式记录日志,不要混合使用。

4.            配置文件的置一定要准确,在一点不正确就会致日志不能正常出,所以在配置先从最简单的开始,同时输出方式选择一种能log4net本身异常的方式,成功后一点一点加在新配置,这样了也容易找到那个地方配置有问题

5.            log4net展性很,几乎所有的件都可以重写,在配置文件中配置好就可以使用。

8、附注:

8.1PatterLayout格式化字符表

转换字符

效果

a

等价于appdomain

appdomain

引发日志事件的应用程序域的友好名称。(使用中一般是可执行文件的名字。)

c

等价于 logger

C

等价于 type

class

等价于 type

d

等价于 date

date

发生日志事件的本地时间。 使用 DE>%utcdate 输出UTC时间。date后面还可以跟一个日期格式,用大括号括起来。DE>例如:%date{HH:mm:ss,fff}或者%date{dd MMM yyyy HH:mm:ss,fff}。如果date后面什么也不跟,将使用ISO8601 格式 。

日期格式和.Net中DateTime类的ToString方法中使用的格式是一样。

另外log4net还有3个自己的格式Formatter。 它们是 "ABSOLUTE", "DATE"和"ISO8601"分别代表 AbsoluteTimeDateFormatter, DateTimeDateFormatter和Iso8601DateFormatter。例如:%date{ISO8601}或%date{ABSOLUTE}。

它们的性能要好于ToString。

exception

异常信息

日志事件中必须存了一个异常对象,如果日志事件不包含没有异常对象,将什么也不输出。异常输出完毕后会跟一个换行。一般会在输出异常前加一个换行,并将异常放在最后。

F

等价于 file

file

发生日志请求的源代码文件的名字。

警告:只在调试的时候有效。调用本地信息会影响性能。

identity

当前活动用户的名字(Principal.Identity.Name).

警告:会影响性能。(我测试的时候%identity返回都是空的。)

l

等价于 location

L

等价于 line

location

引发日志事件的方法(包括命名空间和类名),以及所在的源文件和行号。

警告:会影响性能。没有pdb文件的话,只有方法名,没有源文件名和行号。

level

日志事件等级

line

引发日志事件的行号

警告:会影响性能。

logger

记录日志事件的Logger对象的名字。

可以使用精度说明符控制Logger的名字的输出层级,默认输出全名。

注意,精度符的控制是从右开始的。例如:logger 名为 "a.b.c", 输出模型为%logger{2} ,将输出"b.c"。

m

等价于 message

M

等价于 method

message

由应用程序提供给日志事件的消息。

mdc

MDC (旧为:ThreadContext.Properties) 现在是事件属性的一部分。 保留它是为了兼容性,它等价于 property。

method

发生日志请求的方法名(只有方法名而已)。

警告:会影响性能。

n

等价于 newline

newline

换行符

ndc

NDC (nested diagnostic context)

p

等价于 level

P

等价于 property

properties

等价于 property

property

输出事件的特殊属性。例如: %property{user} 输出user属性。属性是由loggers或appenders添加到时间中的。 有一个默认的属性"DE>log4net:HostName"总是会有。DE>

%property将输出所有的属性 。

(扩展后可以使用)

 

r

等价于 timestamp

t

等价于 thread

timestamp

从程序启动到事件发生所经过的毫秒数。

thread

引发日志事件的线程,如果没有线程名就使用线程号。

type

引发日志请求的类的全名。.

可以使用精度控制符。例如: 类名是 "log4net.Layout.PatternLayout", 格式模型是%type{1} 将输出"PatternLayout"。(也是从右开始的。)

警告:会影响性能。

u

等价于 identity

username

当前用户的WindowsIdentity。(类似:HostName/Username)

警告:会影响性能。

utcdate

发生日志事件的UTC时间。DE>后面还可以跟一个日期格式,用大括号括起来。DE>例如:%utcdate{HH:mm:ss,fff}或者%utcdate{dd MMM yyyy HH:mm:ss,fff}。如果utcdate后面什么也不跟,将使用ISO8601 格式 。

日期格式和.Net中DateTime类的ToString方法中使用的格式是一样。

另外log4net还有3个自己的格式Formatter。 它们是 "ABSOLUTE", "DATE"和"ISO8601"分别代表 AbsoluteTimeDateFormatter, DateTimeDateFormatter和Iso8601DateFormatter。例如:%date{ISO8601}或%date{ABSOLUTE}。

它们的性能要好于ToString。

w

等价于 username

x

等价于 ndc

X

等价于 mdc

%

%%输出一个百分号

关于用本地信息(callerlocation information)的明:

%type %file %line %method%location %class %C %F %L %l %M 都会用本地信息。这样做会影响性能。本地信息使用System.Diagnostics.StackTrace得到。.Net1.0 不支持System.Diagnostics.StackTrace 

本地信息在调试模式下可以正常取,在非调试模式下可能取不到,或只能取一部分。(根据我的测试,其是需要有一个程序数据.pdb)文件。

%property属性要用代置才能使用(也就展一下),

属性log4net:HostName不用置。

转义字符的修符:

Format modifier

left justify

minimum width

maximum width

comment

%20logger

false

20

none

如果logger名不足20个字符,就在左边补空格。

%-20logger

true

20

none

如果logger名不足20个字符,就在右边补空格。

%.30logger

NA

none

30

超过30个字符将截断。

%20.30logger

false

20

30

logger名要在20到30之间,少了在左边补空格,多了截断。

%-20.30logger

true

20

30

logger名要在20到30之间,少了在右边补空格,多了截断。

8.2Layout

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using log4net.Layout;

using log4net.Layout.Pattern;

using System.Reflection;

using System.Collections;

using FastReflectionLib;

 

namespace TGLog.ExpandLayout2

{

    public class ReflectionLayout : PatternLayout

    {

        public ReflectionLayout()

        {

            this.AddConverter("property", typeof(ReflectionPatternConverter));

        }

    }

 

    public class ReflectionPatternConverter : PatternLayoutConverter

    {

        protected override void Convert(

System.IO.TextWriter writer,

 log4net.Core.LoggingEvent loggingEvent

)

        {

            if (Option!= null)

            {

                // 写入指定

                WriteObject(

writer,

 loggingEvent.Repository,

 LookupProperty(Option,

 loggingEvent)

);

            }

            else

            {

                // 写入所有关键值对

                WriteDictionary(

writer,

loggingEvent.Repository,

 loggingEvent.GetProperties()

);

            }

        }

 

        /// <summary>

        /// 反射入的日志象的某个属性的

        /// </summary>

        /// <paramname="property"></param>

        /// <returns></returns>

        private object LookupProperty(

string property,

 log4net.Core.LoggingEvent loggingEvent)

        {

            object propertyValue= string.Empty;

 

            PropertyInfo propertyInfo=

loggingEvent.MessageObject.GetType().GetProperty(property);

            if (propertyInfo!= null)

            {

                propertyValue=

propertyInfo.GetValue(loggingEvent.MessageObject, null);

            }

            return propertyValue;

        }

    }

}

8.3 MyLogImpl

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using log4net.Core;

 

namespace TGLog.ExpandILog

{

    public class MyLogImpl : LogImpl, IMyLog

    {

        /// <summary>

        /// Thefully qualified name of this declaring type not the type of any subclass.

        /// </summary>

        private readonly static Type ThisDeclaringType= typeof(MyLogImpl);

 

        public MyLogImpl(ILogger logger)

            : base(logger)

        {       

        }

 

        #region Implementationof IMyLog

 

        public void Debug(int operatorID, string operand, int actionType,object message,

 string ip, string browser, string machineName)

        {

            Debug(operatorID,  operand,  actionType,message,

  ip,  browser,machineName, null);

        }

 

        public void Debug(int operatorID, string operand, int actionType,object message,

string ip, string browser, string machineName,System.Exception t)

        {

            if (this.IsDebugEnabled)

            {

                LoggingEvent loggingEvent=

new LoggingEvent(ThisDeclaringType,Logger.Repository,

                                       Logger.Name, Level.Info,message, t);

                loggingEvent.Properties["Operator"]= operatorID;

                loggingEvent.Properties["Operand"]= operand;

                loggingEvent.Properties["ActionType"]= actionType;

                loggingEvent.Properties["IP"]= ip;

                loggingEvent.Properties["Browser"]= browser;

                loggingEvent.Properties["MachineName"]= machineName;

                Logger.Log(loggingEvent);

            }

        }

 

        public void Info(int operatorID, string operand, int actionType, object message,

string ip, string browser, string machineName)

        {

            Info(operatorID,operand, actionType, message, ip, browser, machineName, null);

        }

 

        public void Info(int operatorID, string operand, int actionType, object message,

 string ip, string browser, string machineName,System.Exception t)

        {

            if (this.IsInfoEnabled)

            {

                LoggingEvent loggingEvent=

 new LoggingEvent(ThisDeclaringType,Logger.Repository,

 Logger.Name, Level.Info,message, t);

                loggingEvent.Properties["Operator"]= operatorID;

                loggingEvent.Properties["Operand"]= operand;

                loggingEvent.Properties["ActionType"]= actionType;

                loggingEvent.Properties["IP"]= ip;

                loggingEvent.Properties["Browser"]= browser;

                loggingEvent.Properties["MachineName"]= machineName;

                Logger.Log(loggingEvent);

            }

        }

 

        public void Warn(int operatorID, string operand, int actionType, object message,

string ip, string browser, string machineName)

        {

            Warn(operatorID,operand, actionType, message, ip, browser, machineName, null);

        }

 

        public void Warn(int operatorID, string operand, int actionType, object message,

 string ip, string browser, string machineName,System.Exception t)

        {

            if (this.IsWarnEnabled)

            {

                LoggingEvent loggingEvent=

 new LoggingEvent(ThisDeclaringType,Logger.Repository,

Logger.Name, Level.Info,message, t);

                loggingEvent.Properties["Operator"]= operatorID;

                loggingEvent.Properties["Operand"]= operand;

                loggingEvent.Properties["ActionType"]= actionType;

                loggingEvent.Properties["IP"]= ip;

                loggingEvent.Properties["Browser"]= browser;

                loggingEvent.Properties["MachineName"]= machineName;

                Logger.Log(loggingEvent);

            }

        }

 

        public void Error(int operatorID, string operand, int actionType, object message,

string ip, string browser, string machineName)

        {

            Error(operatorID,operand, actionType, message, ip, browser, machineName, null);

        }

 

        public void Error(int operatorID, string operand, int actionType, object message,

 string ip, string browser, string machineName,System.Exception t)

        {

            if (this.IsErrorEnabled)

            {

                LoggingEvent loggingEvent=

 new LoggingEvent(ThisDeclaringType,Logger.Repository,

 Logger.Name, Level.Info,message, t);

                loggingEvent.Properties["Operator"]= operatorID;

                loggingEvent.Properties["Operand"]= operand;

                loggingEvent.Properties["ActionType"]= actionType;

                loggingEvent.Properties["IP"]= ip;

                loggingEvent.Properties["Browser"]= browser;

                loggingEvent.Properties["MachineName"]= machineName;

                Logger.Log(loggingEvent);

            }

        }

 

        public void Fatal(int operatorID, string operand, int actionType, object message,

 string ip, string browser, string machineName)

        {

            Fatal(operatorID,operand, actionType, message, ip, browser, machineName, null);

        }

 

        public void Fatal(int operatorID, string operand, int actionType, object message,

 string ip, string browser, string machineName,System.Exception t)

        {

            if (this.IsFatalEnabled)

            {

                LoggingEvent loggingEvent=

 new LoggingEvent(ThisDeclaringType,Logger.Repository,

                                       Logger.Name, Level.Info,message, t);

                loggingEvent.Properties["Operator"]= operatorID;

                loggingEvent.Properties["Operand"]= operand;

                loggingEvent.Properties["ActionType"]= actionType;

                loggingEvent.Properties["IP"]= ip;

                loggingEvent.Properties["Browser"]= browser;

                loggingEvent.Properties["MachineName"]= machineName;

                Logger.Log(loggingEvent);

            }

        }

        #endregion Implementationof IMyLog

    }

}

 

8.4 MyLogManager

#region Copyright &License

//

// Copyright 2001-2005 TheApache Software Foundation

//

// Licensed under the ApacheLicense, Version 2.0 (the "License");

// you may not use this fileexcept in compliance with the License.

// You may obtain a copy of theLicense at

//

//http://www.apache.org/licenses/LICENSE-2.0

//

// Unless required by applicablelaw or agreed to in writing, software

// distributed under the Licenseis distributed on an "AS IS" BASIS,

// WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.

// See the License for thespecific language governing permissions and

// limitations under theLicense.

//

#endregion

 

using System;

using System.Reflection;

using System.Collections;

using log4net;

using log4net.Core;

using log4net.Repository;

using log4net.Repository.Hierarchy;

 

namespace TGLog.ExpandILog

{

    public class MyLogManager

    {

        #region StaticMember Variables

 

        /// <summary>

        /// Thewrapper map to use to hold the <seecref="EventIDLogImpl"/> objects

        /// </summary>

        private static readonly WrapperMap s_wrapperMap= new WrapperMap(newWrapperCreationHandler(WrapperCreationHandler));

 

        #endregion

 

        #region Constructor

 

        /// <summary>

        /// Privateconstructor to prevent object creation

        /// </summary>

        private MyLogManager(){ }

 

        #endregion

 

        #region TypeSpecific Manager Methods

 

        /// <summary>

        /// Returnsthe named logger if it exists

        /// </summary>

        /// <remarks>

        /// <para>Ifthe named logger exists (in the default hierarchy) then it

        /// returnsa reference to the logger, otherwise it returns

        /// <c>null</c>.</para>

        /// </remarks>

        /// <paramname="name">The fully qualified logger name to lookfor</param>

        /// <returns>Thelogger found, or null</returns>

        public static IMyLog Exists(string name)

        {

            return Exists(Assembly.GetCallingAssembly(),name);

        }

 

        /// <summary>

        /// Returnsthe named logger if it exists

        /// </summary>

        /// <remarks>

        /// <para>Ifthe named logger exists (in the specified domain) then it

        /// returnsa reference to the logger, otherwise it returns

        /// <c>null</c>.</para>

        /// </remarks>

        /// <paramname="domain">the domain to lookup in</param>

        /// <paramname="name">The fully qualified logger name to lookfor</param>

        /// <returns>Thelogger found, or null</returns>

        public static IMyLog Exists(string domain, string name)

        {

            return WrapLogger(LoggerManager.Exists(domain,name));

        }

 

        /// <summary>

        /// Returnsthe named logger if it exists

        /// </summary>

        /// <remarks>

        /// <para>Ifthe named logger exists (in the specified assembly's domain) then it

        /// returnsa reference to the logger, otherwise it returns

        /// <c>null</c>.</para>

        /// </remarks>

        /// <paramname="assembly">the assembly to use to lookup thedomain</param>

        /// <paramname="name">The fully qualified logger name to lookfor</param>

        /// <returns>Thelogger found, or null</returns>

        public static IMyLog Exists(Assembly assembly, string name)

        {

            return WrapLogger(LoggerManager.Exists(assembly,name));

        }

 

        /// <summary>

        /// Returnsall the currently defined loggers in the default domain.

        /// </summary>

        /// <remarks>

        /// <para>Theroot logger is <b>not</b> included in the returnedarray.</para>

        /// </remarks>

        /// <returns>Allthe defined loggers</returns>

        public static IMyLog[]GetCurrentLoggers()

        {

            return GetCurrentLoggers(Assembly.GetCallingAssembly());

        }

 

        /// <summary>

        /// Returnsall the currently defined loggers in the specified domain.

        /// </summary>

        /// <paramname="domain">the domain to lookup in</param>

        /// <remarks>

        /// Theroot logger is <b>not</b> included in the returned array.

        /// </remarks>

        /// <returns>Allthe defined loggers</returns>

        public static IMyLog[]GetCurrentLoggers(string domain)

        {

            return WrapLoggers(LoggerManager.GetCurrentLoggers(domain));

        }

 

        /// <summary>

        /// Returnsall the currently defined loggers in the specified assembly's domain.

        /// </summary>

        /// <paramname="assembly">the assembly to use to lookup thedomain</param>

        /// <remarks>

        /// Theroot logger is <b>not</b> included in the returned array.

        /// </remarks>

        /// <returns>Allthe defined loggers</returns>

        public static IMyLog[]GetCurrentLoggers(Assembly assembly)

        {

            return WrapLoggers(LoggerManager.GetCurrentLoggers(assembly));

        }

 

        /// <summary>

        /// Retrieveor create a named logger.

        /// </summary>

        /// <remarks>

        /// <para>Retrievea logger named as the <paramref name="name"/>

        /// parameter.If the named logger already exists, then the

        /// existinginstance will be returned. Otherwise, a new instance is

        /// created.</para>

        ///

        /// <para>Bydefault, loggers do not have a set level but inherit

        /// itfrom the hierarchy. This is one of the central features of

        /// log4net.</para>

        /// </remarks>

        /// <paramname="name">The name of the logger to retrieve.</param>

        /// <returns>thelogger with the name specified</returns>

        public static IMyLog GetLogger(string name)

        {

            return GetLogger(Assembly.GetCallingAssembly(),name);

        }

 

        /// <summary>

        /// Retrieveor create a named logger.

        /// </summary>

        /// <remarks>

        /// <para>Retrievea logger named as the <paramref name="name"/>

        /// parameter.If the named logger already exists, then the

        /// existinginstance will be returned. Otherwise, a new instance is

        /// created.</para>

        ///

        /// <para>Bydefault, loggers do not have a set level but inherit

        /// itfrom the hierarchy. This is one of the central features of

        /// log4net.</para>

        /// </remarks>

        /// <paramname="domain">the domain to lookup in</param>

        /// <paramname="name">The name of the logger to retrieve.</param>

        /// <returns>thelogger with the name specified</returns>

        public static IMyLog GetLogger(string domain, string name)

        {

            return WrapLogger(LoggerManager.GetLogger(domain,name));

        }

 

        /// <summary>

        /// Retrieveor create a named logger.

        /// </summary>

        /// <remarks>

        /// <para>Retrievea logger named as the <paramref name="name"/>

        /// parameter.If the named logger already exists, then the

        /// existinginstance will be returned. Otherwise, a new instance is

        /// created.</para>

        ///

        /// <para>Bydefault, loggers do not have a set level but inherit

        /// itfrom the hierarchy. This is one of the central features of

        /// log4net.</para>

        /// </remarks>

        /// <paramname="assembly">the assembly to use to lookup the domain</param>

        /// <paramname="name">The name of the logger to retrieve.</param>

        /// <returns>thelogger with the name specified</returns>

        public static IMyLog GetLogger(Assembly assembly, string name)

        {

            return WrapLogger(LoggerManager.GetLogger(assembly,name));

        }

 

        /// <summary>

        /// Shorthandfor <see cref="LogManager.GetLogger(string)"/>.

        /// </summary>

        /// <remarks>

        /// Getthe logger for the fully qualified name of the type specified.

        /// </remarks>

        /// <paramname="type">The full name of <paramrefname="type"/> will

        /// beused as the name of the logger to retrieve.</param>

        /// <returns>thelogger with the name specified</returns>

        public static IMyLog GetLogger(Type type)

        {

            return GetLogger(Assembly.GetCallingAssembly(),type.FullName);

        }

 

        /// <summary>

        /// Shorthandfor <see cref="LogManager.GetLogger(string)"/>.

        /// </summary>

        /// <remarks>

        /// Getthe logger for the fully qualified name of the type specified.

        /// </remarks>

        /// <paramname="domain">the domain to lookup in</param>

        /// <paramname="type">The full name of <paramrefname="type"/> will

        /// beused as the name of the logger to retrieve.</param>

        /// <returns>thelogger with the name specified</returns>

        public static IMyLog GetLogger(string domain, Type type)

        {

            return WrapLogger(LoggerManager.GetLogger(domain,type));

        }

 

        /// <summary>

        /// Shorthandfor <see cref="LogManager.GetLogger(string)"/>.

        /// </summary>

        /// <remarks>

        /// Getthe logger for the fully qualified name of the type specified.

        /// </remarks>

        /// <paramname="assembly">the assembly to use to lookup thedomain</param>

        /// <paramname="type">The full name of <paramrefname="type"/> will

        /// beused as the name of the logger to retrieve.</param>

        /// <returns>thelogger with the name specified</returns>

        public static IMyLog GetLogger(Assembly assembly, Type type)

        {

            return WrapLogger(LoggerManager.GetLogger(assembly,type));

        }

 

        #endregion

 

        #region ExtensionHandlers

 

        /// <summary>

        /// Lookupthe wrapper object for the logger specified

        /// </summary>

        /// <paramname="logger">the logger to get the wrapper for</param>

        /// <returns>thewrapper for the logger specified</returns>

        private static IMyLog WrapLogger(ILogger logger)

        {

            return (IMyLog)s_wrapperMap.GetWrapper(logger);

        }

 

        /// <summary>

        /// Lookupthe wrapper objects for the loggers specified

        /// </summary>

        /// <paramname="loggers">the loggers to get the wrappers for</param>

        /// <returns>Lookupthe wrapper objects for the loggers specified</returns>

        private static IMyLog[]WrapLoggers(ILogger[] loggers)

        {

            IMyLog[]results = new IMyLog[loggers.Length];

            for (int i= 0; i < loggers.Length; i++)

            {

                results[i]= WrapLogger(loggers[i]);

            }

            return results;

        }

 

        /// <summary>

        /// Methodto create the <see cref="ILoggerWrapper"/> objectsused by

        /// thismanager.

        /// </summary>

        /// <paramname="logger">The logger to wrap</param>

        /// <returns>Thewrapper for the logger specified</returns>

        private static ILoggerWrapper WrapperCreationHandler(ILogger logger)

        {

            return new MyLogImpl(logger);

        }

        #endregion

    }

}

8.5 IMyLog

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using log4net;

 

namespace TGLog.ExpandILog

{

    public interface IMyLog : ILog

    {

        void Debug(int operatorID, string operand, int actionType, object message,

string ip, string browser, string machineName);

        void Debug(int operatorID, string operand, int actionType,object message,

string ip, string browser, string machineName, Exception t);

 

        void Info(int operatorID, string operand, int actionType, object message,

string ip, string browser, string machineName);

        void Info(int operatorID, string operand, int actionType, object message,

string ip, string browser, string machineName, Exception t);

 

        void Warn(int operatorID, string operand, int actionType, object message,

string ip, string browser, string machineName);

        void Warn(int operatorID, string operand, int actionType, object message,

 string ip, string browser, string machineName, Exception t);

 

        void Error(int operatorID, string operand, int actionType, object message,

string ip, string browser, string machineName);

        void Error(int operatorID, string operand, int actionType, object message,

string ip, string browser, string machineName, Exception t);

 

        void Fatal(int operatorID, string operand, int actionType, object message,

string ip, string browser, string machineName);

        void Fatal(int operatorID, string operand, int actionType, object message,

string ip, string browser, string machineName, Exception t);

    }

}

8.6附件

使用log4net记录日志

8.7参考

1http://peibing211.blog.163.com/blog/static/37116360200992811595469/

2http://www.cnblogs.com/qiangzi/archive/2009/09/10/1541023.html

3http://blog.chinaunix.net/u/23701/showart_1414206.html

4http://itrust.cnblogs.com/archive/2005/01/25/97225.html

5http://www.cnitblog.com/seeyeah/archive/2009/09/20/61491.aspx

6http://www.cnblogs.com/zhmore/archive/2009/03/19/1416707.html

7http://blog.shinylife.net/blog/article.asp?id=948

8http://www.cnblogs.com/manhoo/archive/2009/06/25/1511066.html

猜你喜欢

转载自blog.csdn.net/wjgwrr/article/details/80324309
今日推荐