-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
Describe the bug
Related to open-telemetry/opentelemetry-collector-contrib#31289
I believe there is a bug in Metadata.Get when accessed by multiple threads.
If the Metadata struct is added to a context that is then shared between multiple exporters and those exporters attempt a Get at the same time the collector will panic with fatal error: concurrent map writes.
We are seeing this happen right now with the headerssetterextension. The extension is telling the exporters to grab details out of the context, but it is the same context used between all the exporters in the pipeline.
Code that I suspect is not thread safe:
opentelemetry-collector/client/client.go
Lines 150 to 171 in 59b45a5
| func (m Metadata) Get(key string) []string { | |
| vals := m.data[key] | |
| if len(vals) == 0 { | |
| // we didn't find the key, but perhaps it just has different cases? | |
| for k, v := range m.data { | |
| if strings.EqualFold(key, k) { | |
| vals = v | |
| // we optimize for the next lookup | |
| m.data[key] = v | |
| } | |
| } | |
| // if it's still not found, it's really not here | |
| if len(vals) == 0 { | |
| return nil | |
| } | |
| } | |
| ret := make([]string, len(vals)) | |
| copy(ret, vals) | |
| return ret |
Steps to reproduce
- Setup a collector to receive OTLP metrics
- Configure a headerssetter extension to extract a value from the context.
- Use the headerssetter extension as auth to multiple exporters (the more exporters, the faster you get crashes)
- Send data through the pipeline for several minutes.
- Watch for the collector to crash
What did you expect to see?
No crashes, multiple exporters could extract from the same context
What did you see instead?
Panic with fatal error: concurrent map writes
What version did you use?
Latest