log4net不写日志_log4net_log4NET写入原理

前言

嘿,朋友们!

时间过得真快啊log4net,国庆长假一下子就没了4 天,真是舍不得呀,你的假期过得快乐吗?分享一下吧

log4net_log4NET写入原理_log4net不写日志

作为一名 C# 程序员,你肯定遇到过需要记录日志的情况,不知道你使用的是哪个日志框架?

是一个流行的日志框架,它提供了强大的功能来轻松记录应用程序的日志,广泛用于 C# 开发中。

但配置起来还是稍微有些繁琐,所以我把它封装起来,使用起来更方便。

好东西要分享嘛,下面我们一起看看如何打造你的专属日志利器。

Step By Step 封装代码

创建一个 项目

首先,创建一个新的 类型项目,命名为 .

安装以下 Nuget 包:

log4net

创建配置文件 log.

创建一个 log. 文件,用于配置 。以下是配置文件的参考内容,留意注释:


<configuration>
  <configSections>
 
 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  
  <log4net>
 
 <root>
   
   <level value="info" />
 </root>

 
 <logger name="WIN_LOG">
   
   <level value="info" /> 
   
   <appender-ref ref="LogFileAppender_Win" /> 
 </logger>

 
 <logger name="WEB_LOG">
   
   <level value="info" /> 
   
   <appender-ref ref="LogFileAppender_Web" /> 
 </logger>

 
 <appender name="LogFileAppender_Win" type="log4net.Appender.RollingFileAppender">
   
   <param name="File" value="logWin.log" /> 
   
   <param name="AppendToFile" value="true" /> 
   
   <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> 
   
   <rollingStyle value="Size" /> 
   
   <maxSizeRollBackups value="100" /> 
   
   <maximumFileSize value="10MB" /> 
   
   <staticLogFileName value="true" /> 
   <layout type="log4net.Layout.PatternLayout">
  
  <param name="ConversionPattern" value="%d %L %-5p %m%n" /> 
   </layout>
 </appender>

 
 <appender name="LogFileAppender_Web" type="log4net.Appender.RollingFileAppender">
   <param name="File" value="logWeb.log" />
   <param name="AppendToFile" value="true" />
   <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
   <rollingStyle value="Size" />
   <maxSizeRollBackups value="100" />
   <maximumFileSize value="10MB" />
   <staticLogFileName value="true" />
   <layout type="log4net.Layout.PatternLayout">
  <param name="ConversionPattern" value="%d %L %-5p %m%n" />
   </layout>
 </appender>

 
 <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
   <layout type="log4net.Layout.PatternLayout">
  <param name="ConversionPattern" value="%d %L %-5p %m%n" />
   </layout>
 </appender>
  </log4net>
</configuration>

配置文件属性

将 log. 文件的 "复制到输出目录" 属性配置为 "如果较新则复制",这样可以确保每次构建时,配置文件如果有修改都会被复制到输出目录

log4NET写入原理_log4net不写日志_log4net

创建日志记录器接口

创建一个日志记录器接口 :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Common.Logger
{
 /// 
 /// 日志记录器接口
 /// 

 public interface ILogger
 {
  /// 
  /// Debug 级别的日志
  /// 

  /// 
  void Debug(object msg);

  /// 
  /// Debug 级别的日志
  /// 

  /// 
  /// 
  void Debug(object msg, Exception ex);

  /// 
  /// Debug 级别的日志
  /// 

  /// 
  /// 
  void DebugFormat(string msg, params object[] args);

  /// 
  /// Info 级别的日志
  /// 

  /// 
  void Info(object msg);

  /// 
  /// Info 级别的日志
  /// 

  /// 
  void Info(object msg, Exception ex);

  /// 
  /// Info 级别的日志
  /// 

  /// 
  void InfoFormat(string msg, params object[] args);

  /// 
  /// Warn 级别的日志
  /// 

  /// 
  void Warn(object msg);

  /// 
  /// Warn 级别的日志
  /// 

  /// 
  /// 
  void Warn(object msg, Exception ex);

  /// 
  /// Warn 级别的日志
  /// 

  /// 
  /// 
  void WarnFormat(string msg, params object[] args);

  /// 
  /// Error 级别的日志
  /// 

  /// 
  void Error(object msg);

  /// 
  /// Error 级别的日志
  /// 

  /// 
  /// 
  void Error(object msg, Exception ex);

  /// 
  /// Error 级别的日志
  /// 

  /// 
  /// 
  void ErrorFormat(string msg, params object[] args);
 }
}

实现日志记录器

创建一个 .cs 文件,实现 接口:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using log4net;

namespace Common.Logger
{
 /// 
 /// ILogger 接口实现类
 /// 

 public class LoggerILogger
 {
  private readonly ILog log4 = null;

  /// 
  /// 初始化 log4 变量
  /// 

  /// 
  public Logger(string logname)
  {
   string logconfig = "";
   if (AppDomain.CurrentDomain.SetupInformation.PrivateBinPath != null)
    logconfig = Path.Combine(AppDomain.CurrentDomain.SetupInformation.PrivateBinPath, "log.config");
   else
    logconfig = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log.config");

   if (!File.Exists(logconfig))
   {
    Assembly myAssembly = Assembly.GetExecutingAssembly();
    FileInfo dllFile = new FileInfo(myAssembly.Location);
    string path = dllFile.Directory.FullName;
    logconfig = Path.Combine(path, "log.config");
   }

   log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(logconfig));
   log4 = GetLogger(logname, logconfig);
  }

  /// 
  /// 根据 log.config 配置实例化特定的 Logger
  /// 

  /// 
  /// 
  /// 
  private ILog GetLogger(string logname, string logconfig)
  {
   ILog log = LogManager.Exists(logname);
   if (log == null)
   {
    throw new NotSupportedException(string.Format("日志配置文件里不存在名为 [{0}] 配置。config=[{1}]", logname, logconfig));
   }
   else
   {
    return log;
   } 
  }

  #region "log interface."
  public void Debug(object msg)
  {
   log4.Debug(msg);
  }
  public void Debug(object msg, Exception ex)
  {
   log4.Debug(msg, ex);
  }

  public void DebugFormat(string msg, params object[] args)
  {
   log4.Debug(string.Format(msg, args));
  }

  public void Info(object msg)
  {
   log4.Info(msg);
  }
  public void Info(object msg, Exception ex)
  {
   log4.Info(msg, ex);
  }

  public void InfoFormat(string msg, params object[] args)
  {
   log4.Info(string.Format(msg, args));
  }

  public void Warn(object msg)
  {
   log4.Warn(msg);
  }
  public void Warn(object msg, Exception ex)
  {
   log4.Warn(msg, ex);
  }

  public void WarnFormat(string msg, params object[] args)
  {
   log4.Warn(string.Format(msg, args));
  }

  public void Error(object msg)
  {
   log4.Error(msg);
  }
  public void Error(object msg, Exception ex)
  {
   log4.Error(msg, ex);
  }

  public void ErrorFormat(string msg, params object[] args)
  {
   log4.Error(string.Format(msg, args));
  }
  #endregion
 }
}

创建日志记录器声明类

创建一个 类log4net,用于定义日志记录器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Common.Logger
{
 /// 
 /// 日志记录器声明类
 /// 

 public class CommonLogger
 {
  /// 
  /// 定义 WIN_LOG logger,名称跟配置文件一致
  /// 

  public static ILogger WINLOG = new Logger("WIN_LOG");

  /// 
  /// 定义 WEB_LOG logger,名称跟配置文件一致
  /// 

  public static ILogger WEBLOG = new Logger("WEB_LOG");
 }
}

完成

至此,基于 的日志记录器就封装完成了,你可以根据业务需要增加更多类型的记录器,比如 SETUP、,将不同类型的日志记录在不同的日志文件里,更方便地跟踪程序的运行细节。

也可以在此基础上,添加或更改日志框架如 NLog,以应付不同的业务需求。

下面我们来看看如何使用这个日志记录器。

使用封装好的日志记录器

在解决方案下创建添加一个新的项目如 ASP.NET

引用这个日志记录器项目 .:

然后就可以直接使用这个日志记录器记录日志了,以下是一段简单的示例代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Common.Logger;

namespace LoggerSample.Controllers
{
 [RoutePrefix("api/auth")]
 public class AuthController : ApiController
 {

  [HttpPost]
  [Route("login")]
  public IHttpActionResult Login(string name, string pwd)
  {
   CommonLogger.WEBLOG.Info("开始执行登录");
   try
   {
    // ...... 登录逻辑,忽略
    return Ok(userData);
   }
   catch (Exception ex)
   {
    CommonLogger.WEBLOG.Error("登录时发现错误:", ex);
    return BadRequestResult("登录失败!");
   }
  }
 }
}

编译并在 中执行这个 API,输入错误的账号密码,就可以看到项目目录下自动生成了 log 目录,并输出日志信息在 Web.log 日志文件里。是不是非常简单?

结论

日志在我们日常开发工作中非常重要,有了详细的日志记录,我们才能更好更快地追踪程序执行路径、优化程序性能和定位排查问题原因等等。

是一个非常成熟的日志框架,体积小,性能高,运行稳定,非常适合中小型项目使用。在多线程的情况下或许会遇到些许问题,但总体而言,使用体验很好。

通过将日志功能封装为一个日志记录器,可以大幅降低项目代码的耦合度,为后期替换或添加其它日志框架(如 NLog)打下良好的基础。比如,我曾经参与某为的一个外包项目,交付时才得知只能用 NLog,非常丝滑地很快就把日志框架更换为 NLog,对整个项目毫无影响。

好了,今天的分享就到这里啦,如果觉得有用,别忘了点个【赞与在看】哦,你的支持是我最大的动力!

往期精彩

我是老杨,一个执着于编程乐趣、至今奋斗在一线的 10年+ 资深研发老鸟,是软件项目管理师,也是快乐的程序猿,持续免费分享全栈实用编程技巧、项目管理经验和职场成长心得,每周一、周三和周五早上 7:20 分,和你相约!欢迎关注,和你共同探索代码世界的奥秘!

喜欢文章欢迎点个【赞与在看】,你的支持是我最大的动力!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注