我看到很多帖子提到了使用Microsoft.Extensions.Logging以及NLog。
我想更好地了解Microsoft.Extensions.Logging的用途?
具体而言,为什么需要它或者与NLog一起使用的好处是什么?
我看到很多帖子提到了使用Microsoft.Extensions.Logging以及NLog。
我想更好地了解Microsoft.Extensions.Logging的用途?
具体而言,为什么需要它或者与NLog一起使用的好处是什么?
使用 NLog,您可以执行以下操作:
var logger = NLog.LogManager.GetCurrentClassLogger();
logger.Info("Hello {Name}", "Earth");
这适用于所有平台和所有框架。
在.NET Core中,微软引入了来自Microsoft.Extensions.Logging的ILogger抽象。您可以在项目中使用该日志记录抽象,并将其与NLog集成。
例如,在ASP.NET Core中,您可以注入Microsoft.Extensions.Logging.ILogger<HomeController>
,并将其发送到NLog日志记录器(参见Getting started with ASP.NET Core 2 · NLog/NLog Wiki)。
using Microsoft.Extensions.Logging;
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
_logger.LogInformation("Index page says hello {Name}", "Universe");
return View();
}
对于NLog和Microsoft.Extensions.Logging,有以下软件包:
直接使用NLog的优点
Logger.WithProperty(..)
通过Microsoft.Extensions.Logging使用NLog的优点:
更新:添加 - 使用appsettings.json的NLog
log.Info(...)
代替 logger.LogInformation(...)
。尽管可以创建扩展方法来解决这个问题,但直接使用更加方便。 - Sedat KapanogluLogInformation
表示它将记录信息时,logger.LogInformation(...)
似乎比 log.Info(...)
更清晰。但是当我看到 Info
方法时,它会让我感到困惑。它是要显示信息还是发送到某个地方? - Timur VafinWhere
、Select
,它们本身并不具有描述性,但在Linq的上下文中,它们是非常合理的。我认为这也是在日志记录的上下文中的一个例子。 - Sedat KapanogluMicrosoft.Extensions.Logging
用于依赖注入,这对于单元测试非常方便:您可以实现一个带有LoggedText属性的记录器,以支持Assert.IsTrue(_logger.LoggedText.Contains("expected value"))
。下面的示例说明了一个实现Microsoft.Extensions.Logging.ILogger<T>
并(为了好玩)还使用Julian的建议将消息发送到NLog的类:
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyDomain.Tests
{
internal class WrappedNLogger<T> : ILogger<T>
{
private StringBuilder _sb = new StringBuilder(); //Support Assert.IsTrue(_logger.LoggedText == "expected value")
private NLog.Logger _nlog = NLog.LogManager.GetCurrentClassLogger(); //support use of NLog
public IDisposable BeginScope<TState>(TState state) => default;
public bool IsEnabled(LogLevel logLevel) => true;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
var jsonLine = JsonConvert.SerializeObject(new
{
timestamp = DateTime.Now.ToLongTimeString(),
logLevel,
eventId,
parameters = (state as IEnumerable<KeyValuePair<string, object>>)?.ToDictionary(i => i.Key, i => i.Value),
message = formatter(state, exception),
exception = exception?.GetType().Name
});
_sb.AppendLine(jsonLine);
NLog.LogLevel nloglevel = logLevel == LogLevel.Debug ? NLog.LogLevel.Debug
: logLevel == LogLevel.Information ? NLog.LogLevel.Info
: logLevel == LogLevel.Warning ? NLog.LogLevel.Warn
: logLevel == LogLevel.Error ? NLog.LogLevel.Error
: logLevel == LogLevel.Critical ? NLog.LogLevel.Fatal : NLog.LogLevel.Trace;
_nlog.Log(nloglevel, jsonLine);
}
public string LoggedText { get => _sb.ToString(); }
}
}
NLog.Extensions.Logging
与LoggerFactory,然后配置一个带有JsonLayout的NLog目标将是更好的选择。 - Rolf Kristensen