opentelemetry-collector/exporter/prometheusremotewriteexporter/testutil_test.go

459 lines
15 KiB
Go

// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package prometheusremotewriteexporter
import (
"fmt"
"time"
"github.com/prometheus/prometheus/prompb"
"go.opentelemetry.io/collector/model/pdata"
)
var (
time1 = uint64(time.Now().UnixNano())
time2 = uint64(time.Now().UnixNano() - 5)
time3 = uint64(time.Date(1970, 1, 0, 0, 0, 0, 0, time.UTC).UnixNano())
msTime1 = int64(time1 / uint64(int64(time.Millisecond)/int64(time.Nanosecond)))
msTime2 = int64(time2 / uint64(int64(time.Millisecond)/int64(time.Nanosecond)))
msTime3 = int64(time3 / uint64(int64(time.Millisecond)/int64(time.Nanosecond)))
label11 = "test_label11"
value11 = "test_value11"
label12 = "test_label12"
value12 = "test_value12"
label21 = "test_label21"
value21 = "test_value21"
label22 = "test_label22"
value22 = "test_value22"
label31 = "test_label31"
value31 = "test_value31"
label32 = "test_label32"
value32 = "test_value32"
label41 = "__test_label41__"
value41 = "test_value41"
dirty1 = "%"
dirty2 = "?"
intVal1 int64 = 1
intVal2 int64 = 2
floatVal1 = 1.0
floatVal2 = 2.0
floatVal3 = 3.0
lbs1 = getLabels(label11, value11, label12, value12)
lbs2 = getLabels(label21, value21, label22, value22)
lbs1Dirty = getLabels(label11+dirty1, value11, dirty2+label12, value12)
exlbs1 = map[string]string{label41: value41}
exlbs2 = map[string]string{label11: value41}
promLbs1 = getPromLabels(label11, value11, label12, value12)
promLbs2 = getPromLabels(label21, value21, label22, value22)
lb1Sig = "-" + label11 + "-" + value11 + "-" + label12 + "-" + value12
lb2Sig = "-" + label21 + "-" + value21 + "-" + label22 + "-" + value22
ns1 = "test_ns"
twoPointsSameTs = map[string]*prompb.TimeSeries{
"DoubleGauge" + "-" + label11 + "-" + value11 + "-" + label12 + "-" + value12: getTimeSeries(getPromLabels(label11, value11, label12, value12),
getSample(float64(intVal1), msTime1),
getSample(float64(intVal2), msTime2)),
}
twoPointsDifferentTs = map[string]*prompb.TimeSeries{
"IntGauge" + "-" + label11 + "-" + value11 + "-" + label12 + "-" + value12: getTimeSeries(getPromLabels(label11, value11, label12, value12),
getSample(float64(intVal1), msTime1)),
"IntGauge" + "-" + label21 + "-" + value21 + "-" + label22 + "-" + value22: getTimeSeries(getPromLabels(label21, value21, label22, value22),
getSample(float64(intVal1), msTime2)),
}
bounds = []float64{0.1, 0.5, 0.99}
buckets = []uint64{1, 2, 3}
quantileBounds = []float64{0.15, 0.9, 0.99}
quantileValues = []float64{7, 8, 9}
quantiles = getQuantiles(quantileBounds, quantileValues)
validIntGauge = "valid_IntGauge"
validDoubleGauge = "valid_DoubleGauge"
validIntSum = "valid_IntSum"
validSum = "valid_Sum"
validIntHistogram = "valid_IntHistogram"
validHistogram = "valid_Histogram"
validSummary = "valid_Summary"
suffixedCounter = "valid_IntSum_total"
validIntGaugeDirty = "*valid_IntGauge$"
unmatchedBoundBucketIntHist = "unmatchedBoundBucketIntHist"
unmatchedBoundBucketHist = "unmatchedBoundBucketHist"
// valid metrics as input should not return error
validMetrics1 = map[string]pdata.Metric{
validIntGauge: getIntGaugeMetric(validIntGauge, lbs1, intVal1, time1),
validDoubleGauge: getDoubleGaugeMetric(validDoubleGauge, lbs1, floatVal1, time1),
validIntSum: getIntSumMetric(validIntSum, lbs1, intVal1, time1),
suffixedCounter: getIntSumMetric(suffixedCounter, lbs1, intVal1, time1),
validSum: getSumMetric(validSum, lbs1, floatVal1, time1),
validIntHistogram: getIntHistogramMetric(validIntHistogram, lbs1, time1, floatVal1, uint64(intVal1), bounds, buckets),
validHistogram: getHistogramMetric(validHistogram, lbs1, time1, floatVal1, uint64(intVal1), bounds, buckets),
validSummary: getSummaryMetric(validSummary, lbs1, time1, floatVal1, uint64(intVal1), quantiles),
}
validMetrics2 = map[string]pdata.Metric{
validIntGauge: getIntGaugeMetric(validIntGauge, lbs2, intVal2, time2),
validDoubleGauge: getDoubleGaugeMetric(validDoubleGauge, lbs2, floatVal2, time2),
validIntSum: getIntSumMetric(validIntSum, lbs2, intVal2, time2),
validSum: getSumMetric(validSum, lbs2, floatVal2, time2),
validIntHistogram: getIntHistogramMetric(validIntHistogram, lbs2, time2, floatVal2, uint64(intVal2), bounds, buckets),
validHistogram: getHistogramMetric(validHistogram, lbs2, time2, floatVal2, uint64(intVal2), bounds, buckets),
validSummary: getSummaryMetric(validSummary, lbs2, time2, floatVal2, uint64(intVal2), quantiles),
validIntGaugeDirty: getIntGaugeMetric(validIntGaugeDirty, lbs1, intVal1, time1),
unmatchedBoundBucketIntHist: getIntHistogramMetric(unmatchedBoundBucketIntHist, pdata.NewStringMap(), 0, 0, 0, []float64{0.1, 0.2, 0.3}, []uint64{1, 2}),
unmatchedBoundBucketHist: getHistogramMetric(unmatchedBoundBucketHist, pdata.NewStringMap(), 0, 0, 0, []float64{0.1, 0.2, 0.3}, []uint64{1, 2}),
}
empty = "empty"
// Category 1: type and data field doesn't match
emptyIntGauge = "emptyIntGauge"
emptyDoubleGauge = "emptyDoubleGauge"
emptyIntSum = "emptyIntSum"
emptySum = "emptySum"
emptyIntHistogram = "emptyIntHistogram"
emptyHistogram = "emptyHistogram"
emptySummary = "emptySummary"
// Category 2: invalid type and temporality combination
emptyCumulativeIntSum = "emptyCumulativeIntSum"
emptyCumulativeSum = "emptyCumulativeSum"
emptyCumulativeIntHistogram = "emptyCumulativeIntHistogram"
emptyCumulativeHistogram = "emptyCumulativeHistogram"
// different metrics that will not pass validate metrics and will cause the exporter to return an error
invalidMetrics = map[string]pdata.Metric{
empty: pdata.NewMetric(),
emptyIntGauge: getEmptyIntGaugeMetric(emptyIntGauge),
emptyDoubleGauge: getEmptyDoubleGaugeMetric(emptyDoubleGauge),
emptyIntSum: getEmptyIntSumMetric(emptyIntSum),
emptySum: getEmptySumMetric(emptySum),
emptyIntHistogram: getEmptyIntHistogramMetric(emptyIntHistogram),
emptyHistogram: getEmptyHistogramMetric(emptyHistogram),
emptySummary: getEmptySummaryMetric(emptySummary),
emptyCumulativeIntSum: getEmptyCumulativeIntSumMetric(emptyCumulativeIntSum),
emptyCumulativeSum: getEmptyCumulativeSumMetric(emptyCumulativeSum),
emptyCumulativeIntHistogram: getEmptyCumulativeIntHistogramMetric(emptyCumulativeIntHistogram),
emptyCumulativeHistogram: getEmptyCumulativeHistogramMetric(emptyCumulativeHistogram),
}
)
// OTLP metrics
// labels must come in pairs
func getLabels(labels ...string) pdata.StringMap {
stringMap := pdata.NewStringMap()
for i := 0; i < len(labels); i += 2 {
stringMap.Upsert(labels[i], labels[i+1])
}
return stringMap
}
// Prometheus TimeSeries
func getPromLabels(lbs ...string) []prompb.Label {
pbLbs := prompb.Labels{
Labels: []prompb.Label{},
}
for i := 0; i < len(lbs); i += 2 {
pbLbs.Labels = append(pbLbs.Labels, getLabel(lbs[i], lbs[i+1]))
}
return pbLbs.Labels
}
func getLabel(name string, value string) prompb.Label {
return prompb.Label{
Name: name,
Value: value,
}
}
func getSample(v float64, t int64) prompb.Sample {
return prompb.Sample{
Value: v,
Timestamp: t,
}
}
func getTimeSeries(labels []prompb.Label, samples ...prompb.Sample) *prompb.TimeSeries {
return &prompb.TimeSeries{
Labels: labels,
Samples: samples,
}
}
func getQuantiles(bounds []float64, values []float64) pdata.ValueAtQuantileSlice {
quantiles := pdata.NewValueAtQuantileSlice()
quantiles.Resize(len(bounds))
for i := 0; i < len(bounds); i++ {
quantile := quantiles.At(i)
quantile.SetQuantile(bounds[i])
quantile.SetValue(values[i])
}
return quantiles
}
func getTimeseriesMap(timeseries []*prompb.TimeSeries) map[string]*prompb.TimeSeries {
tsMap := make(map[string]*prompb.TimeSeries)
for i, v := range timeseries {
tsMap[fmt.Sprintf("%s%d", "timeseries_name", i)] = v
}
return tsMap
}
func getEmptyIntGaugeMetric(name string) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeIntGauge)
return metric
}
func getIntGaugeMetric(name string, labels pdata.StringMap, value int64, ts uint64) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeIntGauge)
dp := metric.IntGauge().DataPoints().AppendEmpty()
dp.SetValue(value)
labels.Range(func(k string, v string) bool {
dp.LabelsMap().Upsert(k, v)
return true
})
dp.SetStartTimestamp(pdata.Timestamp(0))
dp.SetTimestamp(pdata.Timestamp(ts))
return metric
}
func getEmptyDoubleGaugeMetric(name string) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeDoubleGauge)
return metric
}
func getDoubleGaugeMetric(name string, labels pdata.StringMap, value float64, ts uint64) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeDoubleGauge)
dp := metric.DoubleGauge().DataPoints().AppendEmpty()
dp.SetValue(value)
labels.Range(func(k string, v string) bool {
dp.LabelsMap().Upsert(k, v)
return true
})
dp.SetStartTimestamp(pdata.Timestamp(0))
dp.SetTimestamp(pdata.Timestamp(ts))
return metric
}
func getEmptyIntSumMetric(name string) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeIntSum)
return metric
}
func getEmptyCumulativeIntSumMetric(name string) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeIntSum)
metric.IntSum().SetAggregationTemporality(pdata.AggregationTemporalityCumulative)
return metric
}
func getIntSumMetric(name string, labels pdata.StringMap, value int64, ts uint64) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeIntSum)
metric.IntSum().SetAggregationTemporality(pdata.AggregationTemporalityCumulative)
dp := metric.IntSum().DataPoints().AppendEmpty()
dp.SetValue(value)
labels.Range(func(k string, v string) bool {
dp.LabelsMap().Upsert(k, v)
return true
})
dp.SetStartTimestamp(pdata.Timestamp(0))
dp.SetTimestamp(pdata.Timestamp(ts))
return metric
}
func getEmptySumMetric(name string) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeSum)
return metric
}
func getEmptyCumulativeSumMetric(name string) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeSum)
metric.Sum().SetAggregationTemporality(pdata.AggregationTemporalityCumulative)
return metric
}
func getSumMetric(name string, labels pdata.StringMap, value float64, ts uint64) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeSum)
metric.Sum().SetAggregationTemporality(pdata.AggregationTemporalityCumulative)
dp := metric.Sum().DataPoints().AppendEmpty()
dp.SetValue(value)
labels.Range(func(k string, v string) bool {
dp.LabelsMap().Upsert(k, v)
return true
})
dp.SetStartTimestamp(pdata.Timestamp(0))
dp.SetTimestamp(pdata.Timestamp(ts))
return metric
}
func getEmptyIntHistogramMetric(name string) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeIntHistogram)
return metric
}
func getEmptyCumulativeIntHistogramMetric(name string) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeIntHistogram)
metric.IntHistogram().SetAggregationTemporality(pdata.AggregationTemporalityCumulative)
return metric
}
func getIntHistogramMetric(name string, labels pdata.StringMap, ts uint64, sum float64, count uint64, bounds []float64, buckets []uint64) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeIntHistogram)
metric.IntHistogram().SetAggregationTemporality(pdata.AggregationTemporalityCumulative)
dp := metric.IntHistogram().DataPoints().AppendEmpty()
dp.SetCount(count)
dp.SetSum(int64(sum))
dp.SetBucketCounts(buckets)
dp.SetExplicitBounds(bounds)
labels.Range(func(k string, v string) bool {
dp.LabelsMap().Upsert(k, v)
return true
})
dp.SetStartTimestamp(pdata.Timestamp(0))
dp.SetTimestamp(pdata.Timestamp(ts))
return metric
}
func getEmptyHistogramMetric(name string) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeHistogram)
return metric
}
func getEmptyCumulativeHistogramMetric(name string) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeHistogram)
metric.Histogram().SetAggregationTemporality(pdata.AggregationTemporalityCumulative)
return metric
}
func getHistogramMetric(name string, labels pdata.StringMap, ts uint64, sum float64, count uint64, bounds []float64, buckets []uint64) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeHistogram)
metric.Histogram().SetAggregationTemporality(pdata.AggregationTemporalityCumulative)
dp := metric.Histogram().DataPoints().AppendEmpty()
dp.SetCount(count)
dp.SetSum(sum)
dp.SetBucketCounts(buckets)
dp.SetExplicitBounds(bounds)
labels.Range(func(k string, v string) bool {
dp.LabelsMap().Upsert(k, v)
return true
})
dp.SetTimestamp(pdata.Timestamp(ts))
return metric
}
func getEmptySummaryMetric(name string) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeSummary)
return metric
}
func getSummaryMetric(name string, labels pdata.StringMap, ts uint64, sum float64, count uint64, quantiles pdata.ValueAtQuantileSlice) pdata.Metric {
metric := pdata.NewMetric()
metric.SetName(name)
metric.SetDataType(pdata.MetricDataTypeSummary)
dp := metric.Summary().DataPoints().AppendEmpty()
dp.SetCount(count)
dp.SetSum(sum)
labels.Range(func(k string, v string) bool {
dp.LabelsMap().Upsert(k, v)
return true
})
dp.SetTimestamp(pdata.Timestamp(ts))
quantiles.CopyTo(dp.QuantileValues())
quantiles.At(0).Quantile()
return metric
}
func getResource(resources ...string) pdata.Resource {
resource := pdata.NewResource()
for i := 0; i < len(resources); i += 2 {
resource.Attributes().Upsert(resources[i], pdata.NewAttributeValueString(resources[i+1]))
}
return resource
}
func getMetricsFromMetricList(metricList ...pdata.Metric) pdata.Metrics {
metrics := pdata.NewMetrics()
rm := metrics.ResourceMetrics().AppendEmpty()
ilm := rm.InstrumentationLibraryMetrics().AppendEmpty()
ilm.Metrics().Resize(len(metricList))
for i := 0; i < len(metricList); i++ {
metricList[i].CopyTo(ilm.Metrics().At(i))
}
return metrics
}