2024-01-18 10:02:06 +00:00
|
|
|
// DO NOT EDIT. COPIED AS-IS. SEE ../README.md
|
2023-07-28 10:35:28 +00:00
|
|
|
|
|
|
|
// Copyright The OpenTelemetry Authors
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
|
|
|
package prometheusremotewrite // import "github.com/prometheus/prometheus/storage/remote/otlptranslator/prometheusremotewrite"
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/prometheus/prometheus/prompb"
|
|
|
|
"go.opentelemetry.io/collector/pdata/pcommon"
|
|
|
|
"go.opentelemetry.io/collector/pdata/pmetric"
|
|
|
|
"go.uber.org/multierr"
|
|
|
|
|
|
|
|
prometheustranslator "github.com/prometheus/prometheus/storage/remote/otlptranslator/prometheus"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Settings struct {
|
|
|
|
Namespace string
|
|
|
|
ExternalLabels map[string]string
|
|
|
|
DisableTargetInfo bool
|
|
|
|
ExportCreatedMetric bool
|
2023-11-15 14:09:15 +00:00
|
|
|
AddMetricSuffixes bool
|
2023-07-28 10:35:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// FromMetrics converts pmetric.Metrics to prometheus remote write format.
|
|
|
|
func FromMetrics(md pmetric.Metrics, settings Settings) (tsMap map[string]*prompb.TimeSeries, errs error) {
|
|
|
|
tsMap = make(map[string]*prompb.TimeSeries)
|
|
|
|
|
|
|
|
resourceMetricsSlice := md.ResourceMetrics()
|
|
|
|
for i := 0; i < resourceMetricsSlice.Len(); i++ {
|
|
|
|
resourceMetrics := resourceMetricsSlice.At(i)
|
|
|
|
resource := resourceMetrics.Resource()
|
|
|
|
scopeMetricsSlice := resourceMetrics.ScopeMetrics()
|
|
|
|
// keep track of the most recent timestamp in the ResourceMetrics for
|
|
|
|
// use with the "target" info metric
|
|
|
|
var mostRecentTimestamp pcommon.Timestamp
|
|
|
|
for j := 0; j < scopeMetricsSlice.Len(); j++ {
|
|
|
|
scopeMetrics := scopeMetricsSlice.At(j)
|
|
|
|
metricSlice := scopeMetrics.Metrics()
|
|
|
|
|
|
|
|
// TODO: decide if instrumentation library information should be exported as labels
|
|
|
|
for k := 0; k < metricSlice.Len(); k++ {
|
|
|
|
metric := metricSlice.At(k)
|
|
|
|
mostRecentTimestamp = maxTimestamp(mostRecentTimestamp, mostRecentTimestampInMetric(metric))
|
|
|
|
|
|
|
|
if !isValidAggregationTemporality(metric) {
|
|
|
|
errs = multierr.Append(errs, fmt.Errorf("invalid temporality and type combination for metric %q", metric.Name()))
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// handle individual metric based on type
|
2023-11-15 14:09:15 +00:00
|
|
|
//exhaustive:enforce
|
2023-07-28 10:35:28 +00:00
|
|
|
switch metric.Type() {
|
|
|
|
case pmetric.MetricTypeGauge:
|
|
|
|
dataPoints := metric.Gauge().DataPoints()
|
|
|
|
if dataPoints.Len() == 0 {
|
|
|
|
errs = multierr.Append(errs, fmt.Errorf("empty data points. %s is dropped", metric.Name()))
|
|
|
|
}
|
|
|
|
for x := 0; x < dataPoints.Len(); x++ {
|
|
|
|
addSingleGaugeNumberDataPoint(dataPoints.At(x), resource, metric, settings, tsMap)
|
|
|
|
}
|
|
|
|
case pmetric.MetricTypeSum:
|
|
|
|
dataPoints := metric.Sum().DataPoints()
|
|
|
|
if dataPoints.Len() == 0 {
|
|
|
|
errs = multierr.Append(errs, fmt.Errorf("empty data points. %s is dropped", metric.Name()))
|
|
|
|
}
|
|
|
|
for x := 0; x < dataPoints.Len(); x++ {
|
|
|
|
addSingleSumNumberDataPoint(dataPoints.At(x), resource, metric, settings, tsMap)
|
|
|
|
}
|
|
|
|
case pmetric.MetricTypeHistogram:
|
|
|
|
dataPoints := metric.Histogram().DataPoints()
|
|
|
|
if dataPoints.Len() == 0 {
|
|
|
|
errs = multierr.Append(errs, fmt.Errorf("empty data points. %s is dropped", metric.Name()))
|
|
|
|
}
|
|
|
|
for x := 0; x < dataPoints.Len(); x++ {
|
|
|
|
addSingleHistogramDataPoint(dataPoints.At(x), resource, metric, settings, tsMap)
|
|
|
|
}
|
|
|
|
case pmetric.MetricTypeExponentialHistogram:
|
|
|
|
dataPoints := metric.ExponentialHistogram().DataPoints()
|
|
|
|
if dataPoints.Len() == 0 {
|
|
|
|
errs = multierr.Append(errs, fmt.Errorf("empty data points. %s is dropped", metric.Name()))
|
|
|
|
}
|
2023-11-15 14:09:15 +00:00
|
|
|
name := prometheustranslator.BuildCompliantName(metric, settings.Namespace, settings.AddMetricSuffixes)
|
2023-07-28 10:35:28 +00:00
|
|
|
for x := 0; x < dataPoints.Len(); x++ {
|
|
|
|
errs = multierr.Append(
|
|
|
|
errs,
|
|
|
|
addSingleExponentialHistogramDataPoint(
|
|
|
|
name,
|
|
|
|
dataPoints.At(x),
|
|
|
|
resource,
|
|
|
|
settings,
|
|
|
|
tsMap,
|
|
|
|
),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
case pmetric.MetricTypeSummary:
|
|
|
|
dataPoints := metric.Summary().DataPoints()
|
|
|
|
if dataPoints.Len() == 0 {
|
|
|
|
errs = multierr.Append(errs, fmt.Errorf("empty data points. %s is dropped", metric.Name()))
|
|
|
|
}
|
|
|
|
for x := 0; x < dataPoints.Len(); x++ {
|
|
|
|
addSingleSummaryDataPoint(dataPoints.At(x), resource, metric, settings, tsMap)
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
errs = multierr.Append(errs, errors.New("unsupported metric type"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
addResourceTargetInfo(resource, settings, mostRecentTimestamp, tsMap)
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|