问题
I want to save Activity.Current?.Id ?? HttpContext.TraceIdentifier
into database, because that is Request Id which user see in default error view. But how ? HttpContext is not available in startup.cs and i tried access HttpContext in LayoutRenderer not successfully.
Error method in HomeController
public IActionResult Error()
{
var model = new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier };
return View(model);
}
I tried LayoutRenderer
namespace Copacking.Web.Utils
{
[LayoutRenderer("requestid")]
public class NLogRequestIdLayoutRenderer : LayoutRenderer
{
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
builder.Append(Activity.Current?.Id ?? HttpContext.TraceIdentifier);
}
}
}
but I am getting an error with HttpContext, because object reference is required.
How can i solve it ? In Nlog.config file ${aspnet-traceidentifier} is working but ${activityid} variable is empty :/
回答1:
I'm not directly familiar with NLog, so forgive me if I'm missing something here, but in a truly abstracted logging setup, you shouldn't really have any hard NLog depedency, anyhow. Ideally, you should be using something like Microsoft.Extensions.Logging, and simply plugging NLog into that as the provider.
Then, from the controller perspective, you simply inject your logger, and log directly there:
public class ErrorController : Controller
{
private readonly ILoggerFactory _loggerFactory;
public ErrorController(ILoggerFactory loggerFactory)
{
_loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
}
public IActionResult Error()
{
var feature = HttpContext.Features.Get<IExceptionHandlerFeature>();
var logger = _loggerFactory.CreateLogger(feature.Error.TargetSite.DeclaringType);
logger.LogError(feature.Error, "{RequestId} {ErrorMessage}", new
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier,
ErrorMessage = feature.Error.Message
});
var model = new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier };
return View(model);
}
回答2:
How can i solve it ? In Nlog.config file ${aspnet-traceidentifier} is working but ${activityid} variable is empty :/
As per NLog wiki ${Activity}
takes the value from Trace.CorrelationManager.ActivityId
. You try assigning a value at the request start.
if(System.Diagnostics.Trace.CorrelationManager.ActivityId.Equals(Guid.Empty))
System.Diagnostics.Trace.CorrelationManager.ActivityId = Guid.NewGuid();
回答3:
You can do the following with https://www.nuget.org/packages/NLog.Web.AspNetCore:
layout="${activityid:whenEmpty=${mdlc:item=RequestId:whenEmpty=${aspnet-TraceIdentifier}}}"
Remember to include the following in NLog.config:
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
来源:https://stackoverflow.com/questions/51249438/nlog-how-to-access-requestid