-
Notifications
You must be signed in to change notification settings - Fork 129
Description
Current State and Challenges
OpenTelemetry.AutoInstrumentation for .NET (Core) often requires setting the DOTNET_ADDITIONAL_DEPS and DOTNET_SHARED_STORE environment variables. This helps resolve assembly version conflicts between the instrumented application and the instrumentation tool, allowing both to load their required dependencies and ensuring that auto-instrumentation works correctly.
However, this is not a foolproof solution. The following issues remain:
-
Ongoing assembly conflicts:
See [Feature]: StartupHook dependency resolving dotnet/runtime#66138 and Consider removing Microsoft.Extensions.* from additional deps #4155 -
Limited support for self-contained applications:
Mentioned in the original ticket (needs re-verification): Diagnostic Source assembly versioning Issue #260 -
Frequent maintenance:
Updates to the .NET runtime, application dependencies, or instrumentation tools may require repeated updates to the shared store and deps files.
Profiler-based Proposed Solution
Based on my initial experiments with the assembly reference redirection approach (already used in profiler-based instrumentation for .NET Framework), it seems promising that it can be effectively adapted for .NET (Core) by leveraging an already in-use custom AssemblyLoadContext which can be further enhanced (right now it is not used in its full potential).
StartupHook-only Proposed Solution
For StartupHook-only deployments (without a profiler), I experimented with a custom AssemblyLoadContext AND redirecting the instrumented application into this custom context (the secret sauce for this solution). I tried it in a sandbox project (not with the actual OpenTelemetry project yet) but loading the instrumented application into a custom context reduces the influence of the Trusted Platform Assemblies (TPA) list on the automatic resolution of assemblies by the .NET runtime. This makes it much easier to intervene and customize the assembly loading process, giving us more flexibility to resolve conflicts as needed in the use case where profiler is not loaded.
Both solutions could potentially work side by side, giving customers the option to choose their preferred approach (with assembly reference redirection as the default for profiler-based scenarios and the extended AssemblyLoadContext for StartupHook-only scenarios). Together, these approaches might address most dependency issues without requiring to set additional dependencies nor shared store environment variables. I would even go further and remove the store approach altogether; we may make it work with the store approach, but it will probably add unnecessary complexity. In addition, these two new approaches would build on what already works for .NET Framework and make a fuller use of already existing AssemblyLoadContext for assembly isolation in .NET (Core).
Potential Considerations
- The StartupHook-only solution would result in the customer assembly being loaded twice (including once in the additional context) which will require additional handling to be eliminated.
- Some applications may explicitly use
AssemblyLoadContext.Defaultto load assemblies, which could require additional handling, especially for StartupHook-only deployments, where the application is loaded into a separate context. - If a customer subscribes to an assembly resolve event to load a newer version of an assembly than the one we've already loaded, this may not be supported, though this scenario should be relatively rare.
Overall, while these considerations exist, I believe these approaches should significantly reduce dependency conflicts and simplify deployment for most use cases.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status