-
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
[sdk] Use reflection and dynamic types to start providers #4151
Conversation
Relying on ref emit is going to cause problems with Native AOT and potentially trimming. While there will need to be application code differences for those apps - we want to keep that to a minimum, and I would suggest that this is such a fundamental scenario that having differences is going to be bad. |
@samsp-msft What's funny is I spent much effort in .NET 7 and OTel 1.4 to remove our reflection emit only to put it back for this 🤣 We could add a dependency on |
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## main #4151 +/- ##
==========================================
+ Coverage 85.56% 85.58% +0.01%
==========================================
Files 293 292 -1
Lines 11371 11467 +96
==========================================
+ Hits 9730 9814 +84
- Misses 1641 1653 +12
|
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. This is a nice user experience improvement / simplification. We need to follow up with .NET runtime folks and see how to eventually get rid of reflection (not blocking).
@@ -5,6 +5,10 @@ | |||
* Removed the dependency on System.Reflection.Emit.Lightweight | |||
([#4140](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4140)) | |||
|
|||
* The `AddOpenTelemetry` extension will now register an `IHostedService` if |
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.
lets do a more detailed write up here for folks updating to this version. Most end users do not really have the context about this, so we should write the steps one should follow when updating to this version.
- Remove the nuget reference to otel.ext.hosting.
- Remove the startwithhost().
- (change ns based on the other PR from alan.)
Its okay to do this in a separate 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.
also need to write the steps for those users who have to manually retrieve MP/TP .
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 will tackle this in a follow-up. Need to update documentation and then I'll drop a link here for more info.
this.WriteEvent(48); | ||
} | ||
|
||
[Event(49, Message = "OpenTelemetry IHostedService application services registration skipped. Reason: '{0}'", Level = EventLevel.Informational)] |
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.
Warning? This is user-actionable right? We could point users to the steps they should take to resolve 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.
There are 3 reasons we could log skipped:
RuntimeFeature.IsDynamicCodeSupported
==false
Microsoft.Extensions.Hosting.IHostedService, Microsoft.Extensions.Hosting.Abstractions
type could not be found- Reflection/dynamic code blew up. This will also cause an Error to be written for
HostedServiceRegistrationFailure
event.
1 + 2 could be normal/expected, just depends on who is setting up the host. I just updated it to be a warning but if any of that changed your mind LMK.
I don't think using reflection here is a clean approach. Why can't we have the existing AddOpenTelemetryMetrics and AddOpenTelemetryTracing APIs in Extensions.Hosting. The Extensions.Hosting package is a different package that provides a better DI support model so this package exposing different APIs is better than using the hacky reflection here in my opinion. |
As a user I would prefer |
var iHostedServiceType = Type.GetType( | ||
"Microsoft.Extensions.Hosting.IHostedService, Microsoft.Extensions.Hosting.Abstractions", throwOnError: false); | ||
|
||
if (iHostedServiceType == null) |
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.
How will it behave for AzureFunctions. I believe IHostedService will be found on AzureFunctions but the hostedService infra is not supported.
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 Functions team added special support for OTel Hosted Service. I'll try to find that PR, but yes this is something to be tried out. (Independent of this, Otel 1.4 wont work in Functions unless dedicated plan, due to Functions not supporting DS 7.0)
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.
https://github.com/Azure/azure-functions-host/blob/d4655cc4fbb34fc14e6861731991118a9acd02ed/src/WebJobs.Script.WebHost/DependencyInjection/DependencyValidator/DependencyValidator.cs#L57 This one. The ns etc needs to be changed to match this 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.
So, Otel is going to break for Azure functions with 1.4 upgrade? Shouldn't there be a major version bump if it's breaking the functionality for a group of customers?
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 do not think so. There is no breaking change in 1.3 -> 1.4. Its just Azure Functions has a strict DS version dependency. As mentioned in the issue in Azure Functions host, the issue is not with OTel. Any app with DS 7.0 will not work.
Azure/azure-functions-host#8938
(IIRC, this issue was there from 1.0 of OTel onwards (Azure/azure-functions-host#7135) and it got fixed, but again broken (with every new .NET release). Hopefully by the time 1.4 is stable, Functions will fix it :)
Either way, lets use #4047 for this conversation, as this is unrelated to this 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.
If the issue is only with azure functions than it's okay. If it hits any regular .NET flavors than it's a major breaking change.
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.
This is a great callout. Shamefully, I was not aware of this in Azure Functions! Playing with the code right now, I think we can make it backwards compatible with what functions is doing.
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.
OK I just pushed an update that makes Azure Functions happy locally. Need to verify on an actual build of the packages but I think we're good.
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.
@RohitRanjanMS Would you be able to help confirm if this will continue to work in Functions?
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.
Thanks @cijothomas, yes, this will work for Functions.
Summarizing my understanding/thoughts: With 1.4.0-rc3, OTel SDK has native DI capabilities. Also, we need to write a clear step-by-step guide for users upgrading to this version as an issue, and link to that issue from the package deprecations, Obsolete messages, and possibly from internal logs. I can imagine a lot of users (who are not actively following this), would be confused when the package goes missing, and all the breaking changes. |
When such ability gets into .NET, is it going to be in all .NET versions? If not than this reflection is here to live for a very long time, right?
It's a breaking change so wouldn't it demand a major version bump? |
There is no breaking change in any stable releases. Only in pre-release versions, so don't warrant major version bump. |
I would suggest that taking a dependency on Microsoft.Extensions.Hosting.Abstractions from OpenTelemetry.Extensions.DependencyInjection would probably be cleaner and have less impact on customers than this change. There is going to be a big push for Native AOT for ASP.NET Core, and so this will be the wrong direction at that time, |
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.
some follow ups required in docs to help users migrate smoothly, but this should not block this PR.
…en-telemetry#4151)" This reverts commit b549e12.
@CodeBlanch , @cijothomas , I meet the same issue after migrating OTel to 1.4.0-rc.3, may I confirm with you whether this PR is the fix for the issue - "Could not load file or assembly 'System.Diagnostics.DiagnosticSource, version=7.0.0 ...'" with Azure function? What's the version of OTel is going to release? |
@hejingkan2005, please check 1.4.0-rc.4. |
@Kielek , thank you for your comment, but 1.4.0-rc.4 is not applicable as we get two other dependent packages which ask for version must equal to 1.4.0-rc.3: |
This PR (which was reverted), is not for addressing any Functions specific issue. |
I've received a lot of feedback that
StartWithHost
isn't great 🤣 Chatted offline with some folks who seemed to think a reflection-based solution would be better so here goes...Changes
StartWithHost
and uses magic to let theAddOpenTelemetry()
extension (part of SDK) own that responsibility without a dependency onMicrosoft.Extensions.Hosting.Abstractions
.Details
With this change the
IHostedService
currently registered intoIServiceCollection
byOpenTelemetry.Extensions.Hosting
becomes part of the SDK. If the SDK finds theMicrosoft.Extensions.Hosting.IHostedService
type (reflectively) andRuntimeFeature.IsDynamicCodeSupported
is true the SDK will automatically build anIHostedService
and drop it into theIServiceCollection
. We won't need theOpenTelemetry.Extensions.Hosting
package at all if we do this... we can just mark it deprecated and remove the code from the solution. Users who do not have dynamic code support can either access theTracerProvider
and/orMeterProvider
manually from theIServiceProvider
or use the "Sdk.Create*().Build()" configuration style (aka "Console" style).TODOs
CHANGELOG.md
updated for non-trivial changes* [ ] Fix up documentationWill do this as a follow-up.