-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide support for logging Blazor request information #4997
Comments
Hi! Thanks for opening your first issue here! Please make sure to follow the issue template - so we could help you better! |
I don't have any experience with AspNetCore and Blazor. Guess you should ask Microsoft how to extract the blazor-request-information at server-side. Then you can make a pull-request for NLog.Web that implements a layoutrenderer, that can extract the request-information. |
Please add the requested info, so we could help you better! (This issue will be closed in 7 days) |
I tried searching inside using Microsoft.AspNetCore.Components;
...
[Inject]
public NavigationManager MyNavigationManager {get; set;} Would it be possible to somehow inject |
You are wellcome to try creating a LayoutRenderer that resolves NavigationManager as Service-Dependency. You can look at So these should be the steps:
|
Thanks @snakefoot for directions, I followed the steps and tried to use the new layout. I tried to resolve /* AspNetNavigationManagerLayoutRenderer.cs */
using System;
using System.Text;
using Microsoft.AspNetCore.Components;
using NLog.Config;
using NLog.LayoutRenderers;
using NLog.Web.DependencyInjection;
namespace NLog.Web.LayoutRenderers
{
/// <summary>
/// Rendering development environment. <see cref="NavigationManager" />
/// </summary>
[LayoutRenderer("aspnet-navigation-manager")]
[ThreadAgnostic]
public class AspNetNavigationManagerLayoutRenderer : LayoutRenderer
{
private NavigationManager _navigationManager;
private NavigationManager NavManager => _navigationManager ?? (_navigationManager = ServiceLocator.ResolveService<NavigationManager>(ResolveService<IServiceProvider>(), LoggingConfiguration));
/// <summary>
/// Append to target
/// </summary>
/// <param name="builder">The <see cref="StringBuilder" /> to append the rendered data to.</param>
/// <param name="logEvent">Logging event.</param>
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
builder.Append(NavManager?.Uri);
}
/// <inheritdoc />
protected override void CloseLayoutRenderer()
{
_navigationManager = null;
base.CloseLayoutRenderer();
}
}
} But whenever it tries to resolve the service, it gets an error here: /* NLog.Web\src\NLog.Web.AspNetCore\Internal\ServiceLocator.cs : line29 */
var service = serviceProvider?.GetService(typeof(TService)) as TService;
Can you think of any reasons for this error? |
Sounds like Maybe it can be done like https://github.com/NLog/NLog.Web/blob/master/src/NLog.Web.AspNetCore/NLogRequestPostedBodyMiddleware.cs And inject the |
Thank you @snakefoot. After trying to inject
Initiliazing NavigationManager in middlewareWhen you create a middleware and pass the public async Task Invoke(HttpContext context, NavigationManager navigationManager)
{
var requestUri = navigationManager.Uri;
} Exception:
Tried to find out if its possible to access
As for why the middlewares don't get invoked for each request, its because only the first request is an HTTP request to the server which loads all the components and the static data (css/js/images), in this case middleware gets invoked and the browser establishes SignalR connection with the application. Once a
So even if someone somehow manages to inject and initialize @inject NavigationManager NavigationManager;
...
NavigationManager.NavigateTo("url", forceLoad: true);
/* forceLoad: If true, bypasses client-side routing and forces the browser to load the new page from the
server, whether or not the URI would normally be handled by the client-side router.
see: https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.navigationmanager.navigateto
*/ Solution for now (event-properties)So the only possible way, I think, for getting request url in Blazor server is:
Sample counter page from Blazor app: /* Counter.razor */
@page "/counter"
@inject NavigationManager navigationManager
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
/* Define Logger */
NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
private void IncrementCount()
{
currentCount++;
/* Attach property 'navigation-manager-uri' to the logger */
var loggerWithProps = _logger.WithProperty("navigation-manager-uri", navigationManager.Uri);
loggerWithProps.Info("Increment Count");
}
} NLog config file: <!-- NLog.config -->
<targets>
<target layout="${when:when='${event-properties:item=navigation-manager-uri}'!='':Inner=${event-properties:item=navigation-manager-uri} }${message}">
</target>
</targets> which gives correct output logs:
Posting the code for future, someone might be able to figure out how to make it work... |
So initializing the NavigationManager on the server-side is rather expensive, as it has to transfer additional state from the blazor-client to the blazor-server. Still strange that there is not an easy way for tracking the navigation of the blazor-client. But I guess the blazor-client-side can do navigation without contacting the blazor-server-side. But thank you do doing the investigation. Maybe someone will find a more elegant way of capturing state (Maybe using alternate way than |
Closing the issue, since outside the scope of NLog core. Experts in Microsoft Blazor Application Development are very wellcome to provide their elegant solutions at stackoverflow.com: https://stackoverflow.com/questions/72063711/logging-url-in-blazor-server-using-nlog |
With .NET 8, we now have access to public class LoggingCircuitHandler : CircuitHandler
{
private readonly NavigationManager _navigationManager;
private readonly ILogger<LoggingCircuitHandler> _logger;
public LoggingCircuitHandler(NavigationManager navigationManager, ILogger<LoggingCircuitHandler> logger)
{
_navigationManager = navigationManager;
_logger = logger;
}
public override Task OnCircuitOpenedAsync(Circuit circuit, CancellationToken cancellationToken)
{
_logger.LogInformation("Circuit opened for {circuitId}.", circuit.Id);
return base.OnCircuitOpenedAsync(circuit, cancellationToken);
}
public override Task OnConnectionUpAsync(Circuit circuit, CancellationToken cancellationToken)
{
_logger.LogInformation("Connection up for {circuitId}.", circuit.Id);
return base.OnConnectionUpAsync(circuit, cancellationToken);
}
public override Task OnConnectionDownAsync(Circuit circuit, CancellationToken cancellationToken)
{
_logger.LogInformation("Connection down for {circuitId}.", circuit.Id);
return base.OnConnectionDownAsync(circuit, cancellationToken);
}
public override Task OnCircuitClosedAsync(Circuit circuit, CancellationToken cancellationToken)
{
_logger.LogInformation("Circuit closed for {circuitId}.", circuit.Id);
return base.OnCircuitClosedAsync(circuit, cancellationToken);
}
public override Func<CircuitInboundActivityContext, Task> CreateInboundActivityHandler(Func<CircuitInboundActivityContext, Task> next)
{
return context =>
{
var scopeTags = new Dictionary<string, object>()
{
["BlazorUri"] = _navigationManager.Uri,
["CircuitId"] = context.Circuit.Id
};
using (_logger.BeginScope(scopeTags))
{
return next(context);
}
};
}
} Program.cs builder.Services.AddScoped<CircuitHandler, LoggingCircuitHandler>(); |
@alexandrejobin Thank you for your input. You might also post it as alternative solution to this question on StackOverflow: |
NLog version: 5.0.1
NLog.Web.AspNetCore version: 5.0.0
Platform: .Net 6.0 (Blazor Server)
Hey is it possible to log the URL of request in ASP.NET Blazor applications? Right now when I define
${aspnet-request-Url}
in the layout, it only gives this in logs:Is there a workaround for Blazor?
Related question on StackOverflow: https://stackoverflow.com/questions/72063711/logging-url-in-blazor-server-using-nlog
The text was updated successfully, but these errors were encountered: