-
Notifications
You must be signed in to change notification settings - Fork 773
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[http] Add http.client.request.duration metric and .NET Framework support #4870
[http] Add http.client.request.duration metric and .NET Framework support #4870
Conversation
…ensley/opentelemetry-dotnet into net462httpclientmetricsv3
…ensley/opentelemetry-dotnet into net462httpclientmetricsv3 # Conflicts: # src/OpenTelemetry.Instrumentation.Http/MeterProviderBuilderExtensions.cs
…equestActivitySource.netfx.cs Co-authored-by: Johannes Tax <[email protected]>
…ensley/opentelemetry-dotnet into net462httpclientmetricsv3
…equestActivitySource.netfx.cs Co-authored-by: Johannes Tax <[email protected]>
…equestActivitySource.netfx.cs Co-authored-by: Johannes Tax <[email protected]>
…ensley/opentelemetry-dotnet into net462httpclientmetricsv3
src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs
Outdated
Show resolved
Hide resolved
Codecov Report
@@ Coverage Diff @@
## main #4870 +/- ##
==========================================
+ Coverage 82.95% 83.19% +0.23%
==========================================
Files 294 294
Lines 12206 12279 +73
==========================================
+ Hits 10125 10215 +90
+ Misses 2081 2064 -17
Flags with carried forward coverage won't be shown. Click here to find out more.
|
@vishweshbankwar @alanwest @Kielek This ended up being a collaboration between me and @matt-hensley so I'm not going to self-review. Please take a look when you have time. |
internal static HttpClientInstrumentationOptions TracingOptions | ||
{ | ||
get => options; | ||
get => tracingOptions; | ||
set | ||
{ | ||
options = value; | ||
tracingOptions = value; | ||
|
||
emitOldAttributes = value.HttpSemanticConvention.HasFlag(HttpSemanticConvention.Old); | ||
emitNewAttributes = value.HttpSemanticConvention.HasFlag(HttpSemanticConvention.New); | ||
tracingEmitOldAttributes = value.HttpSemanticConvention.HasFlag(HttpSemanticConvention.Old); | ||
tracingEmitNewAttributes = value.HttpSemanticConvention.HasFlag(HttpSemanticConvention.New); | ||
} | ||
} | ||
|
||
internal static HttpClientMetricInstrumentationOptions MetricsOptions | ||
{ | ||
get => metricsOptions; | ||
set | ||
{ | ||
metricsOptions = value; | ||
|
||
metricsEmitOldAttributes = value.HttpSemanticConvention.HasFlag(HttpSemanticConvention.Old); | ||
metricsEmitNewAttributes = value.HttpSemanticConvention.HasFlag(HttpSemanticConvention.New); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact that old & new attributes is separate for Tracing and Metrics seems wrong to me. The HttpSemanticConvention comes from an environment variable. It should be set once for the whole process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ya it is weird. I think though if our plan is to remove the new/old/dupe stuff soon we should just live with it for a bit 😄
Having the two does allow you to do some interesting things. Imagine this...
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddHttpClientInstrumentation()
.AddOtlpExporter()
.ConfigureServices(s => s.AddSingleton<IConfiguration>(new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string> { ["OTEL_SEMCONV_STABILITY_OPT_IN"] = "http" })
.Build()))
.Build();
using var meterProvider = Sdk.CreateTracerProviderBuilder()
.AddHttpClientInstrumentation()
.AddPrometheusExporter()
.ConfigureServices(s => s.AddSingleton<IConfiguration>(new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string> { ["OTEL_SEMCONV_STABILITY_OPT_IN"] = "http/dup" })
.Build()))
.Build();
What that would do is send "new" semantic conventions via OTLP for traces and send "dupe" semantic conventions via Prometheus for metrics. That is because we support IConfiguration for each provider not just envvars for a process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think though if our plan is to remove the new/old/dupe stuff soon we should just live with it for a bit 😄
👍
if (semanticConvention != null && semanticConvention.Value.HasFlag(HttpSemanticConvention.New)) | ||
{ | ||
Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpMethod]); | ||
Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeServerAddress && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeNetPeerName]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a blocker for this PR, but this has a bad smell.
Because the json file wasn't updated, it's using the old attribute names from the test case to validate the new attributes.
When we finally ship stable, the json should be updated to have only the New attributes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we finally ship stable, the json should be updated to have only the New attributes.
👍
test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs
Outdated
Show resolved
Hide resolved
src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs
Show resolved
Hide resolved
} | ||
} | ||
|
||
HttpClientDuration.Record(durationMs, tags); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to use different histogram based on the configured option
metricsEmitOldAttributes - > http.client.duration
metricsEmitNewAttributes -> http.client.request.duration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this PR is focused on adding metrics to NetFx, where my PR was adding the NEW metric to the library. I don't think we should try to accomplish both goals in a single PR. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@TimothyMothra I think it is ok to do this here as your PR only updates HttpHandlerMetricsDiagnosticListener
. But we need two different Histograms for this to be correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the style is "dupe" what happens? You get both old + new histograms each with the full set of tags? Or you get old histogram with the old tags and new histogram with the new tags?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you get old histogram with the old tags and new histogram with the new tags
This^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These HttpClient tests currently are exercising both the .NET Framework & .NET/Core style instrumentations. If we make this change here the tests will start failing for the .NET/Core style. I'm thinking we should tackle both on @TimothyMothra's PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we remove the new conventions from here then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the style is "dupe" what happens? You get both old + new histograms each with the full set of tags? Or you get old histogram with the old tags and new histogram with the new tags?
We would emit old metric using old histogram and old attributes (http.client.duration + miliseconds) AND new metric using new histogram and new attributes (http.client.request.duration + seconds).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we remove the new conventions from here then?
I just pulled @TimothyMothra's work from #4891 into this PR. Seemed like more work to remove it all and then put it back in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just pulled @TimothyMothra's work from #4891 into this PR.
😲
src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs
Show resolved
Hide resolved
src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs
Outdated
Show resolved
Hide resolved
…lerMetricsDiagnosticListener.cs Co-authored-by: Vishwesh Bankwar <[email protected]>
…ensley/opentelemetry-dotnet into net462httpclientmetricsv3
internal static readonly string MeterVersion = AssemblyName.Version.ToString(); | ||
internal static readonly Meter Meter = new(MeterName, MeterVersion); | ||
private static readonly Histogram<double> HttpClientDuration = Meter.CreateHistogram<double>("http.client.duration", "ms", "Measures the duration of outbound HTTP requests."); | ||
private static readonly Histogram<double> HttpClientRequestDuration = Meter.CreateHistogram<double>("http.client.request.duration", "s", "Measures the duration of outbound HTTP requests."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: we are creating an instrument here even in when it will not be used (based on the option selected by user).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, but I wasn't worried about it. For example if user is using only tracing they'll have a Meter + Histogram today that is just sitting there of no use to them. So what's one more thingy? 🤣 Keeping them static readonlys is nice for hot path perf when they are used though. Plus I figured when @TimothyMothra cleans this up we'll go back to just a single histogram in play. Decided to just keep it dumb/simple, basically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - We need to work on changelog and readme
Changelog needs to clearly indicate added support for metrics in HttpWebRequest
Readme needs to be updated https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.Http/README.md#list-of-metrics-produced
I am ok with merging this as is and do follow up for items above (In favor of making progress).
Thanks @matt-hensley and @CodeBlanch!
Just FYI it will work on .NET Framework for either |
👍 I meant to clarify this. It may not be clear to users what is the difference between those two metrics. We should consolidate it with details here. @TimothyMothra will work on the follow up. |
Fixes #4764
Towards #4484
Changes
Adds the new
http.client.request.duration
metric in the HttpClient Instrumentation library.Adds support for
http.client.duration
&http.client.request.duration
metrics on .NET Framework. Unlike Add HttpClient metrics for .NET Framework #4768, this new implementation does not require tracing to be enabled for metrics generation to work.Tests have been updated to cover:
Merge requirement checklist
CHANGELOG.md
files updated for non-trivial changes