代码之家  ›  专栏  ›  技术社区  ›  C. Molendijk

Application Insights-从.net核心中间件添加属性

  •  0
  • C. Molendijk  · 技术社区  · 7 年前

    我正试图从我们的.net核心MVC应用程序中获得一些额外的信息来深入了解应用程序。我找到了以下帖子: Adding custom properties for each request in Application Insights metrics

    现在我们的应用程序中有了一组中间件。他们把一些标题翻译成可读的内容。

    1 回复  |  直到 7 年前
        1
  •  5
  •   C. Molendijk    7 年前

    using Microsoft.AspNetCore.Http;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Test.API.Middleware
    {
        public class ValueMiddleware
        {
            private readonly RequestDelegate next;
    
            public ApiKeyMiddleware(RequestDelegate next)
            {
                this.next = next;
            }
    
            public async Task Invoke(HttpContext httpContext)
            {
                if (!context.Items.ContainsKey("ApplicationData"))
                {
                    httpContext.Items["ApplicationData"] = "Important Data";
                }
            }
        }
    }
    

    然后,当您需要将所有这些项目放入application insights时,您可以使用以下初始值设定项:

    using Microsoft.ApplicationInsights.Channel;
    using Microsoft.ApplicationInsights.Extensibility;
    using Microsoft.AspNetCore.Http;
    
    namespace Test.API.TelemetryInitializers : ITelemetryInitializer
    {
        public class HttpContextItemsTelemetryInitializer
        {
            private readonly IHttpContextAccessor httpContextAccessor;
            public HttpContextItemsTelemetryInitializer(IHttpContextAccessor httpContextAccessor)
            {
                this.httpContextAccessor = httpContextAccessor;
            }
    
            public void Initialize(ITelemetry telemetry)
            {
                var context = httpContextAccessor.HttpContext;
                if (context == null)
                {
                    return;
                }
    
                foreach (var item in context.Items)
                {
                    var itemKey = item.Key.ToString();
    
                    // Remove some pollution that Microsoft and the systems adds to the HttpContext Items.
                    if (itemKey.Contains("Microsoft") || itemKey.Contains("System"))
                    {
                        continue;
                    }
    
                    if (!telemetry.Context.GlobalProperties.ContainsKey(itemKey))
                    {
                        telemetry.Context.GlobalProperties.Add(itemKey, item.Value.ToString());
                    }
                }
            }
        }
    }
    

    using Test.API.TelemetryInitializers;
    using Microsoft.ApplicationInsights.Extensibility;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.DependencyInjection;
    
    namespace Test.API
    {
        public class Startup
        {
            // This method gets called by the runtime. Use this method to add services to the container.
            // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    
                services.AddSingleton<ITelemetryInitializer, HttpContextItemsTelemetryInitializer>();
                services.AddApplicationInsightsTelemetry();
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                app.UseMiddleware<ValueMiddleware>();
                app.UseMvc();
            }
        }
    }
    

    然后将HttpContext.Items的所有值添加到您的应用程序洞察中。

        2
  •  0
  •   Oliver    5 年前

    而不是将中间件中的数据放入 HttpContext 经营一个 TelemetryInitializer ,您可以直接将所需数据添加到中间件内的遥测对象中:

    public class TelemetryMiddleware
    {
        private const string _BodyKey = "Body";
        private readonly RequestDelegate _next;
    
        public TelemetryMiddleware(RequestDelegate next)
        {
            _next = next;
        }
    
        public async Task Invoke(HttpContext httpContext)
        {
            httpContext.Request.EnableBuffering();
    
            if (httpContext.Request.Body.CanRead
                && (httpContext.Request.Method == HttpMethods.Put
                    || httpContext.Request.Method == HttpMethods.Post
                    || httpContext.Request.Method == HttpMethods.Patch))
            {
                // The needed method to access telemetry object within middleware
                var telemetry = httpContext.Features.Get<RequestTelemetry>();
    
                if (telemetry != null
                    && !telemetry.Properties.ContainsKey(_BodyKey))
                {
                    var oldPosition = httpContext.Request.Body.Position;
                    httpContext.Request.Body.Position = 0;
    
                    using (var reader = new StreamReader(httpContext.Request.Body, Encoding.UTF8, false, 4096, true))
                    {
                        var body = await reader.ReadToEndAsync();
    
                        if (!string.IsNullOrEmpty(body))
                            telemetry.Properties.Add(_BodyKey, body);
                    }
    
                    httpContext.Request.Body.Position = oldPosition;
                }
            }
    
            await _next(httpContext);
        }
    }
    

    app.UseMiddleware<TelemetryMiddleware>();