使用NLOG在Blazor服务器中记录URL

发布于 2025-01-25 04:04:56 字数 242 浏览 2 评论 0原文

我目前正在将NLOG与Blazor Server一起使用,并将生成的日志存储在数据库中。我要存储的数据点之一是用户创建日志时用户所在的URL。

在其他ASP.NET核心项目中,我将使用aspnet-request-url布局渲染器,但是在Blazor Server上,这似乎总是返回https:// localhost/_blazor 。有没有一种方法可以获取当前的大发URL并将其包含在日志中?

I'm currently using NLog with Blazor Server and storing generated logs in a database. One of the data points I would like to store is the URL that the user was on when the log was created.

In other asp.net core projects, I would use the aspnet-request-url layout renderer, but on Blazor server this always seems to return https://localhost/_blazor. Is there a way to get the current Blazor URL and include that in the log?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一紙繁鸢 2025-02-01 04:04:56

目前,似乎不可能使用NLOG布局渲染器,例如$ {ASPNET-REQUEST-url}来记录Blazor Server应用程序的正确请求URL,但您仍然可以使其成为通过使用$ {event-properties}布局渲染器将请求URL附加到记录器中来工作(请参见下面的代码)。

原因是$ {aspnet-request-url}布局渲染器搜索httpcontext.request.request获取请求url( nlog noreferrer“> nlog aspnetreqnetrequesturlrenderer.cs ) ,但是大麻的处理方式不同。

Blazor Server应用程序的案例,客户端仅向应用程序发送HTTP请求,仅一次(https:// localhost/_blazor),其中他们下载了所有必要的文件(html/css/css/ js/images)和jlazor建立了与客户的连接。一旦建立了Signalr连接,它就会使用HTTP以外的运输方法(通常是WebSockets)在客户端服务器之间进行通信,并且在此之后没有提出HTTP请求。所有后续请求都是通过SignalR连接提出的,因此,您始终获得https:// localhost/_blazor in $ {aspnet-request-url}布局>布局。

根据文档,获取当前请求的定义方法URI是将navigationManager注入您的大餐组件。您可以从navigationManager获得uri属性,该为您提供了字符串格式的绝对URI。 NLOG记录器可以充满上下文信息和自定义属性(使用with property withProperties 方法),然后可以使用事件属性布局渲染器。因此,您可以做的就是将navigationManager.uri连接到记录器,然后通过在nlog.config中的布局中定义该属性来访问该属性。

解决方案#01示例:

/* Counter.razor */
@page "/counter"

@inject NavigationManager navigationManager
    
/* Define Logger */
NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
    
/* Attaching a property to a logger returns a new enriched logger */
var loggerWithProps = _logger.WithProperty("navigation-manager-uri", navigationManager.Uri);

/* Use this logger which has request url attached in key 'navigation-manager-uri' */
loggerWithProps.Info("Sample message which contains NavManager.Uri property");

现在在您的nlog.config文件中,您可以使用布局渲染器$ {event-properties:item = navigation-manager-uri} 。您的配置文件将看起来像这样:

<!-- NLog.config -->
<targets>
    <target xsi:type="Console" layout="${event-properties:item=navigation-manager-uri} ${message}">

    <!-- Or skip logging this property if it is empty (uses ${when} condition) -->    
    <!-- <target xsi:type="Console" layout="${when:when='${event-properties:item=navigation-manager-uri}'!='':Inner=${event-properties:item=navigation-manager-uri} }${message}"> -->
    </target>
</targets>

给出输出日志:

https://localhost:7123/counter Sample message which contains NavManager.Uri property

[建议]解决方案#02示例(谢谢@Rolf Kristensen),

而不是通过将属性附加到它(创建2个Loggers,一个带有您的属性和一个)来丰富记录器没有它)并使用$ {event-properties}布局渲染器,您可以简单地添加navigationmanager.uri in httpcontext.items in in Onitialized生命周期钩。因为nlog具有 httpcontext项目layender underer 哪些可以访问哪些 httpcontext.items,您可以在nlog.config中使用$ {aspnet-item:acpnet-item:variable = your_variable_name}

/* Counter.razor */
@page "/counter"

/* @* Inject NavigationManager to get current URI *@ */
@inject NavigationManager navigationManager

/* @* Inject IHttpContextAccessor to get access to current HttpContext *@ */
@inject IHttpContextAccessor httpContextAccessor

@code {
    /* Define a simple logger */
    NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

    protected override void OnInitialized()
    {
        /* Add NavigationManager.Uri into HttpContext Items */
        /* This will then be accessible in NLog.config like ${aspnet-item:variable=navigation-manager-uri} */
        httpContextAccessor?.HttpContext?.Items.Add("navigation-manager-uri", navigationManager.Uri);
        
        /* Or make it fail safe so that it doesn't give 'key' already present error when switching to multiple pages */
        // if (httpContextAccessor is not null && httpContextAccessor.HttpContext is not null && httpContextAccessor.HttpContext.Items.ContainsKey("navigation-manager-uri"))
            // httpContextAccessor?.HttpContext?.Items.Remove("navigation-manager-uri");
        // httpContextAccessor?.HttpContext?.Items.Add("navigation-manager-uri", navigationManager.Uri);

        /* Now logging anything will have correct URL displayed in logs */
        /* Use this logger everywhere in this component */
        logger.Info("This will have correct URL attached from NavigationManager.Uri");
    }
}

现在在nlog.config 文件,您可以使用布局渲染器$ {aspnet-iTem:acpnet-item:variable = navigation-manager-uri- }。您的配置文件将看起来像这样:

<!-- NLog.config -->
<targets>
    <target xsi:type="Console" layout="${aspnet-item:variable=navigation-manager-uri} ${message}">

    <!-- Or skip logging this property if it is empty (uses ${when} condition) -->    
    <!-- <target xsi:type="Console" layout="${when:when='${aspnet-item:variable=navigation-manager-uri}'!='':Inner=${aspnet-item:variable=navigation-manager-uri} }${message}"> -->
    </target>
</targets>

提供输出日志:

https://localhost:7123/counter This will have correct URL attached from NavigationManager.Uri

此解决方案更容易,因为您需要做的就是添加3行代码以使其正常工作,并添加NLOG处理其余的。

  1. 注入NavigationManager
  2. 注入IHTTPCONTEXTACCESSOR
  3. 添加navigationManager.uri httpcontext.items

现在,这些是将blazor应用程序登录请求URL的唯一方法。请参阅 nlog问题 - 提供更多信息,以提供更多信息。

Right now, it doesn't seem to be possible to use NLog layout renderers such as ${aspnet-request-url} to log the correct request url for Blazor Server applications, but you can still make it work by appending the request URL to the logger yourself by using the ${event-properties} layout renderer (see code below).

The reason is that ${aspnet-request-url} layout renderer searches HttpContext.Request to get the request URL (NLog AspNetRequestUrlRenderer.cs), which works fine for other asp.net core projects, but Blazor handles things differently.

In-case of Blazor Server applications, clients only send an HTTP request to the application just once (to https://localhost/_blazor), in which they download all the necessary files (html / css / js / images) and Blazor establishes a SignalR connection with the client. Once a SignalR connection is established, it uses transport methods other than HTTP (usually WebSockets) for communicating between the client-server and no HTTP request is made after that. All subsequent requests are made through SignalR connection and therefore, you always get https://localhost/_blazor in ${aspnet-request-url} layout renderer.

As per the documentation, the defined way to get current requests URI is to inject NavigationManager in your Blazor components. You can get the Uri property from NavigationManager which gives you an absolute URI in string format. NLog loggers can be enriched with context information and custom properties (using WithProperty or WithProperties method) which can then be logged using Event Properties layout renderer. So what you can do is attach the NavigationManager.Uri to your logger and then access that property by defining it in your layouts in NLog.config.

Solution #01 Example:

/* Counter.razor */
@page "/counter"

@inject NavigationManager navigationManager
    
/* Define Logger */
NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
    
/* Attaching a property to a logger returns a new enriched logger */
var loggerWithProps = _logger.WithProperty("navigation-manager-uri", navigationManager.Uri);

/* Use this logger which has request url attached in key 'navigation-manager-uri' */
loggerWithProps.Info("Sample message which contains NavManager.Uri property");

Now in your NLog.config file, you can access the request uri using the layout renderer ${event-properties:item=navigation-manager-uri}. Your config file will look like this:

<!-- NLog.config -->
<targets>
    <target xsi:type="Console" layout="${event-properties:item=navigation-manager-uri} ${message}">

    <!-- Or skip logging this property if it is empty (uses ${when} condition) -->    
    <!-- <target xsi:type="Console" layout="${when:when='${event-properties:item=navigation-manager-uri}'!='':Inner=${event-properties:item=navigation-manager-uri} }${message}"> -->
    </target>
</targets>

which gives the output logs:

https://localhost:7123/counter Sample message which contains NavManager.Uri property

[Recommended] Solution #02 Example (thanks @Rolf Kristensen)

Instead of enriching a logger by attaching a property to it (which creates 2 loggers, one with your property and one without it) and using ${event-properties} layout renderer, you can simple add NavigationManager.Uri into HttpContext.Items in OnInitialized lifecycle hook. Since NLog has HttpContext Item Layout Renderer which can access HttpContext.Items, you can access it in NLog.config by using ${aspnet-item:variable=YOUR_VARIABLE_NAME}

/* Counter.razor */
@page "/counter"

/* @* Inject NavigationManager to get current URI *@ */
@inject NavigationManager navigationManager

/* @* Inject IHttpContextAccessor to get access to current HttpContext *@ */
@inject IHttpContextAccessor httpContextAccessor

@code {
    /* Define a simple logger */
    NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

    protected override void OnInitialized()
    {
        /* Add NavigationManager.Uri into HttpContext Items */
        /* This will then be accessible in NLog.config like ${aspnet-item:variable=navigation-manager-uri} */
        httpContextAccessor?.HttpContext?.Items.Add("navigation-manager-uri", navigationManager.Uri);
        
        /* Or make it fail safe so that it doesn't give 'key' already present error when switching to multiple pages */
        // if (httpContextAccessor is not null && httpContextAccessor.HttpContext is not null && httpContextAccessor.HttpContext.Items.ContainsKey("navigation-manager-uri"))
            // httpContextAccessor?.HttpContext?.Items.Remove("navigation-manager-uri");
        // httpContextAccessor?.HttpContext?.Items.Add("navigation-manager-uri", navigationManager.Uri);

        /* Now logging anything will have correct URL displayed in logs */
        /* Use this logger everywhere in this component */
        logger.Info("This will have correct URL attached from NavigationManager.Uri");
    }
}

Now in your NLog.config file, you can access the request URI which you pushed to HttpContext.Items using the layout renderer ${aspnet-item:variable=navigation-manager-uri}. Your config file will look like this:

<!-- NLog.config -->
<targets>
    <target xsi:type="Console" layout="${aspnet-item:variable=navigation-manager-uri} ${message}">

    <!-- Or skip logging this property if it is empty (uses ${when} condition) -->    
    <!-- <target xsi:type="Console" layout="${when:when='${aspnet-item:variable=navigation-manager-uri}'!='':Inner=${aspnet-item:variable=navigation-manager-uri} }${message}"> -->
    </target>
</targets>

which gives the output logs:

https://localhost:7123/counter This will have correct URL attached from NavigationManager.Uri

This solution is easier because all you need to do is add 3 lines of code to make it work and NLog handles the rest.

  1. Inject NavigationManager
  2. Inject IHttpContextAccessor
  3. Add NavigationManager.Uri into HttpContext.Items

Right now these are the only ways to log the request URLs for Blazor applications with NLog. See NLog Issue - Provide support for logging Blazor request information for more information.

別甾虛僞 2025-02-01 04:04:56

nlog.web.aspnetcore库使用httpcontext作为其几乎所有布局渲染器的源。在少数情况下,使用iHostenvironment。在这种情况下,使用属性httpcontext.request.url。中间件没有使用。

也许检查{aspnet-request-routeparameters}是否有帮助?我对大麻的了解不足以知道它如何填充httpcontext

The NLog.Web.AspNetCore library uses the HttpContext as the source for almost all of its layout renderers. In a few cases, IHostEnvironment is used. In this case, the property HttpContext.Request.Url is used. Middleware is not utilized.

Perhaps examining {aspnet-request-routeparameters} could be of assistance? I don't know enough about Blazor to know how it populates the HttpContext.

橘寄 2025-02-01 04:04:56

检索剃须刀特定详细信息的替代方法:

  • 获取页面名称/路径 - routedata.values [“ page”]

      $ {ASPNET-REQUEST-ROUTEPARAMETERS:项目= page}
     
  • 路由模板参数定义为@page的一部分。前任。 @page“ {title?}”@page“ {handler?}”

      $ {ASPNET-REQUEST-ROUTEPARAMETERS:项目= title}
     
  • 替代get get get page name/page name/path from httpcontext- httpcontext.request.request。路径

      $ {aspnet-request-url:properties = path}
     
  • 如果您有处理程序重定向url- httpcontext.request.query [“ handler” < /p>

      $ {aspnet-request-querystring:items = handler}
     
  • 剃须刀页面处理程序的组合查找名称:

      $ {aspnet-request-routeparameters:items = handler:wherempty = $ {aspnet-request-queryString:tock = handler}}}
     
  • 获取端点DisplayName- httpcontext.getendpoint()。displayName

      $ {aspnet-request-endpoint}
     

另请参阅: https://nlog-project.org/config/?tab=layout-renderers&search = package:nlog.web.apt.aspnetcore

Alternative ways of retrieving Razor-specific details:

  • Getting page name/path - RouteData.Values["page"]

    ${aspnet-request-routeparameters:items=page}
    
  • Route Template parameters defined as part of the @page. Ex. @page "{title?}" or @page "{handler?}"

    ${aspnet-request-routeparameters:items=title}
    
  • Alternative get page name/path from HttpContext - HttpContext.Request.Path

    ${aspnet-request-url:properties=path}
    
  • If you have handler to redirect url - HttpContext.Request.Query["handler"]

    ${aspnet-request-querystring:items=handler}
    
  • Combined lookup of Razor Page Handler Name:

    ${aspnet-request-routeparameters:items=handler:whenEmpty=${aspnet-request-querystring:items=handler}}
    
  • Getting the EndPoint DisplayName - HttpContext.GetEndPoint().DisplayName

    ${aspnet-request-endpoint}
    

See also: https://nlog-project.org/config/?tab=layout-renderers&search=package:nlog.web.aspnetcore

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文