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  }