c# - 带有 Func() 参数的 ASP.NET Core 日志记录

标签 c# logging asp.net-core nlog

我将 ASP.NET Core 与 NLog 一起使用,将其用作带有 NLog.Web.AspNetCore block 包的原始 ASP.NET Core 记录器的替代品。

NLog 包含一个有用的 Func() 委托(delegate)签名,仅当启用相应的日志记录级别时才允许执行参数评估:

static readonly Logger log = LogManager.GetCurrentClassLogger();
log.Trace(() => request.JsonSerializer.Serialize(body));

我正在使用带有 NLog 的 ASP.NET,但听起来这个功能不可用:

private ILogger<MyController> log;
log.Trace(() => request.JsonSerializer.Serialize(body));

在开始为自己编写一个方法之前,我想知道我是否遗漏了什么,我没有找到任何关于使用带有 NLog 的 ASP.NET Core 的委托(delegate)参数的此类日志记录方法。

最佳答案

在 Microsoft.Extensions.Logging 抽象中没有这样的东西,而且它的构建方式,做这样的事情并不容易。虽然您可以轻松地向它添加扩展方法,并且实际上所有日志调用 都是 扩展方法,但基本 Log 方法决定是否记录某些内容,因为它是只有真正有权访问配置的日志级别的东西。

话虽如此,日志记录抽象使用的东西可能使类似的事情成为可能。为此,请考虑 ILogger.Log 方法的签名:

void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)

如您所见,实际上并没有传递给它的字符串,只是一个state 和一个formatter。在默认的扩展方法中,状态是一个 FormattedLogValues 对象,格式化程序只是一个在状态上调用 ToString() 的方法,即 FormattedLogValues对象。

FormattedLogValues 是实际构建格式化字符串的内容,也是结构化日志记录发生的地方。所以在你的日志消息中序列化一些对象实际上是一个坏主意;您可以直接将其传递给记录器。

但是您在这里可以做的是为 Log 提供您自己的重载,它采用一个函数,然后将其包装到某个状态对象中,该对象在 ToString() 正在调用。

关于c# - 带有 Func() 参数的 ASP.NET Core 日志记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51238835/

相关文章:

c# - 将 IQueryable where 子句从 DTO 映射到实体

c# - T-SQL 到 LINQ 的转换

c# - 为什么 WriteEntry 不适用于此 EventLog 源?

c# - UserManager 在创建用户时不初始化属性

iis - 移动到不同的 IIS 服务器后,在 IIS 中发布的 asp.net core web api 给出错误 500.19 (0x8007000d)

c# - 如何故意使所有 C# 单元测试失败

c# - 如何让 HttpClient 随请求一起传递凭据?

asp.net - 在 ASP.NET 中自动记录长/异常页面执行时间

php - 使用 flume 进行分布式日志记录

c# - ASP.NET Core 无法使用 RazorViewEngine 按路径找到 cshtml 文件