func()

in collector/export/metric_otlp.go [179:263]


func (c *PromToOtlpExporter) promToOtlpRequest(wr *prompb.WriteRequest) ([]byte, int64, error) {
	scopeMetrics := &metricsv1.ScopeMetrics{
		// TODO - assume we filter most or keep most?
		Metrics: make([]*metricsv1.Metric, 0, len(wr.Timeseries)),
	}
	exportRequest := &v1.ExportMetricsServiceRequest{
		ResourceMetrics: []*metricsv1.ResourceMetrics{
			{
				Resource: &resourcev1.Resource{
					Attributes: c.resourceAttributes,
				},
				ScopeMetrics: []*metricsv1.ScopeMetrics{
					scopeMetrics,
				},
			},
		},
	}

	count := int64(0)
	for _, ts := range wr.Timeseries {
		nameBytes := prompb.MetricName(ts)
		if c.transformer.ShouldDropMetric(ts, nameBytes) {
			continue
		}
		count++

		gauge := &metricsv1.Gauge{
			DataPoints: make([]*metricsv1.NumberDataPoint, 0, len(ts.Samples)),
		}
		metric := &metricsv1.Metric{
			Data: &metricsv1.Metric_Gauge{
				Gauge: gauge,
			},
		}

		attributes := make([]*commonv1.KeyValue, 0, len(ts.Labels))
		c.transformer.WalkLabels(ts, func(k, v []byte) {
			// skip adding the name label and any adxmon_ prefixed labels
			if bytes.Equal(k, nameLabel) || bytes.HasPrefix(k, []byte("adxmon_")) {
				return
			}
			attribute := c.stringKVPool.Get(0).(*commonv1.KeyValue)
			// Explicitly set all fields to reset, but also to avoid allocations for the value
			attribute.Key = string(k)
			// only accept stringval here to avoid allocations
			stringval := attribute.Value.Value.(*commonv1.AnyValue_StringValue)
			stringval.StringValue = string(v)
			attributes = append(attributes, attribute)
		})
		metric.Name = string(nameBytes)

		for _, sample := range ts.Samples {
			datapoint := c.datapointPool.Get(0).(*metricsv1.NumberDataPoint)
			// Explicitly set all fields to reset, but also to avoid allocations for the value
			datapoint.Attributes = attributes
			datapoint.TimeUnixNano = uint64(sample.Timestamp * 1000000) // milliseconds to nanoseconds
			datapoint.StartTimeUnixNano = 0
			datapoint.Exemplars = nil
			datapoint.Flags = 0
			// only accept doubleval here to avoid allocations
			doubleVal := datapoint.Value.(*metricsv1.NumberDataPoint_AsDouble)
			doubleVal.AsDouble = sample.Value
			gauge.DataPoints = append(gauge.DataPoints, datapoint)
		}

		scopeMetrics.Metrics = append(scopeMetrics.Metrics, metric)
	}

	serialized, err := proto.Marshal(exportRequest)

	for _, scopeMetric := range scopeMetrics.Metrics {
		for idx, datapoint := range scopeMetric.GetGauge().GetDataPoints() {
			if idx == 0 {
				// shared attribute with all datapoints under metric
				for _, attribute := range datapoint.Attributes {
					c.stringKVPool.Put(attribute)
				}
			}

			c.datapointPool.Put(datapoint)
		}
	}

	return serialized, count, err
}