-
Notifications
You must be signed in to change notification settings - Fork 26
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
Improve attribute handling #346
Conversation
Can you also specify in PR description that this will fix elastic/apm-server#13703 ? |
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 general direction looks great. Thanks for refactoring it. The code is much cleaner and easier to understand now.
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
c1b91d3
to
f2767ab
Compare
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, thanks for refactoring. Modifying the existing tests to cover the new behavior is great.
Fix elastic/apm-server#13703, with some refactoring of the conversion between OTLP attributes and APMEvent labels.
Context
From my understanding looking at https://opentelemetry.io/docs/specs/otel/common/#attribute, the element values of an array attribute has to:
string
,int64
,bool
, andfloat64
It can be deduced that nested arrays are not allowed, since if this would be the case, the spec would have to also allow pointers, or a struct type to be included as a primitive. Effectively, creating an array reference. An array as value would not suffice, since its not atomic in principle. Rather, a collection, therefore breaking the homogeneous invariant. So I highly doubt that Attribute array value are allowed to be nested.
From a practical point of view, the concept of an attribute is not hierarchical. So nesting doesn't really makes sense. Spans and traces can be nested. Attributes cannot.
Problem
I've come to believe the reason for the bug in elastic/apm-server#13703 is more fundamental to the way we convert between OTLP attributes and APMEvent labels, than simply dropping heterogeneous elements.
The func
ifaceAttributeValue
acts as an interface between conversion of apcommon.Value
and a Go primitive. However, this is done by using theinterface
construct in Go as an abstract buffer for type conversion.This technique, though valid, in practice tends to force a developer's hand to introduce templating, as we see in the
pSliceToType
function. Which is a slippery slope into metaprogramming hell. This is a deadly trap in C++, and is why I'm personally not a big proponent of templates in Go.The bigger problem with introducing
interface
as a buffer, is that at some point, we have to do the actual conversion fromany
(akainterface
) to the real, concrete Go primitives. To my limited knowledge, this is what I understand the purpose ofsetLabel
to be; a producer of Go primitives when the exact translation is not made explicit. Therefore,setLabel
is mostly called in thedefault
section or theswitch
statements in translation methods, liketranslateResourceMetadata
, etc.The problem with this is multifold:
interface
. For example, the concept of abool
in lost afterifaceAttributeValue
is called.ifaceAttributeValue
is called recursively to ensure that all array elements are properly converted. This recursive call is needed if arrays can be nested, which I don't think they can. So you are left with unnecessary stack calls.interface
, templating, more functions than needed, and difficulty debugging.Solution
Do the conversion between
pcommon.Value
and Go primitives directly (by only callingsetLabel
). Do not useinterface
or templating. Ignore a recursive solution. We are not working with a Tree or Graph data structure. Simply, a linear homogeneous array.