log4net之应用

目前项目中用到这一块的内容通过几天的学习和实践,终于了解了其中的使用方式,对于自己2年前还一直学习这个仍是头大的境况终于能够彻底说拜拜了。

先列出博客园中重要链接,后续在跟进我的理解来说明重要的内容。

链接如下:http://www.cnblogs.com/zhangchenliang/p/4546352.html 作者 :Danny Chen 非常感谢: Danny Chen

先列出相关重要内容如下:

1.配置文件路径设置

配置xml路径的问题,有时候一直是初学者比较头疼的问题,我也是在最初学习时,被这个问题弄的不知所以。现在分两种情况来说明。

a.配置型

所谓配置型,就是要想log能起作用(正确写入存入介质中),需要的代码完全是按照xml格式般配置好。其实就是按照C#特性要求来实现

如:AssemblyInfo.cs 中添加 

[assembly: log4net.Config .XmlConfigurator()] or
[assembly: log4net.Config .XmlConfigurator(ConfigFile="log4net.config")] or
[assembly: log4net.Config .XmlConfigurator(ConfigFileExtension="config")]
b.代码型
log4net.Config.XmlConfigurator.Configure(); or

log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(System.Web.HttpContext.Current.Server.MapPath("../Log4Net.config"))); //web

log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo("../Log4Net.config")); //app

 项目启动运行记录日志时,可以用下面代码:

ILogger log=log4net.LogManager.GetLogger("testApp.Logging")
log.Info("message");

2.Configuration 配置

关于Configuration 的配置很简单,可以查看一下前面对该部分的引用链接。但主要结构为:

<log4net>
<appender>
    <param/>
    <layout></layout>
</appender>
<root></root>
<logger></logger><!--可以有多个-->
</log4net>

从上面结构对比下面具体的设置。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
<log4net>
    <root>
      <level value="ALL" />
      <appender-ref ref="console" />
      <appender-ref ref="file" />
    </root>
    <appender name="console" type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %level %logger - %message%newline" />
      </layout>
    </appender>
    <appender name="file" type="log4net.Appender.RollingFileAppender">
      <file value="myapp.log" />
      <appendToFile value="true" />
      <rollingStyle value="Size" />
      <maxSizeRollBackups value="5" />
      <maximumFileSize value="10MB" />
      <staticLogFileName value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
      </layout>
    </appender>
  </log4net>

3.Appender(文本、数据库)、Layout、Logger等说明

a. Appender 文本:具体的可以看注释:

<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" />
      <!--按日期产生文件夹和文件名[在日期方式与混合方式下使用]-->
<!—此处按日期产生文件夹,文件名固定。注意&quot; 的位置-->
      <param name="DatePattern" value="yyyy-MM-dd/&quot;ReflectionLayout.log&quot;"  />
<!—这是按日期产生文件夹,并在文件名前也加上日期-->
      <param name="DatePattern" value="yyyyMMdd/yyyyMMdd&quot;-TimerServer.log&quot;"  />
<!—这是先按日期产生文件夹,再形成下一级固定的文件夹—>
     <param name="DatePattern" value="yyyyMMdd/&quot;TimerServer/TimerServer.log&quot;"  />
      <!--每个文件的大小。只在混合方式与文件大小方式下使用。
超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。
可用的单位: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>

b.Appender 数据库:

<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender,log4net">
<!--BufferSize为缓冲区大小,只有日志记录超设定值才会一块写入到数据库-->
<bufferSize value="10" /><!—或写为<param name="BufferSize" value="10" />--> 
<!--引用-->
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<!--连接数据库字符串-->
<connectionString value="data source=.;initial catalog=Test;integrated security=false;persist security info=True;User ID=sa;Password=;" />
<!--插入到表Log-->
<commandText value="INSERT INTO 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>

c.Layout 

这里主要是将layout 的type 和ConversionPattern

Type表示布局文件的格式。PatternLayout 是最基础的类型,其实还有很多。

Layout用于控制Appender的输出格式,可以使线性的也可以使XML。一个Appender只能有一个Layout。

最常用的Layout应该是用户自定义格式的PatternLayout,其次是SimpleLayout和ExceptionLayout。然后还有4个Layout,其中有两个是输出Xml的Layout,但是中文会有问题。

conversionPattern 的Value可以用下面的链接来学习:Layout 日志格式规则

<layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%location" />
        </layout>

d.Logger

解释:logger中ref 表示appder 的name ,即日志存储的介质所使用的配置是什么。

          logger中name 表示 启动日志存储的方法的名称:LogManager.GetLogger("ReflectionLayout") ,代码中 ReflectionLayout 要与配置的名称一致,这样表示用什么logger 去处理日志信息了。

<logger name="ReflectionLayout">
      <level value="DEBUG"/>
      <appender-ref ref="HashtableLayout"/>
      <appender-ref ref="ReflectionLayout"/>
      <appender-ref ref="ADONetAppender"/>
</logger>

4.自定义Appender与Layout说明

自定义Appender 和layout 如何是将日志存入数据库中 ,下面链接是最后的例子:

自定义日志存入数据库中案例

下面是实际案例源码:案例源码 主要是借鉴其他博友的,再次特别感谢。

5.特殊说明

Tips:特殊说明:其中对于Layout 中ConvertPattern 中自定义字段的部分需要主要了。

如果你是 this.AddConverter("property", typeof(ReflectionPatternConverter)); 添加的,那么 需要用 %property{Brower}等来表示,Brower可替换成对应字段。

如果你是 this.AddConverter("Brower", typeof(ReflectionPatternConverter)); 添加的,那么 需要用 %Brower 等来表示,Brower可替换成对应字段,前提是你替换的字段也如同Brower一下利用AddConverter进行了添加转化了。

好了。今天就先到这里了。

重点说明一下源码中的内容:我对于 源码中MyLog-->ILog ,MyImpl-->Impl, MyLogManager-->LogManager这部分有些理解不到位,如果给位读者有更新的想法,可以和我多沟通。

原文地址:https://www.cnblogs.com/zhaosw/p/7653410.html