-
Notifications
You must be signed in to change notification settings - Fork 276
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
Reporter: allow extending samples with extra attributes #237
base: main
Are you sure you want to change the base?
Conversation
expectedIndices [][]uint64 | ||
expectedAttributeTable []*common.KeyValue | ||
}{ | ||
"empty": { | ||
profile: &profiles.Profile{}, |
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.
Not sure why this was in the struct: it seems that simply making this a local temporary variable in the loop below is easier. I reworked it accordingly, but perhaps I'm missing something on why this was done like this originally.
@@ -29,7 +27,6 @@ func TestGetSampleAttributes(t *testing.T) { | |||
pid: 0, | |||
}, | |||
}, | |||
attributeMap: make(map[string]uint64), |
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.
Same here.
Overall looks better than the generics approach 👍 |
reporter/attrmgr.go
Outdated
profile *profiles.Profile | ||
} | ||
|
||
func NewAttrTableManager(profile *profiles.Profile) *AttrTableManager { |
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.
*profiles.Profile
is internal to the package reporter. How are users of the package supposed to create it?
How should the integration look like, for a different kind of reporter, like for the OTel collector? see #208
From the updated testcase (TestGetSampleAttributes
), where this API is used, it looks more like this API builds a parallel *profiles.Profile
on top of an existing one just with attributes but without traces.
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 is this private? It's a public type from the OTEL proto lib?
From the updated testcase (TestGetSampleAttributes), where this API is used, it looks more like this API builds a parallel *profiles.Profile on top of an existing one just with attributes but without traces.
No, it's just populating the attribute table portion. I'll apply the change that Tim suggested here to make this clearer.
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.
Ah, I looked through #208 now, and I think what you are referring to is that it will be private in the future, replaced by the pdata type? I hadn't followed up with the collector reporter impl -- still catching up after ~1 month mostly away from this repo here -- apologies! Fortunately the changes that Tim suggested (and that I have applied now) should allow the type to generalize to allow using it in the new reporter implementation as well.
Co-authored-by: Tim Rühsen <[email protected]>
Rresolved conflict with profiling vs htlhash key
attrTable *[]*common.KeyValue | ||
} | ||
|
||
func NewAttrTableManager(attrTable *[]*common.KeyValue) *AttrTableManager { |
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.
Alternatively we could not take that any argument, and rename the type to AttrTableBuilder
. In that case I'd then add a new method GetAttrTable()
that returns the final built table. That'd change the workflow for the caller to:
- Create empty instance
- Populate it with
AddXXX
calls - Take the final table with
GetAttrTable()
and manually assign it to the attribute table field
Perhaps more obvious than mutating the slice field in place through a pointer? No strong preference here.
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 thought about this as well (named it Get()
to not repeat AttrTable), but it comes with the downside that you need to call this function when done. And this can be forgotten, while the solution in this PR is safer from accidental failure.
My not very strong preference would be to avoid an extra Get
function call.
type SampleAttrProducer interface { | ||
// CollectExtraSampleMeta gathers extra sample meta-info and returns it as | ||
// a pointer to a **hashable** struct. | ||
CollectExtraSampleMeta(trace *libpf.Trace, meta *TraceEventMeta) any |
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.
Can the returned any
replaced with a (generic) type?
Maybe generic type parameters could help here? My worry is, that any
might introduce subtle bugs by not using this API correctly.
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.
Not elegantly. It'd require us to also propagate the type parameter to Config
and OTLPReporter
structs.
This PR does two things:
Replace
addProfileAttributes
andattrKeyValue[T]
withAttrTableManager
I found the previous design with the generic on
addProfileAttributes
rather inelegant. Firstly, there's no covariance on Go generics, so it would take twoaddProfileAttributes
calls and anappend
to add both string and int attributes:opentelemetry-ebpf-profiler/reporter/otlp_reporter.go
Lines 669 to 675 in 47e8410
It also required reflection in
addProfileAttributes
for no good reason. IMHO this isn't really a good use-case for generics. InAttrTableManager
this is replaced with two separate methods that each add just one attribute.Secondly, a proper type for this results in a much cleaner interface for the second change discussed below.
Introduce
SampleAttrProducer
interfaceThis allows agent implementations to add custom sample attributes without maintaining a fork of the reporter implementation. It can gather extra meta-data when the trace is initially added and then emit extra attributes when the sample is sent out.