-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Wrap TelemetrySettings providers to add component-identifying attributes #12384
base: main
Are you sure you want to change the base?
Wrap TelemetrySettings providers to add component-identifying attributes #12384
Conversation
Do we have a real need for this? Seems unnecessary as far as the RFC goes. Can we leave it out for now and it can be proposed separately if necessary?
One thing I notice about this implementation is it treats TelemetrySettings in such a way that there is only one per component instance, as opposed to allowing derivatives to be made as necessary. The logger was implemented to follow traditional logger patterns, where one part of the codebase may want its own logger. For example, #12203 shows how the OTLP receiver could be refactored to have separate instances that share only the server. In this case, we'd want one set of attributes for each instance, and a different set for the shared server. In my opinion it would make sense that this same pattern be applied across the entire TelemetrySettings, so that share parts of the codebase can have their own set of attributes independently of other parts. |
To be able to remove attributes from a I've considered making it an unexported field to avoid expanding the API, but that would require putting the new functions as methods in the Do you have any ideas on how to leave it out?
Component authors can easily make a copy of the |
By the way, this may be a minor detail, but I noticed that the |
I believe the solution to both problems is the same - to have the "Without" method (whatever it is called) return a new instance. This way, the attributes do not need to be exported. On the topic of naming, I'd prefer we not use "Instance" in the name since TelemetrySettings is not meant exclusively for instances. We may find that there are other situations where we preload some attributes and allow them to be removed. Personally I think |
Ok, I'll move the |
Can we keep this as a function in |
If we do that, we can't access an unexported field on TelemetrySettings. |
If we need to, we can define |
That's a good point, I hadn't thought of that. |
I updated the API, tell me if this is not what you had in mind @djaglowski. It looks like the remaining CI failure is related to the fact that zpagesextension relies on SDK-only methods for TracerProvider. I added a This has the side effect of adding an indirect dependency on the SDK to a lot of modules, including component, configauth, connector, extension... Is that okay? If not I can define a new |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #12384 +/- ##
==========================================
+ Coverage 91.55% 91.61% +0.06%
==========================================
Files 467 472 +5
Lines 25652 25857 +205
==========================================
+ Hits 23485 23690 +205
Misses 1768 1768
Partials 399 399 ☔ View full report in Codecov by Sentry. |
# Include 'user' if the change is relevant to end users. | ||
# Include 'api' if there is a change to a library API. | ||
# Default: '[user]' | ||
change_logs: [user, api] |
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 approach looks good to me. Thank you for putting this together. Are there any visible changes for end-users at this point?
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 say yes, since this adds otelcol.component.id
and friends to basically all internal metrics/logs.
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 you please add this to the subtext or create another user-facing changelog item?
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 description of the item is "Internal metrics and spans now include component attributes", and the subtext already says "[The providers] automatically insert metric/span attributes which identify the originating component instance, as defined in the Pipeline Component Telemetry RFC". Do you think I should list the attributes explicitly?
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 reworded the changelog and added more details, tell me whether you think it's sufficient.
I like the new interface option better |
Looking into it more, it looks like it's not actually doable without importing the SDK unfortunately, since the interface relies on types from the SDK. The zpagesextension defines an extension with the two methods it needs, but imports the SDK anyway for the types in the method signatures. This is fine for its purpose (in case another API implementation has those methods but not others I guess), but in our case, we probably want to expose as much of the SDK as possible. |
newOptions = append(newOptions, metric.WithInt64Callback(wrapInt64Callback(cb, mwa.option))) | ||
} | ||
return mwa.Meter.Int64ObservableCounter(name, newOptions...) | ||
} |
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 method of wrapping the callbacks (using NewXConfig
to parse the options, wrapping the callbacks, then manually "reserializing" the config) will be somewhat problematic if the API adds a new kind of option for asynchronous instruments, as we will be silently dropping them until we update this code. Does anyone have a better way to do this?
tp = tpwa.TracerProvider | ||
} | ||
if tpSdk, ok := tp.(*sdkTrace.TracerProvider); ok { | ||
return tracerProviderWithAttributesSdk{ |
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.
An alternative method of exposing SDK-specific TracerProvider
methods would be to explicitly declare which methods we're forwarding. This would not allow us to drop the dependency on the SDK (since the relevant method signatures make use of SDK-only types), and it would require updating this code whenever new SDK-specific method are added. However, it would mean that alternate API implementations could hypothetically provide those same methods and have them forwarded.
Should we consider this an issue? Are there currently any alternate SDKs that provides methods like TracerProvider.RegisterSpanProcessor
? If yes, do we expect such cross-SDK methods to be added to the API eventually?
Description
Following the discussions in #12217, this PR adds (internal for now) code which wraps the
TracerProvider
andMeterProvider
incomponent.TelemetrySettings
to automatically add the component-identifying attributes defined in the Pipeline Component Telemetry RFC to all telemetry created by components.This PR has one addition to the user-visible API:
component.TelemetrySettings
now has aInstanceAttributes attribute.Set
field, which is used as the source of truth for theTracerProvider
,MeterProvider
, andLogger
. If this field is updated manually, the providers can be updated withcomponentattribute.UpdateInstanceAttributes
.The common use case of components opting out of certain attributes can be achieved by calling
componentattribute.RemoveInstanceAttributes
.Link to tracking issue
Fixes #12217
Also resolves #12213 and resolves #12117, as receiverhelper and exporterhelper use the TelemetrySettings of the component that uses them
Testing
For now, I've only done manual testing to check that the attributes are indeed added for the two signals.
Documentation
None for now.