-
Notifications
You must be signed in to change notification settings - Fork 28
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
Drop invalid array elements in OTLP payload #342
Conversation
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 implementation in this PR will essentially leave the array element corresponding to invalid element as zero value (i.e. "" or 0.0). I'd prefer actually dropping the element such that the resulting array is smaller, but I don't have a strong opinion as long as we avoid the panic.
I'm fine with not propagating an error / logging, as this is such an edge case on invalid input that is not spec-compliant.
There is no need to use reflect imo.
I believe this is not possible to craft a problematic payload with Go otel sdk. But we can add unit test for setLabel function in this instance, although we don't usually unit test every unexported function. |
@carsonip I'll skip the unit test, since I'll have to change |
05b775c
to
d03a251
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.
Found a way to reproduce/test this in Go, not sure how I missed this the last time I tried.
func TestTranslateSpan(t *testing.T) {
m := pcommon.NewMap()
s := m.PutEmptySlice("f")
s.FromRaw([]any{"f", 1})
e := &modelpb.APMEvent{}
otlp.TranslateSpan(ptrace.SpanKindInternal, m, e)
}
Can you add a test based on this?
input/otlp/metadata.go
Outdated
// Ensure that the array is homogeneous | ||
// Drop value that is not OTEL supported: https://opentelemetry.io/docs/specs/otel/common/ | ||
if r, ok := v[i].(string); ok { | ||
value[i] = r | ||
} | ||
} | ||
modelpb.Labels(event.Labels).SetSlice(key, value) | ||
case float64: | ||
value := make([]float64, len(v)) | ||
for i := range v { | ||
value[i] = v[i].(float64) | ||
// Ensure that the array is homogeneous | ||
// Drop value that is not OTEL supported: https://opentelemetry.io/docs/specs/otel/common/ | ||
if r, ok := v[i].(float64); ok { | ||
value[i] = r | ||
} |
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 we add a test please?
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.
thanks for adding the test
|
||
testCases := []struct { | ||
desc string | ||
input []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.
input []any | |
input func() pcommon.Map |
Would it be possible to consolidate TestTranslateSpanValue into this test by having input as a function that returns a map?
testCases := []struct { | ||
desc string | ||
input []any | ||
expected int |
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.
Better to assert both expected label value and expected numeric label value instead of just checking the length. There will be minimal increase to the line of code, but it will provide real value in checking if the elements are really correct. Also, if the test really fails, the assertion output will be less useful when it just compares length.
assert.Equal(t, float64(1), e.GetNumericLabels()["f"].Value) | ||
} | ||
|
||
func TestTranslateSpanSlice(t *testing.T) { |
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.
If I look at this test without the context that this actually tests setLabel
, I'd wonder why we test TranslateSpan
only, but not TranslateTransaction
. I think it makes sense to add a dimension to this table driven test so that it tests both TranslateSpan
and TranslateTransaction
. Span events also use setLabel
, but convertSpanEvent
is slightly complex, so I'm fine with leaving that out unless others feel strongly about it.
Superseded by #346 |
Fixes elastic/apm-server#13703
Context
The issue occurs due to an invalid OTLP payload. Specifically, an array containing heterogeneous elements.
APM Server Setup
apm-data
changes to yourapm-server
package:apm-server
instanceExample Setup
A Python example had to be used, since the OpenTelemetry Go SDK does not natively support heterogeneous arrays.
changes.diff
opentelemetry-exporter-otlp*
packages locally fromopentelemetry-python/exporter
folder. For example,Notes
reflect
, but please comment if you think usingreflect
will be better and why.