如何记录布局渲染器尚不可用的参数?

How to log parameter that's not yet available for the layout renderer?

我正在开发 ASP.NET Core 2.2 MVC 应用程序,该应用程序将 NLog 设置为其记录器。我不太熟悉它的设置,但我们有一个 nlog.config,我们可以在其中设置我们记录的参数名称以及为它们获取值的布局渲染器。我们使用 using Microsoft.Extensions.Logging;ILogger 的实例注入到整个应用程序的控制器操作和服务方法中。

例如,当我们记录类似 _logger.LogInformation("Client was created"); 的内容以及其他数据时,我们会记录经过身份验证的用户的名称。这是下面代码中的ObjectID,其值取自HttpContext.User.Identity.Name.

问题是我想在 HttpContext.User.Identity.Name 中尚不可用的位置记录 ObjectID。这会导致没有 ObjectID 的日志记录。但是,ObjectID 在另一个变量中可用。

有没有办法记录消息并传递参数值,而不是让记录器从布局渲染器获取它?如果我不手动传递参数,我仍然希望它使用布局渲染器。

nlog.config的相关部分:

<commandText>
  insert into dbo.Log (
  CorrelationId, Application, ObjectID, Logged, Level, Message,
  Logger, CallSite, Exception
  ) values (
  @CorrelationId, @Application, @ObjectID, @Logged, @Level, @Message,
  @Logger, @Callsite, @Exception
  );
</commandText>
<parameter name="@correlationId" layout="${aspnet-traceidentifier}" />
<parameter name="@application" layout="${configsetting:AppSettings.NlogConnection.AppName}" />
<parameter name="@ObjectID" layout="${aspnet-user-identity}" /> <!-- I want to be able to optionally pass the value of this parameter manually -->
<parameter name="@logged" layout="${date}" />
<parameter name="@level" layout="${level}" />
<parameter name="@message" layout="${message}" />
<parameter name="@logger" layout="${logger}" />
<parameter name="@callSite" layout="${callsite:filename=false}" />
<parameter name="@exception" layout="${exception:toString}" />

我们如何注入和使用记录器实例:

public class ClientService : IClientService
{
    private readonly ILogger<ClientService> _logger;

    public ClientService(ILogger<ClientService> Logger)
    {
        _logger = Logger;
    }

    public string CreateClient() {
        //some logic to create client
        string userName = "John Doe"; // I want to log this as ObjectID in the database
        _logger.LogInformation("Client created");
    }
}

你可以add properties喜欢他的:

_logger.LogInformation("Client created {ObjectID}", userName);

并使用 whenEmpty 配置 @ObjectId-参数,如下所示:

<parameter name="@ObjectID" layout="${event-properties:ObjectID:whenEmpty=${aspnet-user-identity}}" />