@@ -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