in otelcollector/prometheusreceiver/internal/metricfamily.go [159:233]
func (mg *metricGroup) toExponentialHistogramDataPoints(dest pmetric.ExponentialHistogramDataPointSlice) {
if !mg.hasCount {
return
}
point := dest.AppendEmpty()
point.SetTimestamp(timestampFromMs(mg.ts))
// We do not set Min or Max as native histograms don't have that information.
switch {
case mg.fhValue != nil:
fh := mg.fhValue
if value.IsStaleNaN(fh.Sum) {
point.SetFlags(pmetric.DefaultDataPointFlags.WithNoRecordedValue(true))
// The count and sum are initialized to 0, so we don't need to set them.
} else {
point.SetScale(fh.Schema)
// Input is a float native histogram. This conversion will lose
// precision,but we don't actually expect float histograms in scrape,
// since these are typically the result of operations on integer
// native histograms in the database.
point.SetCount(uint64(fh.Count))
point.SetSum(fh.Sum)
point.SetZeroThreshold(fh.ZeroThreshold)
point.SetZeroCount(uint64(fh.ZeroCount))
if len(fh.PositiveSpans) > 0 {
point.Positive().SetOffset(fh.PositiveSpans[0].Offset - 1) // -1 because OTEL offset are for the lower bound, not the upper bound
convertAbsoluteBuckets(fh.PositiveSpans, fh.PositiveBuckets, point.Positive().BucketCounts())
}
if len(fh.NegativeSpans) > 0 {
point.Negative().SetOffset(fh.NegativeSpans[0].Offset - 1) // -1 because OTEL offset are for the lower bound, not the upper bound
convertAbsoluteBuckets(fh.NegativeSpans, fh.NegativeBuckets, point.Negative().BucketCounts())
}
}
case mg.hValue != nil:
h := mg.hValue
if value.IsStaleNaN(h.Sum) {
point.SetFlags(pmetric.DefaultDataPointFlags.WithNoRecordedValue(true))
// The count and sum are initialized to 0, so we don't need to set them.
} else {
point.SetScale(h.Schema)
point.SetCount(h.Count)
point.SetSum(h.Sum)
point.SetZeroThreshold(h.ZeroThreshold)
point.SetZeroCount(h.ZeroCount)
if len(h.PositiveSpans) > 0 {
point.Positive().SetOffset(h.PositiveSpans[0].Offset - 1) // -1 because OTEL offset are for the lower bound, not the upper bound
convertDeltaBuckets(h.PositiveSpans, h.PositiveBuckets, point.Positive().BucketCounts())
}
if len(h.NegativeSpans) > 0 {
point.Negative().SetOffset(h.NegativeSpans[0].Offset - 1) // -1 because OTEL offset are for the lower bound, not the upper bound
convertDeltaBuckets(h.NegativeSpans, h.NegativeBuckets, point.Negative().BucketCounts())
}
}
default:
// This should never happen.
return
}
tsNanos := timestampFromMs(mg.ts)
if mg.created != 0 {
point.SetStartTimestamp(timestampFromFloat64(mg.created))
} else if !removeStartTimeAdjustment.IsEnabled() {
// metrics_adjuster adjusts the startTimestamp to the initial scrape timestamp
point.SetStartTimestamp(tsNanos)
}
point.SetTimestamp(tsNanos)
populateAttributes(pmetric.MetricTypeHistogram, mg.ls, point.Attributes())
mg.setExemplars(point.Exemplars())
}