@@ -5,6 +5,7 @@ package exemplar // import "go.opentelemetry.io/otel/sdk/metric/exemplar"
55
66import (
77 "context"
8+ "sync"
89 "time"
910
1011 "go.opentelemetry.io/otel/attribute"
@@ -24,8 +25,14 @@ func newStorage(n int) *storage {
2425 return & storage {measurements : make ([]measurement , n )}
2526}
2627
27- func (r * storage ) store (idx int , m measurement ) {
28- r .measurements [idx ] = m
28+ func (r * storage ) store (ctx context.Context , idx int , ts time.Time , v Value , droppedAttr []attribute.KeyValue ) {
29+ r .measurements [idx ].mux .Lock ()
30+ defer r .measurements [idx ].mux .Unlock ()
31+ r .measurements [idx ].FilteredAttributes = droppedAttr
32+ r .measurements [idx ].Time = ts
33+ r .measurements [idx ].Value = v
34+ r .measurements [idx ].Ctx = ctx
35+ r .measurements [idx ].valid = true
2936}
3037
3138// Collect returns all the held exemplars.
@@ -34,61 +41,57 @@ func (r *storage) store(idx int, m measurement) {
3441func (r * storage ) Collect (dest * []Exemplar ) {
3542 * dest = reset (* dest , len (r .measurements ), len (r .measurements ))
3643 var n int
37- for _ , m := range r .measurements {
38- if ! m . valid {
39- continue
44+ for i := range r .measurements {
45+ if r . measurements [ i ]. exemplar ( & ( * dest )[ n ]) {
46+ n ++
4047 }
41-
42- m .exemplar (& (* dest )[n ])
43- n ++
4448 }
4549 * dest = (* dest )[:n ]
4650}
4751
4852// measurement is a measurement made by a telemetry system.
4953type measurement struct {
54+ mux sync.Mutex
5055 // FilteredAttributes are the attributes dropped during the measurement.
5156 FilteredAttributes []attribute.KeyValue
5257 // Time is the time when the measurement was made.
5358 Time time.Time
5459 // Value is the value of the measurement.
5560 Value Value
56- // SpanContext is the SpanContext active when a measurement was made.
57- SpanContext trace. SpanContext
61+ // Ctx is the context active when a measurement was made.
62+ Ctx context. Context
5863
5964 valid bool
6065}
6166
62- // newMeasurement returns a new non-empty Measurement.
63- func newMeasurement (ctx context.Context , ts time.Time , v Value , droppedAttr []attribute.KeyValue ) measurement {
64- return measurement {
65- FilteredAttributes : droppedAttr ,
66- Time : ts ,
67- Value : v ,
68- SpanContext : trace .SpanContextFromContext (ctx ),
69- valid : true ,
67+ // exemplar returns m as an [Exemplar].
68+ // returns true if it populated the exemplar.
69+ func (m * measurement ) exemplar (dest * Exemplar ) bool {
70+ m .mux .Lock ()
71+ defer m .mux .Unlock ()
72+ if ! m .valid {
73+ return false
7074 }
71- }
7275
73- // exemplar returns m as an [Exemplar].
74- func (m measurement ) exemplar (dest * Exemplar ) {
7576 dest .FilteredAttributes = m .FilteredAttributes
7677 dest .Time = m .Time
7778 dest .Value = m .Value
7879
79- if m .SpanContext .HasTraceID () {
80- traceID := m .SpanContext .TraceID ()
80+ sc := trace .SpanContextFromContext (m .Ctx )
81+ if sc .HasTraceID () {
82+ traceID := sc .TraceID ()
8183 dest .TraceID = traceID [:]
8284 } else {
8385 dest .TraceID = dest .TraceID [:0 ]
8486 }
8587
86- if m . SpanContext .HasSpanID () {
87- spanID := m . SpanContext .SpanID ()
88+ if sc .HasSpanID () {
89+ spanID := sc .SpanID ()
8890 dest .SpanID = spanID [:]
8991 } else {
9092 dest .SpanID = dest .SpanID [:0 ]
9193 }
94+ return true
9295}
9396
9497func reset [T any ](s []T , length , capacity int ) []T {
0 commit comments