extensions icon indicating copy to clipboard operation
extensions copied to clipboard

How do I use AddHttpClientLatencyTelemetry?

Open aetos382 opened this issue 1 year ago • 2 comments

Description

See the reproduction steps section for the code I wrote.

The code outputs the following log.

{
  "EventId": 1,
  "LogLevel": "Information",
  "Category": "Microsoft.Extensions.Http.Logging.HttpClientLogger",
  "Message": "GET dot.net/REDACTED",
  "State": {
    "Message": "LatencyInfo=,,http.request.method=GET,server.address=dot.net,url.path=REDACTED,Duration=2613,http.response.status_code=200",
    "LatencyInfo": ",",
    "http.request.method": "GET",
    "server.address": "dot.net",
    "url.path": "REDACTED",
    "Duration": 2613,
    "http.response.status_code": 200
  }
}

The LatencyInfo in log is empty. How can I get it to output a valid value here?

I apologise if I have misunderstood how to use this library. In that case, please tell me how to use it correctly.

Reproduction Steps

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

var services = new ServiceCollection();

services
    .AddHttpClient()
    .AddRedaction()
    .AddLatencyContext()
    .AddExtendedHttpClientLogging()
    .AddHttpClientLatencyTelemetry();

services.AddLogging(static builder =>
    builder.AddJsonConsole(static options =>
    {
        options.JsonWriterOptions = new()
        {
            Indented = true
        };
    }));

await using var serviceProvider = services.BuildServiceProvider();

var client = serviceProvider.GetRequiredService<HttpClient>();

using var response = await client.GetAsync("http://dot.net").ConfigureAwait(false);

Console.WriteLine(response.StatusCode);

Expected behavior

The LatencyInfo in the log should be as follows, shouldn't it?

"LatencyInfo": ",handreqs/dnss/dnse/cons/cone/cones/rlq/reqhs/reqhe/reshs/reshe/enrin/,0.1706/68.8664/81.0259/86.9632/335.9692/341.1706/341.921/342.4656/342.7676/629.649/630.2728/1358.2388999999998/"

Actual behavior

The LatencyInfo in the log is as follows

"LatencyInfo":","

Regression?

The behavior was the same in ver 8.0.0.

Known Workarounds

No response

Configuration

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Compliance.Redaction" Version="9.0.0" />
    <PackageReference Include="Microsoft.Extensions.Http.Diagnostics" Version="9.0.0" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.0" />
  </ItemGroup>

</Project>

Other information

HttpClientLoggerHandler runs outside HttpLatencyTelemetryHandler because the wrapHandlersPipeline parameter is set to true when the HttpClientLogger is added.

https://github.com/dotnet/extensions/blob/16acdbf1442f579862cfea15ffd0782510078ff0/src/Libraries/Microsoft.Extensions.Http.Diagnostics/Logging/HttpClientLoggingHttpClientBuilderExtensions.cs#L96-L100

The ILatencyContext is stored in AsyncLocal, so it is not possible to read the value that was set downstream of the call from upstream. In other words, I think that the HttpClientLoggerHandler cannot get the values set by the HttpLatencyTelemetryHandler.

When I changed the wrapHandlersPipeline parameter to false while debugging, I got the output I wrote in the Expected behaviour section. Is it correct that this parameter is true?

Alternatively, using AsyncState instead of AsyncLocal.

aetos382 avatar Dec 16 '24 07:12 aetos382

@aetos382 Thank you for reporting the bug.

iliar-turdushev avatar Jan 10 '25 10:01 iliar-turdushev

@aetos382 thank you for reporting this bug. There’s an open issue scheduled for review this week, and based on the outcome, we’ll implement the appropriate fix. I’ll keep you updated

rainsxng avatar Dec 01 '25 15:12 rainsxng