Skip to content

Commit

Permalink
Distinguish data labels instead of identifying ones
Browse files Browse the repository at this point in the history
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
  • Loading branch information
aknuds1 committed Feb 6, 2024
1 parent c7c6d7d commit a5028ca
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 134 deletions.
8 changes: 2 additions & 6 deletions model/labels/labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,12 +412,8 @@ func (b *ScratchBuilder) Reset() {

// Add a name/value pair.
// Note if you Add the same name twice you will get a duplicate label, which is invalid.
func (b *ScratchBuilder) Add(name, value string, identifyingLabels ...string) {
identifying := false
if len(identifyingLabels) > 0 && slices.Contains(identifyingLabels, name) {
identifying = true
}
b.add = append(b.add, Label{Name: name, Value: value, Identifying: identifying})
func (b *ScratchBuilder) Add(name, value string) {
b.add = append(b.add, Label{Name: name, Value: value})
}

// Add a name/value pair, using []byte instead of string.
Expand Down
8 changes: 0 additions & 8 deletions model/labels/labels_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package labels
import (
"bytes"
"encoding/json"
"fmt"
"strconv"

"github.com/prometheus/common/model"
Expand All @@ -37,13 +36,6 @@ var seps = []byte{'\xff'}
// Label is a key/value pair of strings.
type Label struct {
Name, Value string
// Identifying signifies whether this is an identifying label for an info metric.
Identifying bool
}

// String returns l's string representation.
func (l Label) String() string {
return fmt.Sprintf("%s=%s", l.Name, l.Value)
}

func (ls Labels) String() string {
Expand Down
8 changes: 2 additions & 6 deletions model/labels/labels_stringlabels.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,12 +620,8 @@ func (b *ScratchBuilder) Reset() {

// Add a name/value pair.
// Note if you Add the same name twice you will get a duplicate label, which is invalid.
func (b *ScratchBuilder) Add(name, value string, identifyingLabels ...string) {
identifying := false
if len(identifyingLabels) > 0 && slices.Contains(identifyingLabels, name) {
identifying = true
}
b.add = append(b.add, Label{Name: name, Value: value, Identifying: identifying})
func (b *ScratchBuilder) Add(name, value string) {
b.add = append(b.add, Label{Name: name, Value: value})
}

// Add a name/value pair, using []byte instead of string to reduce memory allocations.
Expand Down
2 changes: 1 addition & 1 deletion model/labels/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ func TestBuilder(t *testing.T) {
},
{
base: FromStrings("aaa", "111", "bbb", "222", "ccc", "333"),
set: []Label{{Name: "aaa", Value: "444"}, {Name: "bbb", Value: "555"}, {Name: "ccc", Value: "666"}},
set: []Label{{"aaa", "444"}, {"bbb", "555"}, {"ccc", "666"}},
want: FromStrings("aaa", "444", "bbb", "555", "ccc", "666"),
},
{
Expand Down
165 changes: 82 additions & 83 deletions prompb/types.pb.go

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion prompb/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ message TimeSeries {
repeated Sample samples = 2 [(gogoproto.nullable) = false];
repeated Exemplar exemplars = 3 [(gogoproto.nullable) = false];
repeated Histogram histograms = 4 [(gogoproto.nullable) = false];
repeated string identifyingLabels = 5;
// data labels for target_info metrics.
repeated string dataLabels = 5;
}

message Label {
Expand Down
4 changes: 2 additions & 2 deletions storage/remote/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -760,10 +760,10 @@ func LabelProtosToMetric(labelPairs []*prompb.Label) model.Metric {
return metric
}

func labelProtosToLabels(labelPairs []prompb.Label, identifyingLabels ...string) labels.Labels {
func labelProtosToLabels(labelPairs []prompb.Label) labels.Labels {
b := labels.ScratchBuilder{}
for _, l := range labelPairs {
b.Add(l.Name, l.Value, identifyingLabels...)
b.Add(l.Name, l.Value)
}
b.Sort()
return b.Labels()
Expand Down
41 changes: 20 additions & 21 deletions storage/remote/otlptranslator/prometheusremotewrite/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ func (a ByLabelName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// creates a new TimeSeries in the map if not found and returns the time series signature.
// tsMap will be unmodified if either labels or sample is nil, but can still be modified if the exemplar is nil.
func addSample(tsMap map[string]*prompb.TimeSeries, sample *prompb.Sample, labels []prompb.Label,
datatype string, isTargetMetric bool) string {

datatype string) string {
if sample == nil || labels == nil || tsMap == nil {
return ""
}
Expand All @@ -84,18 +83,9 @@ func addSample(tsMap map[string]*prompb.TimeSeries, sample *prompb.Sample, label
if ok {
ts.Samples = append(ts.Samples, *sample)
} else {
var identifyingLabels []string
if isTargetMetric {
identifyingLabels = []string{
model.InstanceLabel,
model.JobLabel,
}
slices.Sort(identifyingLabels)
}
newTs := &prompb.TimeSeries{
Labels: labels,
Samples: []prompb.Sample{*sample},
IdentifyingLabels: identifyingLabels,
Labels: labels,
Samples: []prompb.Sample{*sample},
}
tsMap[sig] = newTs
}
Expand Down Expand Up @@ -300,7 +290,7 @@ func addSingleHistogramDataPoint(pt pmetric.HistogramDataPoint, resource pcommon
}

sumlabels := createLabels(sumStr)
addSample(tsMap, sum, sumlabels, metric.Type().String(), false)
addSample(tsMap, sum, sumlabels, metric.Type().String())

}

Expand All @@ -314,7 +304,7 @@ func addSingleHistogramDataPoint(pt pmetric.HistogramDataPoint, resource pcommon
}

countlabels := createLabels(countStr)
addSample(tsMap, count, countlabels, metric.Type().String(), false)
addSample(tsMap, count, countlabels, metric.Type().String())

// cumulative count for conversion to cumulative histogram
var cumulativeCount uint64
Expand All @@ -336,7 +326,7 @@ func addSingleHistogramDataPoint(pt pmetric.HistogramDataPoint, resource pcommon
}
boundStr := strconv.FormatFloat(bound, 'f', -1, 64)
labels := createLabels(bucketStr, leStr, boundStr)
sig := addSample(tsMap, bucket, labels, metric.Type().String(), false)
sig := addSample(tsMap, bucket, labels, metric.Type().String())

bucketBounds = append(bucketBounds, bucketBoundsData{sig: sig, bound: bound})
}
Expand All @@ -350,7 +340,7 @@ func addSingleHistogramDataPoint(pt pmetric.HistogramDataPoint, resource pcommon
infBucket.Value = float64(pt.Count())
}
infLabels := createLabels(bucketStr, leStr, pInfStr)
sig := addSample(tsMap, infBucket, infLabels, metric.Type().String(), false)
sig := addSample(tsMap, infBucket, infLabels, metric.Type().String())

bucketBounds = append(bucketBounds, bucketBoundsData{sig: sig, bound: math.Inf(1)})
addExemplars(tsMap, promExemplars, bucketBounds)
Expand Down Expand Up @@ -496,7 +486,7 @@ func addSingleSummaryDataPoint(pt pmetric.SummaryDataPoint, resource pcommon.Res
sum.Value = math.Float64frombits(value.StaleNaN)
}
sumlabels := createLabels(baseName + sumStr)
addSample(tsMap, sum, sumlabels, metric.Type().String(), false)
addSample(tsMap, sum, sumlabels, metric.Type().String())

// treat count as a sample in an individual TimeSeries
count := &prompb.Sample{
Expand All @@ -507,7 +497,7 @@ func addSingleSummaryDataPoint(pt pmetric.SummaryDataPoint, resource pcommon.Res
count.Value = math.Float64frombits(value.StaleNaN)
}
countlabels := createLabels(baseName + countStr)
addSample(tsMap, count, countlabels, metric.Type().String(), false)
addSample(tsMap, count, countlabels, metric.Type().String())

// process each percentile/quantile
for i := 0; i < pt.QuantileValues().Len(); i++ {
Expand All @@ -521,7 +511,7 @@ func addSingleSummaryDataPoint(pt pmetric.SummaryDataPoint, resource pcommon.Res
}
percentileStr := strconv.FormatFloat(qt.Quantile(), 'f', -1, 64)
qtlabels := createLabels(baseName, quantileStr, percentileStr)
addSample(tsMap, quantile, qtlabels, metric.Type().String(), false)
addSample(tsMap, quantile, qtlabels, metric.Type().String())
}

// add _created time series if needed
Expand Down Expand Up @@ -586,7 +576,16 @@ func addResourceTargetInfo(resource pcommon.Resource, settings Settings, timesta
// convert ns to ms
Timestamp: convertTimeStamp(timestamp),
}
addSample(tsMap, sample, labels, infoType, true)
sig := addSample(tsMap, sample, labels, infoType)

dataLabels := make([]string, 0, len(labels))
for _, l := range labels {
if l.Name != model.InstanceLabel && l.Name != model.JobLabel {
dataLabels = append(dataLabels, l.Name)
}
}
slices.Sort(dataLabels)
tsMap[sig].DataLabels = dataLabels
}

// convertTimeStamp converts OTLP timestamp in ns to timestamp in ms
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func addSingleGaugeNumberDataPoint(
if pt.Flags().NoRecordedValue() {
sample.Value = math.Float64frombits(value.StaleNaN)
}
addSample(series, sample, labels, metric.Type().String(), false)
addSample(series, sample, labels, metric.Type().String())
}

// addSingleSumNumberDataPoint converts the Sum metric data point to a Prometheus
Expand Down Expand Up @@ -80,7 +80,7 @@ func addSingleSumNumberDataPoint(
if pt.Flags().NoRecordedValue() {
sample.Value = math.Float64frombits(value.StaleNaN)
}
sig := addSample(series, sample, labels, metric.Type().String(), false)
sig := addSample(series, sample, labels, metric.Type().String())

if ts, ok := series[sig]; sig != "" && ok {
exemplars := getPromExemplars[pmetric.NumberDataPoint](pt)
Expand Down
12 changes: 8 additions & 4 deletions storage/remote/write_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,14 @@ func (h *writeHandler) write(ctx context.Context, req *prompb.WriteRequest) (err

var exemplarErr error
for _, ts := range req.Timeseries {
labels := labelProtosToLabels(ts.Labels, ts.IdentifyingLabels...)
labels := labelProtosToLabels(ts.Labels)
if !labels.IsValid() {
level.Warn(h.logger).Log("msg", "Invalid metric names or labels", "got", labels.String())
samplesWithInvalidLabels++
continue
}
var ref storage.SeriesRef
for _, s := range ts.Samples {
// When recording a sample for an info type metric with identifying labels,
// make sure also to persist which of the labels are identifying
ref, err = app.Append(ref, labels, s.Timestamp, s.Value)
if err != nil {
unwrappedErr := errors.Unwrap(err)
Expand All @@ -135,7 +133,6 @@ func (h *writeHandler) write(ctx context.Context, req *prompb.WriteRequest) (err
}
return err
}

}

for _, ep := range ts.Exemplars {
Expand Down Expand Up @@ -170,6 +167,13 @@ func (h *writeHandler) write(ctx context.Context, req *prompb.WriteRequest) (err
return err
}
}

if len(ts.DataLabels) > 0 {
// Info type metric with metadata represented as data labels
if err := app.AppendDataLabels(ts.DataLabels, ts.Samples[0].Timestamp); err != nil {

Check failure on line 173 in storage/remote/write_handler.go

View workflow job for this annotation

GitHub Actions / lint

app.AppendDataLabels undefined (type "github.com/prometheus/prometheus/storage".Appender has no field or method AppendDataLabels)) (typecheck)

Check failure on line 173 in storage/remote/write_handler.go

View workflow job for this annotation

GitHub Actions / lint

app.AppendDataLabels undefined (type "github.com/prometheus/prometheus/storage".Appender has no field or method AppendDataLabels)) (typecheck)

Check failure on line 173 in storage/remote/write_handler.go

View workflow job for this annotation

GitHub Actions / lint

app.AppendDataLabels undefined (type "github.com/prometheus/prometheus/storage".Appender has no field or method AppendDataLabels) (typecheck)

Check failure on line 173 in storage/remote/write_handler.go

View workflow job for this annotation

GitHub Actions / lint

app.AppendDataLabels undefined (type "github.com/prometheus/prometheus/storage".Appender has no field or method AppendDataLabels)) (typecheck)

Check failure on line 173 in storage/remote/write_handler.go

View workflow job for this annotation

GitHub Actions / lint

app.AppendDataLabels undefined (type "github.com/prometheus/prometheus/storage".Appender has no field or method AppendDataLabels)) (typecheck)

Check failure on line 173 in storage/remote/write_handler.go

View workflow job for this annotation

GitHub Actions / lint

app.AppendDataLabels undefined (type "github.com/prometheus/prometheus/storage".Appender has no field or method AppendDataLabels)) (typecheck)

Check failure on line 173 in storage/remote/write_handler.go

View workflow job for this annotation

GitHub Actions / lint

app.AppendDataLabels undefined (type "github.com/prometheus/prometheus/storage".Appender has no field or method AppendDataLabels)) (typecheck)

Check failure on line 173 in storage/remote/write_handler.go

View workflow job for this annotation

GitHub Actions / lint

app.AppendDataLabels undefined (type "github.com/prometheus/prometheus/storage".Appender has no field or method AppendDataLabels) (typecheck)

Check failure on line 173 in storage/remote/write_handler.go

View workflow job for this annotation

GitHub Actions / lint

app.AppendDataLabels undefined (type "github.com/prometheus/prometheus/storage".Appender has no field or method AppendDataLabels)) (typecheck)

Check failure on line 173 in storage/remote/write_handler.go

View workflow job for this annotation

GitHub Actions / lint

app.AppendDataLabels undefined (type "github.com/prometheus/prometheus/storage".Appender has no field or method AppendDataLabels)) (typecheck)
return err
}
}
}

if outOfOrderExemplarErrs > 0 {
Expand Down

0 comments on commit a5028ca

Please sign in to comment.