.netazureazure-application-insightstelemetry

Avoid sending anonymous User.Id and Session.Id to Application Insights for Non-HTTP Operations


I'm facing an issue with Application Insights where the user count is being incremented even for non-HTTP operations, leading to inaccurate user statistics. I have a Telemetry Initializer that sets custom session and user IDs base on the request header. However, this initializer runs periodically, causing sending anonymous data like User.Id and Session.Id.

Here's a simplified version of my Telemetry Initializer:

TelemetryInitializer.cs

public class TelemetryInitializer : ITelemetryInitializer
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public TelemetryInitializer(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public void Initialize(ITelemetry telemetry)
    {
            string customSessionId = _httpContextAccessor?.HttpContext?.Request.Headers["MyHeader"];

            if(customSessionId is null)
              return;

            telemetry.Context.Session.Id = customSessionId;
            telemetry.Context.User.Id = customSessionId;
        }
    }
}

Program.cs

builder.Services.AddHttpContextAccessor();
builder.Services.AddSingleton<ITelemetryInitializer, TelemetryInitializer >();
builder.Services.AddApplicationInsightsTelemetry();

enter image description here

About application: .NET 7 Core, Web API without views so I can't add js code and I wouldn't like to do it, only swagger.


Solution

  • To avoid incrementing the user count for non-HTTP operations. One approach to address this issue That is to check if the telemetry operation is an HTTP request before setting the session and user IDs.

    Code:

    public class TelemetryInitializer : ITelemetryInitializer
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
    
        public TelemetryInitializer(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }
    
        public void Initialize(ITelemetry telemetry)
        {
            // Check if the operation is an HTTP request
            if (!(telemetry is RequestTelemetry requestTelemetry))
            {
                // Skip non-HTTP operations
                return;
            }
    
            // Check if there is a custom session ID header in the HTTP context
            string customSessionId = _httpContextAccessor?.HttpContext?.Request.Headers["MyHeader"];
    
            if (customSessionId is null)
            {
                // Skip if there is no custom session ID
                return;
            }
    
            // Set session and user IDs for HTTP requests
            telemetry.Context.Session.Id = customSessionId;
            telemetry.Context.User.Id = customSessionId;
        }
    }
    

    enter image description here

    HTTP and Non-HTTP Operations: enter image description here