Home > Enterprise >  Dependency logging with application insights does not log responses
Dependency logging with application insights does not log responses

Time:02-03

We have set up application insights with our ASP.NET Core 6 application which uses application insights for logging. We use a RestSharp based HTTP client for executing HTTP requests which works fine.

When trying to debug calls made through the RestSharp library, I am not seeing any response bodies being logged, only the statuscode, while the requests are being (kind of) logged:

App Insights logging

{
  "name": "AppDependencies",
  "time": "2023-02-02T06:05:04.6268266Z",
  "tags": {
    "ai.application.ver": "1.0.0.0",
    "ai.cloud.roleInstance": "MY_NICE_PC",
    "ai.user.id": "ltK4V",
    "ai.operation.id": "11bf52695a8d8ea19f1cb7573f2b195b",
    "ai.operation.parentId": "324234234234",
    "ai.operation.name": "POST to/somewhere [v]",
    "ai.location.ip": "::1",
    "ai.internal.sdkVersion": "rdddsc:2.21.0-429",
    "ai.internal.nodeName": "MY_NICE_PC"
  },
  "data": {
    "baseType": "RemoteDependencyData",
    "baseData": {
      "ver": 2,
      "name": "POST /none/of-your/business",
      "id": "bfa554335eefae0b",
      "data": "https://none.of.your.business/my-nice-api-0/my=1&nice&=2&querystring=3",
      "duration": "00:00:04.8666247",
      "resultCode": "422",
      "success": false,
      "type": "Http",
      "target": "none.of.your.business",
      "properties": {
        "DeveloperMode": "true",
        "AspNetCoreEnvironment": "localdev",
        "_MS.ProcessedByMetricExtractors": "(Name:'Dependencies', Ver:'1.1')"
      }
    }
  }
}

We are using ASP.NET Core 6.0 with the Microsoft.ApplicationInsights.AspNetCore version 2.2.21 and the following DI setup:

services.AddApplicationInsightsTelemetry(configure =>
            {
                configure.ConnectionString = "MySecretConnectionString";
                configure.EnableAdaptiveSampling = false;
            });   

--- Edit: I also made an implementation of the ITelemetryInitializer to capture all telemetry for all instances of DependencyTelemetry:

public class DependencyTelemetryInitializer : ITelemetryInitializer
    {
        public void Initialize(ITelemetry telemetry)
        {
            // SKIP for now
            if (telemetry is DependencyTelemetry dependencyTelemetry)
            {

            }
            
        }
    }

This showed me that for every dependency call only the request is being captured, but the response is not.

CodePudding user response:

I came up with the following, since it is needed to buffer the response, so that it can be read again, I have added the LoadIntoBufferAsync. Also this seems be available as Async only.

 public void Initialize(ITelemetry telemetry)
 {
       if (telemetry is DependencyTelemetry dependencyTelemetry && 
             dependencyTelemetry.Type.Equals(DEPENDENCYTELEMETRY_TYPE_HTTP, 
             StringComparison.InvariantCultureIgnoreCase)
                            && dependencyTelemetry.TryGetHttpResponseOperationDetail(out var response))
            {
                var task = Task.Run(async () => await response.Content.LoadIntoBufferAsync());
                task. Wait();

                var stream = response.Content.ReadAsStream();

                using var reader = new StreamReader(
                   stream,
                   Encoding.UTF8,
                   detectEncodingFromByteOrderMarks: false,
                   bufferSize: 512, leaveOpen: true);

                var responseBody = reader.ReadToEnd();

                dependencyTelemetry.Properties.Add("responseBody", responseBody);
            }
        }

CodePudding user response:

That is by design, the dependency call basically logs the outgoing call, as that is what application insights has access to. It logs the duration, and also the response code (422 in your example.) I am also not sure what kind of information you would expect to see from the response.

If you want to get access to the response you can do so in a TelemetryInitializer:

public class CustomInitializer : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        if (telemetry is DependencyTelemetry dt
                && dt.Type.Equals("http", System.StringComparison.InvariantCultureIgnoreCase)
                && dt.TryGetHttpResponseOperationDetail(out var response))
        {
            ...
        }
    }
}

You can then access the headers etc. Technically you can access the response content but since it is a stream by default it can only be read. So reading the full response content can't be done here withouth breaking the application afaik.

Also, even if you could, you should be carefull regarding logging the request and response playload. The size might be large, and Application Insights is not designed for that kind of log data. You might also hit the limits to the lenght of the custom properties and the logged payload will be cut off.

  • Related