ASP.NET Core Application Insights 400 ModelState详细信息

时间:2018-09-06 14:59:56

标签: azure-application-insights asp.net-core-2.1

我正在尝试确定是否有可能查看应用程序内为什么发生400错误的详细信息。我认为知道不具有该值的属性将可以更好地针对漏洞进行调查。例如,知道它是“名称”属性。

我在Azure中配置了应用程序见解。它成功收集了Web应用程序发出的400个响应,但未显示任何详细信息。

特别是在这种情况下,我在ActionFilterAttribute中看到了此代码生成的400。

public override void OnActionExecuting(ActionExecutingContext context)
{
    if (!context.ModelState.IsValid)
    {
        context.Result = new BadRequestObjectResult(context.ModelState);
    }
}

响应的内容将包含JSON序列化的ModelState值。

这种情况发生时,App Insights记录错误,指出请求失败,并显示400状态代码。它不显示任何ModelState值。

我实际上希望能够看到的关键信息不是模型的内容(可能包含敏感信息),但是ModelState.Values集合的详细信息的收集实际上等同于它具有以下属性:

ModelState.Values.Keys.Key
ModelState.Values.Keys.Errors()

无效的属性会将ModelState.Values.Keys.ValidationState设置为false。

到目前为止,我发现的内容似乎表明我可以通过手动获取TelemetryClient并将另一个事件添加到App Insights中来解决此问题。

是否可以将此详细信息附加到任何具有400异常的请求上?还是我需要向TelemetryClient添加另一个自定义调用并以这种方式进行跟踪?

如果我能以某种方式将后者添加到ActionFilterAttribute中,以便全部在其中处理?

感觉像是我没有理解一些简单的东西,使一切都变得有意义。

2 个答案:

答案 0 :(得分:1)

您可以尝试利用AI SDK中的Telemetry InitializersThis GutHub repo有一个示例,说明如何在正在收集的请求遥测中更新属性,但是,它没有涉及在ModelState上下文属性的情况下如何专门工作,但是如果该上下文也可用,则您应该能够使用您要查找的属性。

它应该遵循以下原则:

import Component from 'module-name/lib/components/Component';
import AnotherComponent from 'module-name/lib/components/AnotherComponent';

然后将其注册到DI:

public class PropertyTelemetryInitializer : ITelemetryInitializer
{
    IHttpContextAccessor httpContextAccessor;

    public PropertyTelemetryInitializer(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }

    public void Initialize(ITelemetry telemetry)
    {
        if (telemetry is RequestTelemetry request)
        {
            request.Context.Properties["tenantName"] = httpContextAccessor.Value.Items["tenantName"].ToString();
        }
    }
}

答案 1 :(得分:0)

对于遇到此问题的任何人,我们最终在ASP.Net Core中创建一个结果过滤器,该过滤器在生成400响应时自动将模型状态记录为json。它为我们提供了所需的一切,以帮助您在错误发生时进行故障排除。

public sealed class Log400DetailsResultFilter : IResultFilter
{
    private readonly ILogger<Log400DetailsResultFilter> _log;

    public Log400DetailsResultFilter(ILogger<Log400DetailsResultFilter> log)
    {
        _log = log;
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
        if (context.HttpContext.Response.StatusCode == (int)HttpStatusCode.BadRequest && context.ModelState.ErrorCount > 0)
        {
            var errors = new SerializableError(context.ModelState);
            _log.LogError($"Bad Request Model State Errors: {JsonConvert.SerializeObject(errors)}");
        }
    }

    public void OnResultExecuting(ResultExecutingContext context)
    {

    }
}

然后只需在启动时注册它,它将针对所有400个结果运行。

services.AddMvc(config =>
{
    config.Filters.Add<Log400DetailsResultFilter>();
});

然后,在Application Insights中,您只需单击“端对端事务详细信息”刀片中的“查看所有遥测”按钮,它将为您显示该事务的所有日志,包括模型状态的详细信息。

enter image description here