202 lines
6.6 KiB
Go
202 lines
6.6 KiB
Go
// Copyright 2024 Prometheus Team
|
|
// 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 prompb
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/prometheus/common/model"
|
|
|
|
"github.com/prometheus/prometheus/model/exemplar"
|
|
"github.com/prometheus/prometheus/model/histogram"
|
|
"github.com/prometheus/prometheus/model/labels"
|
|
)
|
|
|
|
// NOTE(bwplotka): This file's code is tested in /prompb/rwcommon.
|
|
|
|
// ToLabels return model labels.Labels from timeseries' remote labels.
|
|
func (m TimeSeries) ToLabels(b *labels.ScratchBuilder, _ []string) labels.Labels {
|
|
return labelProtosToLabels(b, m.GetLabels())
|
|
}
|
|
|
|
// ToLabels return model labels.Labels from timeseries' remote labels.
|
|
func (m ChunkedSeries) ToLabels(b *labels.ScratchBuilder, _ []string) labels.Labels {
|
|
return labelProtosToLabels(b, m.GetLabels())
|
|
}
|
|
|
|
func labelProtosToLabels(b *labels.ScratchBuilder, labelPairs []Label) labels.Labels {
|
|
b.Reset()
|
|
for _, l := range labelPairs {
|
|
b.Add(l.Name, l.Value)
|
|
}
|
|
b.Sort()
|
|
return b.Labels()
|
|
}
|
|
|
|
// FromLabels transforms labels into prompb labels. The buffer slice
|
|
// will be used to avoid allocations if it is big enough to store the labels.
|
|
func FromLabels(lbls labels.Labels, buf []Label) []Label {
|
|
result := buf[:0]
|
|
lbls.Range(func(l labels.Label) {
|
|
result = append(result, Label{
|
|
Name: l.Name,
|
|
Value: l.Value,
|
|
})
|
|
})
|
|
return result
|
|
}
|
|
|
|
// FromMetadataType transforms a Prometheus metricType into prompb metricType. Since the former is a string we need to transform it to an enum.
|
|
func FromMetadataType(t model.MetricType) MetricMetadata_MetricType {
|
|
mt := strings.ToUpper(string(t))
|
|
v, ok := MetricMetadata_MetricType_value[mt]
|
|
if !ok {
|
|
return MetricMetadata_UNKNOWN
|
|
}
|
|
return MetricMetadata_MetricType(v)
|
|
}
|
|
|
|
// IsFloatHistogram returns true if the histogram is float.
|
|
func (h Histogram) IsFloatHistogram() bool {
|
|
_, ok := h.GetCount().(*Histogram_CountFloat)
|
|
return ok
|
|
}
|
|
|
|
// ToIntHistogram returns integer Prometheus histogram from the remote implementation
|
|
// of integer histogram. If it's a float histogram, the method returns nil.
|
|
func (h Histogram) ToIntHistogram() *histogram.Histogram {
|
|
if h.IsFloatHistogram() {
|
|
return nil
|
|
}
|
|
return &histogram.Histogram{
|
|
CounterResetHint: histogram.CounterResetHint(h.ResetHint),
|
|
Schema: h.Schema,
|
|
ZeroThreshold: h.ZeroThreshold,
|
|
ZeroCount: h.GetZeroCountInt(),
|
|
Count: h.GetCountInt(),
|
|
Sum: h.Sum,
|
|
PositiveSpans: spansProtoToSpans(h.GetPositiveSpans()),
|
|
PositiveBuckets: h.GetPositiveDeltas(),
|
|
NegativeSpans: spansProtoToSpans(h.GetNegativeSpans()),
|
|
NegativeBuckets: h.GetNegativeDeltas(),
|
|
}
|
|
}
|
|
|
|
// ToFloatHistogram returns float Prometheus histogram from the remote implementation
|
|
// of float histogram. If the underlying implementation is an integer histogram, a
|
|
// conversion is performed.
|
|
func (h Histogram) ToFloatHistogram() *histogram.FloatHistogram {
|
|
if h.IsFloatHistogram() {
|
|
return &histogram.FloatHistogram{
|
|
CounterResetHint: histogram.CounterResetHint(h.ResetHint),
|
|
Schema: h.Schema,
|
|
ZeroThreshold: h.ZeroThreshold,
|
|
ZeroCount: h.GetZeroCountFloat(),
|
|
Count: h.GetCountFloat(),
|
|
Sum: h.Sum,
|
|
PositiveSpans: spansProtoToSpans(h.GetPositiveSpans()),
|
|
PositiveBuckets: h.GetPositiveCounts(),
|
|
NegativeSpans: spansProtoToSpans(h.GetNegativeSpans()),
|
|
NegativeBuckets: h.GetNegativeCounts(),
|
|
}
|
|
}
|
|
// Conversion from integer histogram.
|
|
return &histogram.FloatHistogram{
|
|
CounterResetHint: histogram.CounterResetHint(h.ResetHint),
|
|
Schema: h.Schema,
|
|
ZeroThreshold: h.ZeroThreshold,
|
|
ZeroCount: float64(h.GetZeroCountInt()),
|
|
Count: float64(h.GetCountInt()),
|
|
Sum: h.Sum,
|
|
PositiveSpans: spansProtoToSpans(h.GetPositiveSpans()),
|
|
PositiveBuckets: deltasToCounts(h.GetPositiveDeltas()),
|
|
NegativeSpans: spansProtoToSpans(h.GetNegativeSpans()),
|
|
NegativeBuckets: deltasToCounts(h.GetNegativeDeltas()),
|
|
}
|
|
}
|
|
|
|
func spansProtoToSpans(s []BucketSpan) []histogram.Span {
|
|
spans := make([]histogram.Span, len(s))
|
|
for i := 0; i < len(s); i++ {
|
|
spans[i] = histogram.Span{Offset: s[i].Offset, Length: s[i].Length}
|
|
}
|
|
|
|
return spans
|
|
}
|
|
|
|
func deltasToCounts(deltas []int64) []float64 {
|
|
counts := make([]float64, len(deltas))
|
|
var cur float64
|
|
for i, d := range deltas {
|
|
cur += float64(d)
|
|
counts[i] = cur
|
|
}
|
|
return counts
|
|
}
|
|
|
|
// FromIntHistogram returns remote Histogram from the integer Histogram.
|
|
func FromIntHistogram(timestamp int64, h *histogram.Histogram) Histogram {
|
|
return Histogram{
|
|
Count: &Histogram_CountInt{CountInt: h.Count},
|
|
Sum: h.Sum,
|
|
Schema: h.Schema,
|
|
ZeroThreshold: h.ZeroThreshold,
|
|
ZeroCount: &Histogram_ZeroCountInt{ZeroCountInt: h.ZeroCount},
|
|
NegativeSpans: spansToSpansProto(h.NegativeSpans),
|
|
NegativeDeltas: h.NegativeBuckets,
|
|
PositiveSpans: spansToSpansProto(h.PositiveSpans),
|
|
PositiveDeltas: h.PositiveBuckets,
|
|
ResetHint: Histogram_ResetHint(h.CounterResetHint),
|
|
Timestamp: timestamp,
|
|
}
|
|
}
|
|
|
|
// FromFloatHistogram returns remote Histogram from the float Histogram.
|
|
func FromFloatHistogram(timestamp int64, fh *histogram.FloatHistogram) Histogram {
|
|
return Histogram{
|
|
Count: &Histogram_CountFloat{CountFloat: fh.Count},
|
|
Sum: fh.Sum,
|
|
Schema: fh.Schema,
|
|
ZeroThreshold: fh.ZeroThreshold,
|
|
ZeroCount: &Histogram_ZeroCountFloat{ZeroCountFloat: fh.ZeroCount},
|
|
NegativeSpans: spansToSpansProto(fh.NegativeSpans),
|
|
NegativeCounts: fh.NegativeBuckets,
|
|
PositiveSpans: spansToSpansProto(fh.PositiveSpans),
|
|
PositiveCounts: fh.PositiveBuckets,
|
|
ResetHint: Histogram_ResetHint(fh.CounterResetHint),
|
|
Timestamp: timestamp,
|
|
}
|
|
}
|
|
|
|
func spansToSpansProto(s []histogram.Span) []BucketSpan {
|
|
spans := make([]BucketSpan, len(s))
|
|
for i := 0; i < len(s); i++ {
|
|
spans[i] = BucketSpan{Offset: s[i].Offset, Length: s[i].Length}
|
|
}
|
|
|
|
return spans
|
|
}
|
|
|
|
// ToExemplar converts remote exemplar to model exemplar.
|
|
func (m Exemplar) ToExemplar(b *labels.ScratchBuilder, _ []string) exemplar.Exemplar {
|
|
timestamp := m.Timestamp
|
|
|
|
return exemplar.Exemplar{
|
|
Labels: labelProtosToLabels(b, m.GetLabels()),
|
|
Value: m.Value,
|
|
Ts: timestamp,
|
|
HasTs: timestamp != 0,
|
|
}
|
|
}
|