当前位置: 移动技术网 > IT编程>开发语言>.net > 基于Log4Net本地日志服务简单实现

基于Log4Net本地日志服务简单实现

2019年04月11日  | 移动技术网IT编程  | 我要评论

qq邮箱登陆界面,一路向西电影完整版快播,朝鲜深夜疑射导弹

背景

  1. 项目开发中,我们或多或少会使用诸如nlog,log4net,kafka+elk等等日志套件;

  2. 基于关注点分离原则,业务开发的时候不应该关注日志具体实现;并且后续能方便切换其他日志套件;

  3. 这里先实现基于文件的日志服务,在下一篇将实现基于kafka+elk;

  4. 具体源码:masterchief

  5. nuget:install-package masterchief.dotnet.core.log

  6. 欢迎star,欢迎issues;

日志接口定义

/// <summary>
///     日志记录接口
/// </summary>
public interface ilogservice
{
    #region methods
 
    /// <summary>
    ///     debug记录
    /// </summary>
    /// <param name="message">日志信息</param>
    void debug(string message);
 
    /// <summary>
    ///     debug记录
    /// </summary>
    /// <param name="message">日志信息</param>
    /// <param name="ex">异常信息</param>
    void debug(string message, exception ex);
 
    /// <summary>
    ///     error记录
    /// </summary>
    /// <param name="message">日志信息</param>
    void error(string message);
 
    /// <summary>
    ///     error记录
    /// </summary>
    /// <param name="message">日志信息</param>
    /// <param name="ex">异常信息</param>
    void error(string message, exception ex);
 
    /// <summary>
    ///     fatal记录
    /// </summary>
    /// <param name="message">日志信息</param>
    void fatal(string message);
 
    /// <summary>
    ///     fatal记录
    /// </summary>
    /// <param name="message">日志信息</param>
    /// <param name="ex">异常信息</param>
    void fatal(string message, exception ex);
 
    /// <summary>
    ///     info记录
    /// </summary>
    /// <param name="message">日志信息</param>
    void info(string message);
 
    /// <summary>
    ///     info记录
    /// </summary>
    /// <param name="message">日志信息</param>
    /// <param name="ex">异常信息</param>
    void info(string message, exception ex);
 
    /// <summary>
    ///     warn记录
    /// </summary>
    /// <param name="message">日志信息</param>
    void warn(string message);
 
    /// <summary>
    ///     warn记录
    /// </summary>
    /// <param name="message">日志信息</param>
    /// <param name="ex">异常信息</param>
    void warn(string message, exception ex);
 
    #endregion methods
}

基于log4net本地文件日志服务实现

/// <summary>
///     基于log4net的文件日志记录
/// </summary>
public sealed class filelogservice : ilogservice
{
    #region constructors
 
    static filelogservice()
    {
        debuglogger = logmanager.getlogger(debugloggername);
        infologger = logmanager.getlogger(infologgername);
        warnlogger = logmanager.getlogger(warnloggername);
        errorlogger = logmanager.getlogger(errorloggername);
        fatallogger = logmanager.getlogger(fatalloggername);
    }
 
    #endregion constructors
 
    #region fields
 
    /// <summary>
    ///     the debug logger name
    /// </summary>
    public const string debugloggername = "debug_filelogger";
 
    /// <summary>
    ///     the error logger name
    /// </summary>
    public const string errorloggername = "error_filelogger";
 
    /// <summary>
    ///     the fatal logger name
    /// </summary>
    public const string fatalloggername = "fatal_filelogger";
 
    /// <summary>
    ///     the information logger name
    /// </summary>
    public const string infologgername = "info_filelogger";
 
    /// <summary>
    ///     the warn logger name
    /// </summary>
    public const string warnloggername = "warn_filelogger";
 
    /// <summary>
    ///     the debug logger
    /// </summary>
    public static readonly ilog debuglogger;
 
    /// <summary>
    ///     the error logger
    /// </summary>
    public static readonly ilog errorlogger;
 
    /// <summary>
    ///     the fatal logger
    /// </summary>
    public static readonly ilog fatallogger;
 
    /// <summary>
    ///     the information logger
    /// </summary>
    public static readonly ilog infologger;
 
    /// <summary>
    ///     the warn logger
    /// </summary>
    public static readonly ilog warnlogger;
 
    #endregion fields
 
    #region methods
 
    /// <summary>
    ///     debug记录
    /// </summary>
    /// <param name="message">日志信息</param>
    public void debug(string message)
    {
        if (debuglogger.isdebugenabled) debuglogger.debug(message);
    }
 
    /// <summary>
    ///     debug记录
    /// </summary>
    /// <param name="message">日志信息</param>
    /// <param name="ex">异常信息</param>
    public void debug(string message, exception ex)
    {
        if (debuglogger.isdebugenabled) debuglogger.debug(message, ex);
    }
 
    /// <summary>
    ///     error记录
    /// </summary>
    /// <param name="message">日志信息</param>
    public void error(string message)
    {
        if (errorlogger.iserrorenabled) errorlogger.error(message);
    }
 
    /// <summary>
    ///     error记录
    /// </summary>
    /// <param name="message">日志信息</param>
    /// <param name="ex">异常信息</param>
    public void error(string message, exception ex)
    {
        if (errorlogger.iserrorenabled) errorlogger.error(message, ex);
    }
 
    /// <summary>
    ///     fatal记录
    /// </summary>
    /// <param name="message">日志信息</param>
    public void fatal(string message)
    {
        if (fatallogger.isfatalenabled) fatallogger.fatal(message);
    }
 
    /// <summary>
    ///     fatal记录
    /// </summary>
    /// <param name="message">日志信息</param>
    /// <param name="ex">异常信息</param>
    public void fatal(string message, exception ex)
    {
        if (fatallogger.isfatalenabled) fatallogger.fatal(message, ex);
    }
 
    /// <summary>
    ///     info记录
    /// </summary>
    /// <param name="message">日志信息</param>
    public void info(string message)
    {
        if (infologger.isinfoenabled) infologger.info(message);
    }
 
    /// <summary>
    ///     info记录
    /// </summary>
    /// <param name="message">日志信息</param>
    /// <param name="ex">异常信息</param>
    public void info(string message, exception ex)
    {
        if (infologger.isinfoenabled) infologger.info(message, ex);
    }
 
    /// <summary>
    ///     warn记录
    /// </summary>
    /// <param name="message">日志信息</param>
    public void warn(string message)
    {
        if (warnlogger.iswarnenabled) warnlogger.warn(message);
    }
 
    /// <summary>
    ///     warn记录
    /// </summary>
    /// <param name="message">日志信息</param>
    /// <param name="ex">异常信息</param>
    public void warn(string message, exception ex)
    {
        if (warnlogger.iswarnenabled) warnlogger.warn(message, ex);
    }
 
    #endregion methods
}

log4net 配置文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configsections>
    <section name="log4net" type="log4net.config.log4netconfigurationsectionhandler" />
  </configsections>
  <log4net>
    <!-- filelogger -->
    <logger name="fatal_filelogger">
      <level value="all" />
      <appender-ref ref="fatal_fileappender" />
    </logger>
    <logger name="error_filelogger">
      <level value="all" />
      <appender-ref ref="error_fileappender" />
    </logger>
    <logger name="warn_filelogger">
      <level value="all" />
      <appender-ref ref="warn_fileappender" />
    </logger>
    <logger name="info_filelogger">
      <level value="all" />
      <appender-ref ref="info_fileappender" />
    </logger>
    <logger name="debug_filelogger">
      <level value="all" />
      <appender-ref ref="debug_fileappender" />
    </logger>
    <!-- adonetlogger -->
    <!--<logger name="adonetlogger">
      <level value="all" />
      <appender-ref ref="adonetappender" />
    </logger>-->
    <!-- consolelogger -->
    <logger name="consolelogger">
      <level value="all" />
      <appender-ref ref="coloredconsoleappender" />
    </logger>
 
    <!--使用rolling方式记录日志按照日来记录日志-->
    <appender name="fatal_fileappender" type="log4net.appender.rollingfileappender">
      <!--文件名,可以相对路径,也可以绝对路径,这里只给定了文件夹-->
      <file value=".\log\\fatal\\" />
      <!--是否增加文件-->
      <appendtofile value="true" />
      <maxsizerollbackups value="5" />
      <!--日志追加类型,date为按日期增加文件,size为按大小-->
      <rollingstyle value="date" />
      <!--最小锁定模型以允许多个进程可以写入同一个文件,解决文件独占问题-->
      <lockingmodel type="log4net.appender.fileappender+minimallock" />
      <!--最大文件大小-->
      <maximumfilesize value="10mb" />
      <!--文件命名格式,非日期参数化要进行转义,如自定义文件后缀-->
      <datepattern value="yyyymm\\yyyy-mm-dd&quot;.log&quot;" />
      <!--是否固定文件名-->
      <staticlogfilename value="false" />
      <layout type="log4net.layout.patternlayout">
        <conversionpattern value="---------------------------------------------------%newline发生时间:%date %newline事件级别:%-5level %newline事件来源:%logger%newline日志内容:%message%newline" />
      </layout>
    </appender>
    <appender name="error_fileappender" type="log4net.appender.rollingfileappender">
      <!--文件名,可以相对路径,也可以绝对路径,这里只给定了文件夹-->
      <file value=".\log\\error\\" />
      <!--是否增加文件-->
      <appendtofile value="true" />
      <maxsizerollbackups value="5" />
      <!--日志追加类型,date为按日期增加文件,size为按大小-->
      <rollingstyle value="date" />
      <!--最小锁定模型以允许多个进程可以写入同一个文件,解决文件独占问题-->
      <lockingmodel type="log4net.appender.fileappender+minimallock" />
      <!--最大文件大小-->
      <maximumfilesize value="10mb" />
      <!--文件命名格式,非日期参数化要进行转义,如自定义文件后缀-->
      <datepattern value="yyyymm\\yyyy-mm-dd&quot;.log&quot;" />
      <!--是否固定文件名-->
      <staticlogfilename value="false" />
      <layout type="log4net.layout.patternlayout">
        <conversionpattern value="---------------------------------------------------%newline发生时间:%date %newline事件级别:%-5level %newline事件来源:%logger%newline日志内容:%message%newline" />
      </layout>
    </appender>
    <appender name="warn_fileappender" type="log4net.appender.rollingfileappender">
      <!--文件名,可以相对路径,也可以绝对路径,这里只给定了文件夹-->
      <file value=".\log\\warn\\" />
      <!--是否增加文件-->
      <appendtofile value="true" />
      <maxsizerollbackups value="5" />
      <!--日志追加类型,date为按日期增加文件,size为按大小-->
      <rollingstyle value="date" />
      <!--最小锁定模型以允许多个进程可以写入同一个文件,解决文件独占问题-->
      <lockingmodel type="log4net.appender.fileappender+minimallock" />
      <!--最大文件大小-->
      <maximumfilesize value="10mb" />
      <!--文件命名格式,非日期参数化要进行转义,如自定义文件后缀-->
      <datepattern value="yyyymm\\yyyy-mm-dd&quot;.log&quot;" />
      <!--是否固定文件名-->
      <staticlogfilename value="false" />
      <layout type="log4net.layout.patternlayout">
        <conversionpattern value="---------------------------------------------------%newline发生时间:%date %newline事件级别:%-5level %newline事件来源:%logger%newline日志内容:%message%newline" />
      </layout>
    </appender>
    <appender name="info_fileappender" type="log4net.appender.rollingfileappender">
      <!--文件名,可以相对路径,也可以绝对路径,这里只给定了文件夹-->
      <file value=".\log\\info\\" />
      <!--是否增加文件-->
      <appendtofile value="true" />
      <maxsizerollbackups value="5" />
      <!--日志追加类型,date为按日期增加文件,size为按大小-->
      <rollingstyle value="date" />
      <!--最小锁定模型以允许多个进程可以写入同一个文件,解决文件独占问题-->
      <lockingmodel type="log4net.appender.fileappender+minimallock" />
      <!--最大文件大小-->
      <maximumfilesize value="10mb" />
      <!--文件命名格式,非日期参数化要进行转义,如自定义文件后缀-->
      <datepattern value="yyyymm\\yyyy-mm-dd&quot;.log&quot;" />
      <!--是否固定文件名-->
      <staticlogfilename value="false" />
      <layout type="log4net.layout.patternlayout">
        <conversionpattern value="---------------------------------------------------%newline发生时间:%date %newline事件级别:%-5level %newline事件来源:%logger%newline日志内容:%message%newline" />
      </layout>
    </appender>
    <appender name="debug_fileappender" type="log4net.appender.rollingfileappender">
      <!--文件名,可以相对路径,也可以绝对路径,这里只给定了文件夹-->
      <file value=".\log\\debug\\" />
      <!--是否增加文件-->
      <appendtofile value="true" />
      <maxsizerollbackups value="5" />
      <!--日志追加类型,date为按日期增加文件,size为按大小-->
      <rollingstyle value="date" />
      <!--最小锁定模型以允许多个进程可以写入同一个文件,解决文件独占问题-->
      <lockingmodel type="log4net.appender.fileappender+minimallock" />
      <!--最大文件大小-->
      <maximumfilesize value="10mb" />
      <!--文件命名格式,非日期参数化要进行转义,如自定义文件后缀-->
      <datepattern value="yyyymm\\yyyy-mm-dd&quot;.log&quot;" />
      <!--是否固定文件名-->
      <staticlogfilename value="false" />
      <layout type="log4net.layout.patternlayout">
        <conversionpattern value="---------------------------------------------------%newline发生时间:%date %newline事件级别:%-5level %newline事件来源:%logger%newline日志内容:%message%newline" />
      </layout>
    </appender>
    <!--使用adonetappender方式记录日志按照日来记录日志-->
    <!--<appender name="adonetappender" type="log4net.appender.adonetappender">
      <buffersize value="1" />
      <connectiontype value="system.data.sqlclient.sqlconnection, system.data, version=1.0.3300.0, culture=neutral, publickeytoken=b77a5c561934e089" />
      <connectionstring value="database=sample;server=.\sqlexpress;uid=sa;pwd=sasa;connect timeout=15;" />
      <commandtext value="insert into [log4net] ([date],[host],[thread],[level],[logger],[message],[exception]) values (@log_date, @host, @thread, @log_level, @logger, @message, @exception)" />
      <parameter>
        <parametername value="@log_date" />
        <dbtype value="datetime" />
        <layout type="log4net.layout.rawtimestamplayout" />
      </parameter>
      <parameter>
        <parametername value="@thread" />
        <dbtype value="string" />
        <size value="255" />
        <layout type="log4net.layout.patternlayout">
          <conversionpattern value="%thread" />
        </layout>
      </parameter>
 
      <parameter>
        <parametername value="@host" />
        <dbtype value="string" />
        <size value="50" />
        <layout type="log4net.layout.patternlayout">
          <conversionpattern value="%property{log4net:hostname}" />
        </layout>
      </parameter>
      <parameter>
        <parametername value="@log_level" />
        <dbtype value="string" />
        <size value="50" />
        <layout type="log4net.layout.patternlayout">
          <conversionpattern value="%level" />
        </layout>
      </parameter>
      <parameter>
        <parametername value="@logger" />
        <dbtype value="string" />
        <size value="255" />
        <layout type="log4net.layout.patternlayout">
          <conversionpattern value="%logger" />
        </layout>
      </parameter>
      <parameter>
        <parametername value="@message" />
        <dbtype value="string" />
        <size value="4000" />
        <layout type="log4net.layout.patternlayout">
          <conversionpattern value="%message" />
        </layout>
      </parameter>
      <parameter>
        <parametername value="@exception" />
        <dbtype value="string" />
        <size value="4000" />
        <layout type="log4net.layout.exceptionlayout" />
      </parameter>
    </appender>-->
    <!--使用consoleappender方式记录日志按照日来记录日志-->
    <appender name="coloredconsoleappender" type="log4net.appender.coloredconsoleappender">
      <mapping>
        <level value="info" />
        <forecolor value="white, highintensity" />
        <backcolor value="green" />
      </mapping>
      <mapping>
        <level value="debug" />
        <forecolor value="white, highintensity" />
        <backcolor value="blue" />
      </mapping>
      <mapping>
        <level value="warn" />
        <forecolor value="yellow, highintensity" />
        <backcolor value="purple" />
      </mapping>
      <mapping>
        <level value="error" />
        <forecolor value="yellow, highintensity" />
        <backcolor value="red" />
      </mapping>
      <layout type="log4net.layout.patternlayout">
        <conversionpattern value="---------------------------------------------------%newline发生时间:%date %newline事件级别:%-5level%newline事件来源:%logger%newline事件行号:%line%newline日志内容:%message%newline" />
      </layout>
    </appender>
    <appender name="udpappender" type="log4net.appender.udpappender">
      <remoteaddress value="127.0.0.1" />
      <remoteport value="7071" />
      <layout type="log4net.layout.xmllayoutschemalog4j" />
    </appender>
    <root>
      <appender-ref ref="udpappender" />
    </root>
  </log4net>
</configuration>

怎么使用

private ikernel _kernel = null;
private ilogservice _logservice = null;
 
[testinitialize]
public void setup()
{
    _kernel = new standardkernel(new logmodule());
    assert.isnotnull(_kernel);
 
    _logservice = _kernel.get<ilogservice>();
}
 
[testmethod()]
public void debugtest()
{
    _logservice.debug("debugtest");
}

结语

  1. 整个实现很简单,就是业务或者功能不依赖具体实现类,这也是开发中最基本原则;
  2. 小弟不才,大佬轻拍;

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网