前言
嘿,朋友们!
时间过得真快啊log4net,国庆长假一下子就没了4 天,真是舍不得呀,你的假期过得快乐吗?分享一下吧
作为一名 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. 文件的 "复制到输出目录" 属性配置为 "如果较新则复制",这样可以确保每次构建时,配置文件如果有修改都会被复制到输出目录
创建日志记录器接口
创建一个日志记录器接口 :
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 Logger: ILogger
{
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 分,和你相约!欢迎关注,和你共同探索代码世界的奥秘!
喜欢文章欢迎点个【赞与在看】,你的支持是我最大的动力!