github.com/thanos-io/thanos@v0.32.5/pkg/exemplars/exemplarspb/custom.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package exemplarspb 5 6 import ( 7 "encoding/json" 8 "math/big" 9 10 "github.com/prometheus/common/model" 11 "github.com/prometheus/prometheus/model/exemplar" 12 "github.com/prometheus/prometheus/model/labels" 13 14 "github.com/thanos-io/thanos/pkg/store/labelpb" 15 ) 16 17 // ExemplarStore wraps the ExemplarsClient and contains the info of external labels. 18 type ExemplarStore struct { 19 ExemplarsClient 20 LabelSets []labels.Labels 21 } 22 23 // UnmarshalJSON implements json.Unmarshaler. 24 func (m *Exemplar) UnmarshalJSON(b []byte) error { 25 v := struct { 26 Labels labelpb.ZLabelSet 27 TimeStamp model.Time 28 Value model.SampleValue 29 }{} 30 if err := json.Unmarshal(b, &v); err != nil { 31 return err 32 } 33 34 m.Labels = v.Labels 35 m.Ts = int64(v.TimeStamp) 36 m.Value = float64(v.Value) 37 38 return nil 39 } 40 41 // MarshalJSON implements json.Marshaler. 42 func (m *Exemplar) MarshalJSON() ([]byte, error) { 43 v := struct { 44 Labels labels.Labels `json:"labels"` 45 TimeStamp model.Time `json:"timestamp"` 46 Value model.SampleValue `json:"value"` 47 }{ 48 Labels: labelpb.ZLabelsToPromLabels(m.Labels.Labels), 49 TimeStamp: model.Time(m.Ts), 50 Value: model.SampleValue(m.Value), 51 } 52 return json.Marshal(v) 53 } 54 55 func NewExemplarsResponse(e *ExemplarData) *ExemplarsResponse { 56 return &ExemplarsResponse{ 57 Result: &ExemplarsResponse_Data{ 58 Data: e, 59 }, 60 } 61 } 62 63 func NewWarningExemplarsResponse(warning error) *ExemplarsResponse { 64 return &ExemplarsResponse{ 65 Result: &ExemplarsResponse_Warning{ 66 Warning: warning.Error(), 67 }, 68 } 69 } 70 71 // Compare only compares the series labels of two exemplar data. 72 func (s1 *ExemplarData) Compare(s2 *ExemplarData) int { 73 return labels.Compare(s1.SeriesLabels.PromLabels(), s2.SeriesLabels.PromLabels()) 74 } 75 76 func (s *ExemplarData) SetSeriesLabels(ls labels.Labels) { 77 var result labelpb.ZLabelSet 78 79 if len(ls) > 0 { 80 result = labelpb.ZLabelSet{Labels: labelpb.ZLabelsFromPromLabels(ls)} 81 } 82 83 s.SeriesLabels = result 84 } 85 86 // Compare is used for sorting and comparing exemplars. Start from timestamp, then labels, finally values. 87 func (e1 *Exemplar) Compare(e2 *Exemplar) int { 88 if e1.Ts < e2.Ts { 89 return -1 90 } 91 if e1.Ts > e2.Ts { 92 return 1 93 } 94 95 if d := labels.Compare(e1.Labels.PromLabels(), e2.Labels.PromLabels()); d != 0 { 96 return d 97 } 98 return big.NewFloat(e1.Value).Cmp(big.NewFloat(e2.Value)) 99 } 100 101 func ExemplarsFromPromExemplars(exemplars []exemplar.Exemplar) []*Exemplar { 102 ex := make([]*Exemplar, 0, len(exemplars)) 103 for _, e := range exemplars { 104 ex = append(ex, &Exemplar{ 105 Labels: labelpb.ZLabelSet{Labels: labelpb.ZLabelsFromPromLabels(e.Labels)}, 106 Value: e.Value, 107 Ts: e.Ts, 108 }) 109 } 110 return ex 111 }