-
Notifications
You must be signed in to change notification settings - Fork 772
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
[build] Use compiler constant to toggle experimental public apis #4735
[build] Use compiler constant to toggle experimental public apis #4735
Conversation
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## main #4735 +/- ##
==========================================
- Coverage 82.08% 82.07% -0.02%
==========================================
Files 313 313
Lines 12784 12784
==========================================
- Hits 10494 10492 -2
- Misses 2290 2292 +2
|
<ExposeExperimentalFeatures Condition="'$(MinVerPreRelease)' != ''">true</ExposeExperimentalFeatures> | ||
<ExposeExperimentalFeatures Condition="'$(MinVerPreRelease)' == ''">false</ExposeExperimentalFeatures> |
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.
@utpilla I'll need to verify once this is all done and building, but this change should automatically toggle ExposeExperimentalFeatures
in the publish workflow.
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 could probably also look at updating the publish-packages workflow by making use of the release event activity types:
https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#release
@@ -22,12 +22,21 @@ | |||
using OpenTelemetry.Internal; | |||
using OpenTelemetry.Trace; | |||
|
|||
#if EXPOSE_EXPERIMENTAL_FEATURES | |||
namespace OpenTelemetry.Logs.Experimental; |
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 would discourage placing experimental features into a different namespace. This placement means it will be impossible to ship a new experimental feature by simply marking it public
(which would be a non-breaking change for both source and binary consumers). By requiring a rename of the namespace, you end up with a source and binary breaking change which tends to produce churn that adds unnecessary ship risk to the 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.
What you think about this feedback @alanwest?
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.
By requiring a rename of the namespace, you end up with a source and binary breaking change which tends to produce churn that adds unnecessary ship risk to the process.
I definitely see some value in not placing the experimental features into their own namespace. It would make the process of stabilizing the experimental features seamless for customers (as they wouldn't need to update their namespaces).
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 feel strongly that an Experimental
namespace is the best way to address my underlying concern. It's just one idea and maybe a bad one at that. I'm open to other ideas. Since we talked about this offline, I'll summarize my concern and what I'm interested in brainstorming. Consider the following scenario
- User begins using 1.6.0-beta
- User starts using the experimental log API and/or exemplar APIs
- Then 1.6.0 stable is release
- User gets excited and upgrades to the stable release only to find their code does not compile anymore
There's a variety of things we can consider to ameliorate this pain
- Include clear release notes
- Immediately publish a 1.7.0-alpha.1 release on the heels of the 1.6.0 stable allowing users to stay on the latest code and continue using experimental APIs.
Though, since in my experience many folks do not read release notes, I was trying to consider an option that makes it more abundantly clear that a user is using an experimental feature.
In my opinion, I think the best way I've seen this done is to ship experimental stuff in a separate package altogether much like we did with the OTLP log exporter. This pattern has the additional benefit of aligning with what most other OTel language SDKs do today. Though, I suspect this pattern may be challenging to apply to the log and exemplar APIs, so if this is true, then I am supportive of the pattern this PR poses.
Though, at a minimum, I think we should make sure to do 1 and 2 above.
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 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 reverted the namespace and added this to the XML comments:
/// <remarks><b>WARNING</b>: This is an experimental API which might change or be removed in the future. Use at your own risk.</remarks>
When we consume the net8 bits we can also add ExperimentalAttribute
into the mix.
…IMENTAL_FEATURES.
/// </summary> | ||
/// <remarks> | ||
/// <para><inheritdoc cref="AddInstrumentation{T}(LoggerProviderBuilder, T)" path="/remarks"/></para> | ||
/// Note: The type specified by <typeparamref name="T"/> will be |
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.
Add the warning for this method as well?
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.
It is there on line 41 via the inheritdoc
. Easy to miss 😄 I did my best to not copy the warning text everywhere. It should be at most in 1 spot per assembly. In SDK there are 2, one for logs and one for exemplars. Because I figured it was a good idea to detach those two conceptual areas from each other.
@@ -30,13 +30,13 @@ | |||
</ItemGroup> | |||
|
|||
<ItemGroup> | |||
<Compile Include="$(RepoRoot)\src\Shared\Guard.cs" Link="Includes\Guard.cs" /> | |||
<Compile Include="$(RepoRoot)\src\Shared\Guard.cs" Link="Includes\Guard.cs" Condition="'$(ExposeExperimentalFeatures)' == 'true'" /> |
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: Create a new ItemGroup
with this condition and place these four shared files under it.
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
@@ -19,6 +19,7 @@ | |||
[assembly: InternalsVisibleTo("OpenTelemetry.Extensions.Hosting.Tests" + AssemblyInfo.PublicKey)] | |||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] | |||
|
|||
#if EXPOSE_EXPERIMENTAL_FEATURES |
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.
Why is this being wrapped in the experimental check?
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 !EXPOSE_EXPERIMENTAL_FEATURES
than OpenTelemetry.Extension.Hosting
sees the internals of OpenTelemetry.Api and it also sees the internal static class AssemblyInfo from that same file.
It is essentially yet another InternalsVisibleTo
problem 🤣
Check out this commit I pushed. I had the idea to use this new C# 11 file-local types feature to prevent these AssemblyInfo
helper classes from flowing to other assemblies. Let me know what you think about that!
@@ -27,3 +27,4 @@ static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetCoreInstrum | |||
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder | |||
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action<OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreInstrumentationOptions> configureAspNetCoreInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder | |||
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action<OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreInstrumentationOptions> configureAspNetCoreInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder | |||
virtual OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreMetricsInstrumentationOptions.AspNetCoreMetricEnrichmentFunc.Invoke(string name, Microsoft.AspNetCore.Http.HttpContext context, ref System.Diagnostics.TagList tags) -> void |
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.
Is this being added because of the new public API analyzer?
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. The new beta seems to have improved delegate checking or something 🤣
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 new beta seems to have improved delegate checking or something
Correct. The previous version listed delegates as simple types, without any indication of what the return value or parameter types were. The full delegate signature is captured by the implicitly-created Invoke
method, which doesn't exist in source but now is included in the Public API files in order to catch breaking changes to these signatures.
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.
#pragma warning disable SA1400 // Access modifier should be declared | ||
file static class AssemblyInfo |
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.
@sharwell I couldn't find an order for the modifiers that would make SA1400/SA1206 and IDE0036 happy. I'm sure you are aware of this but I thought I would mention it.
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.
DotNetAnalyzers/StyleCopAnalyzers#3588
Fixed in 1.2.0-beta.507 and newer.
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.
What this PR does is move the Log Bridge artifacts (Logger, LoggerProvider, etc.) and Exemplar artifacts under a compiler constant/switch that will make them
public
orinternal
based on a build property. For pre-release builds (alpha/beta/rc) these things will be markedpublic
and for stable releases they will be markedinternal
. The goal being to allow us to expose experimental things in order to gather feedback while reserving the right to make changes.