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

背景

  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. 小弟不才,大佬轻拍;

原文地址:https://www.cnblogs.com/MeetYan/p/10687029.html

时间: 2024-10-14 10:03:06

基于Log4Net本地日志服务简单实现的相关文章

基于log4net的日志组件扩展分装,实现自动记录交互日志 XYH.Log4Net.Extend

背景: 随着公司的项目不断的完善,功能越来越复杂,服务也越来越多(微服务),公司迫切需要对整个系统的每一个程序的运行情况进行监控,并且能够实现对自动记录不同服务间的程序调用的交互日志,以及通一个服务或者项目中某一次执行情况的跟踪监控 根据log4net的现有功能满足不了实际需求,所以需要以log4net为基础进行分装完善,现在分装出了一个基础的版本,如有不妥之处,多多指点功能简介: 该组件是在log4net的基础上,进行了一定的扩展封装实现的自动记录交互日志功能 该组件的封装的目的是解决一下几个

centos 如何用 rsyslog 搭建本地日志服务(续1: omprog模块与php deamon的配合使用)

上一篇说到了如何用 rsyslog 搭建本地的日志服务,地址在这里,没有看的童鞋可以先瞅一眼 : http://www.cnblogs.com/smallrookie/p/5677004.html 显然这个是比较简单粗暴的,如果没有做过什么特殊的输出配置,所有的输出都会写到一个文件里面,当然 rsyslog 是支持关键词匹配,然后把日志定向的写到你想写的文件里面的,如果你只有数量比较小的接口并且一段时间内,接口的数量不会发生变更,那么使用这种方式是OK的.不过实际情况是,我们通常要处理的是大量的

基于Log4Net的日志系统

阅读目录 日志系统应具备的特性 Log4Net 配置文件:log4net.config 初始化 输出信息 对Log4Net的封装 log4net.config复杂配置 不管是Web应用程序还是WinForm应用程序,Visual Studio所带的调试功能都是足够强大,足以应付开发中的各种调试需求.但是,对于已经发布的应用,要记录错误.记载运行中的各种状态信息,就需要依靠日志系统了. 回到顶部 日志系统应具备的特性 一个好的日志系统,应该具备以下的特性: 1.运行稳定.因为日志的作用就是要在系统

Log4net创建日志及简单扩展

1.概述 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.本文主要是介绍如何在Visual Studio2008中使用log4net快速创建系统日志,如何扩展以输出自定义字段.2.一个简单的使用实例 第一步:在项目中添加对log4net.dll的引用,这里引用版本是1.2.10.0. 第二步:程序启动时读取log4net的配置文件. 如果是CS程序,在根目录的Program.cs中的Main

如何使用Log4net创建日志及简单扩展

第一步:在项目中添加对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();

[开源]基于Log4Net简单实现KafkaAppender

背景 基于之前基于Log4Net本地日志服务简单实现 实现本地日志服务,但是随着项目开发演进,本地日志服务满足不了需求,譬如在预发布环境或者生产环境,不可能让开发人员登录查看本地日志文件分析. Kafka+ELK日志服务套件,可以在线日志服务可以解决上述问题,并且提供丰富报表分析等等: 具体源码:MasterChief Nuget:Install-Package MasterChief.DotNet.Core.KafkaLog 欢迎Star,欢迎Issues: 源码 基于Log4Net来实现与k

基于ActiveMQ的统一日志服务

概述 以ActiveMQ + Log4j + Spring的技术组合,实现基于消息队列的统一日志服务. 参考:Spring+Log4j+ActiveMQ实现远程记录日志——实战+分析 与参考文章的比较 1. 更新了技术的版本    e.g. Spring升级到4.2.0,ActiveMQ升级到5.13.2 2. 更新了依赖    e.g. 使用activemq-client 5.13.2替换activemq-core最高版本是5.7.0,并取消了多余的spring-jms依赖 3. 精简了配置 

【阿里云产品公测】简单日志服务SLS使用评测 + 教程

[阿里云产品公测]简单日志服务SLS使用评测 + 教程 评测介绍 被测产品: 简单日志服务SLS 评测环境: 阿里云基础ECS x2(1核, 512M, 1M) 操作系统: CentOS 6.5 x64 日志环境: Nginx(v1.6.2) HTTP服务器访问日志.服务器系统日志 评测人: mr_wid 评测时间: 2014年9月28日-2014年10月8日 准备工作 一.知彼知己, 百战不殆.对产品的了解程度, 直接决定着评测质量, 在评测前, 笔者首先整理并详细阅读了有关SLS产品以及关联

Log4Net日志记录简单使用讲解

一. Log4Net 简介 Log4net 是 Apache 下一个开放源码的项目,我们可以控制日志信息的输出目的地(数据库.控制台.文本文档.文件).Log4net中定义了多种日志信息输出模式. 在做项目的时候令我最头疼的是在程序发布到正式环境之后出现了问题,我们不能调试而且问题很难重新,于是我们需要大量的日志数据来精确的跟踪程序的运行状况. Log4net就可以帮我来解决这一个难题,对于日志的输出我们不需要人为的去干涉,它可以根据需要将日志输出到控制台,文本文件,windows 日志事件查看