func()

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())
}