繁体   English   中英

登录 C# 库

[英]Logging in a C# library

关于在图书馆内登录的最佳做法是什么?

我正在创建一个供用户使用的 C# 库,有时我想记录错误或警告。 使用 log4net 并登录文件是一个好习惯吗?

我在我自己的库中使用 log4net,但如果我的库应该被其他人使用(即我的组织之外),我不会这样做。 在这种情况下,我将使用一个接口进行日志记录,在单独的程序集中提供基于 log4net 的默认实现,并使用一种或另一种方式允许库的用户注入他们自己的实现。

话虽如此:我真的很喜欢 log4net,不会使用其他任何东西,但我认为强迫他人必须使用您选择的日志记录框架是错误的。

编辑:

  • 我也不认为默认情况下将库记录到文件中是一个好习惯。 您图书馆的用户应该能够决定日志消息的最终位置。
  • 我还将提供一个“无操作”实现,如果根本不需要日志记录,则可以使用它。 这可能应该是默认行为,不需要任何额外的程序集或步骤来实现。

使用 log4net 的美妙之处在于您的库不必指定记录内容的位置。 日志消息的目的地(日志附加程序)由应用程序指定的配置决定(通常在配置文件中)。

所以是的,按照他们推荐的模式(每个类一个独特的“记录器”)使用 log4net,并通知您的用户您的库使用 log4net。 您的库代码生成的任何日志消息都将根据 使用者配置(文件、数据库、控制台、跟踪等)进行路由。

编辑:这是一个很好的关于 log4net 的简短入门,解释了基本概念。

这里的所有答案似乎都过时了。 我会做一个新的:

我的库要求使用可选的Microsoft.Extensions.Logging.ILogger对象来写入日志消息。 如果没有ILogger对象,它就不会记录任何内容。

消费者应用程序可以使用 NLog、Log4Net 或 SeriLog 创建这个ILogger对象。我的库可以在没有日志框架锁定的 ASP.NET 核心应用程序中使用。

使用其他 lggging 框架创建 Microsoft ILogger 的示例

private static readonly ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddNLog(); //=>install NLog.Extensions.Logging nuget
    //or builder.AddSerilog(); => install Serilog.Extensions.Logging nuget
    //or builder.AddLog4Net() //=> Microsoft.Extensions.Logging.Log4Net.AspNetCore
 });
private static readonly ILogger<Program> log = loggerFactory.CreateLogger<Program>();

//configure nlog/serilog/log4net normally then
log.LogInformation("Hello");

在 Log4Net 的情况下,您还可以

ILoggerFactory loggerFactory = new LoggerFactory();
loggerFactory.AddLog4Net(); //load log4net.config by default

我会警惕在通用类库中引入对 3rd 方库(例如 log4net)的依赖:我更愿意将其留给调用者来决定如何进行日志记录。 如果库的用户已经在使用不同的日志框架怎么办?

一些替代方案是:

  • 对于错误,抛出一个Exception或允许一个Exception传播,让调用者处理它并做任何日志记录。

  • 对于警告(例如,您在库中处理的异常),您可以考虑引发一个事件,如果他想记录它,调用者可以处理该事件。 例如,您可以引发一个Error事件,该事件采用带有错误详细信息的System.IO.ErrorEventArgs (或类似的自定义EventArgs )。

  • 如果您觉得库需要更多检测,您可以在库中的战略点引发更多事件,调用者可以处理这些事件来进行日志记录。

  • 或者,您可以在您的类库( ILogging或类似的)中定义一个接口,如果他们想要记录,调用者必须实现该接口。 让调用者将此接口的实例传递给类构造函数以启用日志记录。

  • 您可以执行类似于登录AWS SDK for .NET 的操作,即支持多个日志记录框架,但使用反射加载第 3 方框架以避免创建依赖项。 我个人不喜欢这个,但这是一种有效的方法,特别是如果您的库足够大以证明详细的检测是合理的。

log4net 只是一个 3rd 方库,在使用 C# 时必须将其用作日志库并不是最佳实践 我的建议是始终将日志保存到某个地方(最常见的是文本文件)。 但是,还有事件日志(需要一些额外的设置)。

我倾向于使用NLog ,我发现它非常易于使用且易于设置。 至于在您的类库中登录,您认为哪种方法最适合您的应用程序。 有些人会创造1个日志和它向下传递到类,其他人会创造每一个单独的记录loggable类。 我倾向于为每个类创建一个静态记录器,它工作正常。

练习虎钳的一个好方法是引入一个 Logging 门面,这样你就不用关心你使用的记录器,你有一个一致的记录器通用接口。

例如,你可以试试这个,或者干脆自己写。

在我看来,将日志记录在您自己的小适配器中永远不会有什么坏处,例如,以后可以轻松地从生产中剥离日志记录。 我为此创建了一个小的日志包装器,它的 API 如下所示:

Log.d("I'm a log message");
Log.w("I'm a warning with parmas", "param 1", 2, "..");
Log.e("I'm an error");
Log.e(new Exception("I'm an exception"));
AssertV2.IsTrue(1 + 1 == 3, "This assertion will fail");

有关更多示例,请参阅https://github.com/cs-util-com/cscore#logging

您可以登录到控制台、文件、Unity,并且可以轻松添加更复杂的日志记录目标,例如 Serilog

如果您有任何建议或其他反馈,请告诉我,我想让它尽可能小,但想了解它尚未涵盖的用例💚

我使用SmartInspect

这个程序的好处是你可以在查看应用程序中过滤日志,这个功能在实践中非常有用。

郑重声明,我与 SmartInspect 没有任何关联。

这取决于你想做什么。

您是否想为纯技术内容提供一个日志记录机制,您可以使用不同的详细程度(用于支持活动)打开/关闭? 或者您想记录更多旨在供图书馆用户阅读的业务相关内容?

您应该先回答这些问题,然后才能决定要记录的内容、存储位置以及如何格式化...

无论如何,log4net 是用于所有这些目的的良好、成熟和稳定的日志记录框架。 并且记录到滚动文件是常见的做法(但到目前为止不是唯一的选择......)。

问候托马斯

您的用户使用什么进行日志记录?
这是您需要回答以确定正确框架的问题。
从我的观点来看,Log4net 功能强大且相对容易。 如果没有指定其他内容,您也可以使用它来登录流编写器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM