-
Notifications
You must be signed in to change notification settings - Fork 782
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
[DependencyInjection] Introduce new package and refactor SDK #3923
[DependencyInjection] Introduce new package and refactor SDK #3923
Conversation
This PR was marked stale due to lack of activity and will be closed in 7 days. Commenting or Pushing will instruct the bot to automatically remove the label. This bot runs once per day. |
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 good and I think it is the approach we should move forward with.
Though, just putting some of my thought process into words...
I had waffled a lot on whether it just makes sense to adopt #3663 and have OpenTelemetry.Api just take a dependency on Microsoft.Extensions.DependencyInjection.Abstractions.
I think the main question is: who is the target audience for OpenTelemetry.Api and does OpenTelemetry.DependencyInjection have the exact same audience?
As it stands OpenTelemetry.Api serves two (maybe) distinct audiences.
Instrumentation authors
OpenTelemetry.Api enables instrumentation authors to:
- Use the OpenTelemetry shim API rather than DiagnosticSource directly.
- Use features of the OpenTelemetry API not yet provided by DiagnosticSource.
Instrumentation library authors
OpenTelemetry.Api enables instrumentation library authors to:
- Everything instrumentation authors do, plus
- Configure telemetry providers e.g., TracerProvider, MeterProvider.
So, the main distinction between an instrumentation author and an instrumentation library author is that the latter is concerned with configuration of emitted telemetry. Examples of configuration include enabling telemetry, filtering telemetry, hooks to further enrich telemetry, sanitizing telemetry, etc.
If we had it to do over again, would MeterProviderBuilder and TracerProviderBuilder not be in OpenTelemetry.Api? If this were the case then I think a separate package definitely makes sense.
But since MeterProviderBuilder and TracerProviderBuild are already in the API then it raises the question whether to continue shoving additional configuration related concerns into the API. I think the answer is still no and a separate package still makes sense. That said, I think the "instrumentation author" audience is theoretical, and in practice there are really only going to be "instrumentation library authors".
src/OpenTelemetry.DependencyInjection/ConfigureProviderBuilderCallbackWrapper.cs
Outdated
Show resolved
Hide resolved
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## main #3923 +/- ##
==========================================
- Coverage 85.50% 85.36% -0.15%
==========================================
Files 288 289 +1
Lines 11080 11219 +139
==========================================
+ Hits 9474 9577 +103
- Misses 1606 1642 +36
|
src/OpenTelemetry.DependencyInjection/OpenTelemetry.DependencyInjection.csproj
Outdated
Show resolved
Hide resolved
@@ -0,0 +1,25 @@ | |||
# OpenTelemetry .NET DependencyInjection |
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.
Should we call this project OpenTelemetry.Extensions.DependencyInjection
?
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.
Related to #3469 (specifically the section titled "Integrations for specific application frameworks or libraries")
I agree, I like OpenTelemetry.Extensions.DependencyInjection
. The package is mostly extensions involving IServiceCollection
and I'm pretty sure we don't see a future where it would deviate from this. There are a few extensions from IServiceProvider
as well, but I think this is ok.
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.
Updated with rename to: OpenTelemetry.Extensions.DependencyInjection
using Microsoft.Extensions.DependencyInjection; | ||
using OpenTelemetry.Internal; | ||
|
||
namespace OpenTelemetry.Metrics; |
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.
Normally the namespace would match the namespace of the thing being extended. In this case IServiceCollection
, so Microsoft.Extensions.DependencyInjection
.
In speaking with @CodeBlanch offline, he said he intentionally chose OpenTelemetry.Metrics
here because methods like ConfigureOpenTelemetryMeterProvider
are for more advanced use cases and he wanted to make it a little less likely these extensions would pop up in intellisense for more common use cases.
I think this is good reasoning, however, what if we took it a bit further and named it OpenTelemetry.Metrics.AdvancedExtensions
(ugh... naming is hard)? Users would have to be pretty intentional that they do in fact want to use them.
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.
.NET team has a guidance on naming: https://learn.microsoft.com/en-us/dotnet/core/extensions/options-library-authors#namespace-guidance, according to which they discourage people from using Microsoft.Extensions.DependencyInjection
as the namespace.
OpenTelemetry.Metrics.AdvancedExtensions
is good or we could have OpenTelemetry.AdvancedExtensions.Metrics
😀
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.
Or they could just not use ConfigureOpenTelemetryMeterProvider
after reading the documentation which would explicitly say it's for library authors?
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.
Just to add a little more to the discussion, in addition to changing the namespaces of these methods I also...
-
Changed the names. They used to be "ConfigureOpenTelemetryTracing/Metrics" and now they are "ConfigureOpenTelemetryTracerProvider/MeterProvider". I did that to intentionally scare away casual users. Hopefully they don't know what those things are and shy away from these methods in favor of the more friendly
AddOpenTelemetry
in their intellisense. -
Changed the signatures. They used to receive a simple delegate like
Action<TracerProviderBuilder>
now they receive the service provider as well likeAction<IServiceProvider, TracerProviderBuilder>
the goal there was to also scare away casual users looking for something easy 👻
PS: I am not opposed to moving them again to some sub namespaces, just wanted to point out these changes.
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.
they discourage people from using Microsoft.Extensions.DependencyInjection as the namespace.
Interesting! I thought I've read guidance stating the opposite before. Though maybe this is an exception?
In that case, we probably want to reconsider our use of Microsoft.Extensions.DependencyInjection
namespace for all the other classes in this PR?
Though what namespace should StartWithHost
be in? Either OpenTelemetry.Extensions.DependencyInjection
or OpenTelemetry.Extensions.Hosting
? If we did OpenTelemetry.Extensions.Hosting
then I think it would be very hard to find.
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.
Hmm... ok so maybe I was mistaken, this PR does not add anything to the Microsoft.Extensions.DependencyInjection namespace
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.
Hmm... ok so maybe I was mistaken, this PR does not add anything to the Microsoft.Extensions.DependencyInjection namespace
I was chatting with @utpilla offline about this. It was not a goal of this work to be compliant with the guidance, but it just kind of happened 🤣 The reason was we now have AddOpenTelemetry
which returns OpenTelemetryBuilder
. Extensions like StartWithHost
target OpenTelemetryBuilder
. To make it work nicely for users, everything should be in the same namespace. So it was either put everything in Microsoft.Extensions.DependencyInjection
or everything in OpenTelemetry
. The later felt more appropriate to me so that's what landed on the PR.
The only thing left in the MEDI namespace should be the hosting extensions which are now marked Obsolete
.
Is the extra required |
@bravecobra I'm not sure what you mean by breaking because
Old style: appBuilder.Services.AddOpenTelemetryTracing(/* tracing configuration code */);
appBuilder.Services.AddOpenTelemetryMetrics(/* metrics configuration code */); New style: appBuilder.Services.AddOpenTelemetry()
.WithTracing(/* tracing configuration code */)
.WithMetrics(/* metrics configuration code */)
.StartWithHost();
Should already be done (in this repo). You see somewhere I missed? The other examples and docs as well as tests should be smiliar. Also the obsolete warning has a hint. If you are talking about the open telemetry site, I'm not sure how to update that. Need to look into it 😄 |
Well, it seems I ran into problems, assuming that the OtlpExporterOptions were distinct per exporter (traces, metrics, etc..). This is no longer the case but it worked in Dependency injection wise each The easiest way to reproduce this, is with the AspNetCore example project, but exporting through HTTP (4318) instead of gRPC (4317) to an otel collector in Docker. It'll start throwing exceptions for the traces, since the metrics options are the last to be registered and the endpoint are set. If you don't know that those options are shared between traces and metrics unless you name them given the endpoints are being set, you'll run into issues easily. So in short, if you have multiple I had to check out this project to debug the issue as my code (https://github.com/bravecobra/emojivoto-dotnet) looked very similar to the examples project assuming that the examples project was working. It didn't when using Http. I assume lots of people will run into similar issues. |
@bravecobra Thanks for that write up! Same issue as #4043 I think. We should definitely do something about this. /cc @alanwest |
Yes, that seems to be exactly the same case I encountered. |
Relates to #3663
Overview
We have been discussing the public API additions for 1.4.0. One concern is that instrumentation libraries with only API references won't be able to participate fully in the library patterns. One option was #3663. This PR is another option which is to add another package which instrumentation could depend on without consuming the full SDK. Currently named OpenTelemetry.Extensions.DependencyInjection (itself depends on API + Microsoft.Extensions.DependencyInjection.Abstractions).
Changes
Refactors the following APIs from SDK into OpenTelemetry.Extensions.DependencyInjection:
Example usage
Here is a diff showing how this helps solve the problem.
New startup pattern
There is a new pattern being deployed here. We used to do this:
The new style is this:
The reason for that is something needs to invoke the SDK so it can patch everything up to pick up the
IConfigureTracerProviderBuilder
&IConfigureMeterProviderBuilder
registrations in theIServiceCollection
(that's what OpenTelemetry.DependencyInjection does). @alanwest and I kicked around a bunch of ideas and this is the best we could come up with.One thing nice it does as a side effect is give us a spot to do cross-cutting things. Like this:
PS: We can do logging there too, I'm just waiting on the spec to go stable before messing with it. I will update main-logs if/when this goes in.
Public API Changes
OpenTelemetry.Extensions.DependencyInjection
OpenTelemetry
OpenTelemetry.Extensions.Hosting
TODOs
CHANGELOG.md
updated for non-trivial changes