Skip to content

Commit fb0278f

Browse files
committed
Currently while generating metrics out of traces, the start timestamp of a metric is currently tied to the root span. When a "new" child span appears for trace (eg : unhappy path on an api call which results in a new subspan or an async process that was triggered much later), the time starttimestamp for the new metric for the new child span is that of the parent span(which can be well in the past).
This MR moves the start timestamp from resource level (root span) to metric level(child span) . (Doesn't consider delta-temporality as of now). References: open-telemetry#35994 Upstream Fix: open-telemetry#36019
1 parent 3a3b701 commit fb0278f

File tree

2 files changed

+32
-39
lines changed

2 files changed

+32
-39
lines changed

connector/spanmetricsconnector/connector.go

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -283,35 +283,25 @@ func (p *connectorImp) buildMetrics() pmetric.Metrics {
283283
* - For delta metrics: (T1, T2), (T2, T3), (T3, T4) ...
284284
*/
285285
deltaMetricKeys := make(map[metrics.Key]bool)
286-
startTimeGenerator := func(mk metrics.Key) pcommon.Timestamp {
287-
startTime := rawMetrics.startTimestamp
288-
if p.config.GetAggregationTemporality() == pmetric.AggregationTemporalityDelta {
289-
if lastTimestamp, ok := p.lastDeltaTimestamps.Get(mk); ok {
290-
startTime = lastTimestamp
291-
}
292-
// Collect lastDeltaTimestamps keys that need to be updated. Metrics can share the same key, so defer the update.
293-
deltaMetricKeys[mk] = true
294-
}
295-
return startTime
296-
}
297286

298287
sums := rawMetrics.sums
299288
metric := sm.Metrics().AppendEmpty()
300289
metric.SetName(buildMetricName(p.config.Namespace, metricNameCalls))
301-
sums.BuildMetrics(metric, startTimeGenerator, timestamp, p.config.GetAggregationTemporality())
290+
sums.BuildMetrics(metric, timestamp, p.config.GetAggregationTemporality())
291+
302292
if !p.config.Histogram.Disable {
303293
histograms := rawMetrics.histograms
304294
metric = sm.Metrics().AppendEmpty()
305295
metric.SetName(buildMetricName(p.config.Namespace, metricNameDuration))
306296
metric.SetUnit(p.config.Histogram.Unit.String())
307-
histograms.BuildMetrics(metric, startTimeGenerator, timestamp, p.config.GetAggregationTemporality())
297+
histograms.BuildMetrics(metric, timestamp, p.config.GetAggregationTemporality())
308298
}
309299

310300
events := rawMetrics.events
311301
if p.events.Enabled {
312302
metric = sm.Metrics().AppendEmpty()
313303
metric.SetName(buildMetricName(p.config.Namespace, metricNameEvents))
314-
events.BuildMetrics(metric, startTimeGenerator, timestamp, p.config.GetAggregationTemporality())
304+
events.BuildMetrics(metric, timestamp, p.config.GetAggregationTemporality())
315305
}
316306

317307
for mk := range deltaMetricKeys {
@@ -405,13 +395,13 @@ func (p *connectorImp) aggregateMetrics(traces ptrace.Traces) {
405395
}
406396
if !p.config.Histogram.Disable {
407397
// aggregate histogram metrics
408-
h := histograms.GetOrCreate(key, attributes)
398+
h := histograms.GetOrCreate(key, attributes, startTimestamp)
409399
p.addExemplar(span, duration, h)
410400
h.Observe(duration)
411401

412402
}
413403
// aggregate sums metrics
414-
s := sums.GetOrCreate(key, attributes)
404+
s := sums.GetOrCreate(key, attributes, startTimestamp)
415405
if p.config.Exemplars.Enabled && !span.TraceID().IsEmpty() {
416406
s.AddExemplar(span.TraceID(), span.SpanID(), duration)
417407
}
@@ -435,7 +425,7 @@ func (p *connectorImp) aggregateMetrics(traces ptrace.Traces) {
435425
eAttributes = p.buildAttributes(serviceName, span, rscAndEventAttrs, eDimensions)
436426
p.metricKeyToDimensions.Add(eKey, eAttributes)
437427
}
438-
e := events.GetOrCreate(eKey, eAttributes)
428+
e := events.GetOrCreate(eKey, eAttributes, startTimestamp)
439429
if p.config.Exemplars.Enabled && !span.TraceID().IsEmpty() {
440430
e.AddExemplar(span.TraceID(), span.SpanID(), duration)
441431
}
@@ -479,8 +469,8 @@ func (p *connectorImp) getOrCreateResourceMetrics(attr pcommon.Map, startTimesta
479469
if !ok {
480470
v = &resourceMetrics{
481471
histograms: initHistogramMetrics(p.config),
482-
sums: metrics.NewSumMetrics(p.config.Exemplars.MaxPerDataPoint),
483-
events: metrics.NewSumMetrics(p.config.Exemplars.MaxPerDataPoint),
472+
sums: metrics.NewSumMetrics(p.config.Exemplars.MaxPerDataPoint, startTimestamp),
473+
events: metrics.NewSumMetrics(p.config.Exemplars.MaxPerDataPoint, startTimestamp),
484474
attributes: attr,
485475
startTimestamp: startTimestamp,
486476
}

connector/spanmetricsconnector/internal/metrics/metrics.go

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import (
1414
type Key string
1515

1616
type HistogramMetrics interface {
17-
GetOrCreate(key Key, attributes pcommon.Map) Histogram
18-
BuildMetrics(pmetric.Metric, generateStartTimestamp, pcommon.Timestamp, pmetric.AggregationTemporality)
17+
GetOrCreate(key Key, attributes pcommon.Map, startTimestamp pcommon.Timestamp) Histogram
18+
BuildMetrics(pmetric.Metric, pcommon.Timestamp, pmetric.AggregationTemporality)
1919
ClearExemplars()
2020
}
2121

@@ -47,6 +47,7 @@ type explicitHistogram struct {
4747
bounds []float64
4848

4949
maxExemplarCount *int
50+
startTimestamp pcommon.Timestamp
5051
}
5152

5253
type exponentialHistogram struct {
@@ -56,6 +57,7 @@ type exponentialHistogram struct {
5657
histogram *structure.Histogram[float64]
5758

5859
maxExemplarCount *int
60+
startTimestamp pcommon.Timestamp
5961
}
6062

6163
type generateStartTimestamp = func(Key) pcommon.Timestamp
@@ -76,7 +78,7 @@ func NewExplicitHistogramMetrics(bounds []float64, maxExemplarCount *int) Histog
7678
}
7779
}
7880

79-
func (m *explicitHistogramMetrics) GetOrCreate(key Key, attributes pcommon.Map) Histogram {
81+
func (m *explicitHistogramMetrics) GetOrCreate(key Key, attributes pcommon.Map, startTimestamp pcommon.Timestamp) Histogram {
8082
h, ok := m.metrics[key]
8183
if !ok {
8284
h = &explicitHistogram{
@@ -94,17 +96,16 @@ func (m *explicitHistogramMetrics) GetOrCreate(key Key, attributes pcommon.Map)
9496

9597
func (m *explicitHistogramMetrics) BuildMetrics(
9698
metric pmetric.Metric,
97-
startTimestamp generateStartTimestamp,
9899
timestamp pcommon.Timestamp,
99100
temporality pmetric.AggregationTemporality,
100101
) {
101102
metric.SetEmptyHistogram().SetAggregationTemporality(temporality)
102103
dps := metric.Histogram().DataPoints()
103104
dps.EnsureCapacity(len(m.metrics))
104-
for k, h := range m.metrics {
105+
for _, h := range m.metrics {
105106
dp := dps.AppendEmpty()
106-
dp.SetStartTimestamp(startTimestamp(k))
107107
dp.SetTimestamp(timestamp)
108+
dp.SetStartTimestamp(h.startTimestamp)
108109
dp.ExplicitBounds().FromRaw(h.bounds)
109110
dp.BucketCounts().FromRaw(h.bucketCounts)
110111
dp.SetCount(h.count)
@@ -114,6 +115,7 @@ func (m *explicitHistogramMetrics) BuildMetrics(
114115
}
115116
h.exemplars.CopyTo(dp.Exemplars())
116117
h.attributes.CopyTo(dp.Attributes())
118+
dp.Attributes().PutInt("startTimestamp", int64(h.startTimestamp))
117119
}
118120
}
119121

@@ -123,7 +125,7 @@ func (m *explicitHistogramMetrics) ClearExemplars() {
123125
}
124126
}
125127

126-
func (m *exponentialHistogramMetrics) GetOrCreate(key Key, attributes pcommon.Map) Histogram {
128+
func (m *exponentialHistogramMetrics) GetOrCreate(key Key, attributes pcommon.Map, startTimeStamp pcommon.Timestamp) Histogram {
127129
h, ok := m.metrics[key]
128130
if !ok {
129131
histogram := new(structure.Histogram[float64])
@@ -147,23 +149,23 @@ func (m *exponentialHistogramMetrics) GetOrCreate(key Key, attributes pcommon.Ma
147149

148150
func (m *exponentialHistogramMetrics) BuildMetrics(
149151
metric pmetric.Metric,
150-
startTimestamp generateStartTimestamp,
151152
timestamp pcommon.Timestamp,
152153
temporality pmetric.AggregationTemporality,
153154
) {
154155
metric.SetEmptyExponentialHistogram().SetAggregationTemporality(temporality)
155156
dps := metric.ExponentialHistogram().DataPoints()
156157
dps.EnsureCapacity(len(m.metrics))
157-
for k, m := range m.metrics {
158+
for _, e := range m.metrics {
158159
dp := dps.AppendEmpty()
159-
dp.SetStartTimestamp(startTimestamp(k))
160+
dp.SetStartTimestamp(e.startTimestamp)
160161
dp.SetTimestamp(timestamp)
161-
expoHistToExponentialDataPoint(m.histogram, dp)
162-
for i := 0; i < m.exemplars.Len(); i++ {
163-
m.exemplars.At(i).SetTimestamp(timestamp)
162+
expoHistToExponentialDataPoint(e.histogram, dp)
163+
for i := 0; i < e.exemplars.Len(); i++ {
164+
e.exemplars.At(i).SetTimestamp(timestamp)
164165
}
165-
m.exemplars.CopyTo(dp.Exemplars())
166-
m.attributes.CopyTo(dp.Attributes())
166+
e.exemplars.CopyTo(dp.Exemplars())
167+
e.attributes.CopyTo(dp.Attributes())
168+
dp.Attributes().PutInt("startTimestamp", int64(e.startTimestamp))
167169
}
168170
}
169171

@@ -242,13 +244,14 @@ type Sum struct {
242244
count uint64
243245
exemplars pmetric.ExemplarSlice
244246
maxExemplarCount *int
247+
startTimestamp pcommon.Timestamp
245248
}
246249

247250
func (s *Sum) Add(value uint64) {
248251
s.count += value
249252
}
250253

251-
func NewSumMetrics(maxExemplarCount *int) SumMetrics {
254+
func NewSumMetrics(maxExemplarCount *int, startTimeStamp pcommon.Timestamp) SumMetrics {
252255
return SumMetrics{
253256
metrics: make(map[Key]*Sum),
254257
maxExemplarCount: maxExemplarCount,
@@ -260,13 +263,14 @@ type SumMetrics struct {
260263
maxExemplarCount *int
261264
}
262265

263-
func (m *SumMetrics) GetOrCreate(key Key, attributes pcommon.Map) *Sum {
266+
func (m *SumMetrics) GetOrCreate(key Key, attributes pcommon.Map, startTimestamp pcommon.Timestamp) *Sum {
264267
s, ok := m.metrics[key]
265268
if !ok {
266269
s = &Sum{
267270
attributes: attributes,
268271
exemplars: pmetric.NewExemplarSlice(),
269272
maxExemplarCount: m.maxExemplarCount,
273+
startTimestamp: startTimestamp,
270274
}
271275
m.metrics[key] = s
272276
}
@@ -285,7 +289,6 @@ func (s *Sum) AddExemplar(traceID pcommon.TraceID, spanID pcommon.SpanID, value
285289

286290
func (m *SumMetrics) BuildMetrics(
287291
metric pmetric.Metric,
288-
startTimestamp generateStartTimestamp,
289292
timestamp pcommon.Timestamp,
290293
temporality pmetric.AggregationTemporality,
291294
) {
@@ -294,9 +297,9 @@ func (m *SumMetrics) BuildMetrics(
294297

295298
dps := metric.Sum().DataPoints()
296299
dps.EnsureCapacity(len(m.metrics))
297-
for k, s := range m.metrics {
300+
for _, s := range m.metrics {
298301
dp := dps.AppendEmpty()
299-
dp.SetStartTimestamp(startTimestamp(k))
302+
dp.SetStartTimestamp(s.startTimestamp)
300303
dp.SetTimestamp(timestamp)
301304
dp.SetIntValue(int64(s.count))
302305
for i := 0; i < s.exemplars.Len(); i++ {

0 commit comments

Comments
 (0)