github.com/thanos-io/thanos@v0.32.5/pkg/exemplars/prometheus.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package exemplars
     5  
     6  import (
     7  	"context"
     8  	"net/url"
     9  
    10  	"github.com/prometheus/prometheus/model/labels"
    11  
    12  	"github.com/thanos-io/thanos/pkg/exemplars/exemplarspb"
    13  	"github.com/thanos-io/thanos/pkg/promclient"
    14  	"github.com/thanos-io/thanos/pkg/store/labelpb"
    15  	"github.com/thanos-io/thanos/pkg/tracing"
    16  )
    17  
    18  // Prometheus implements exemplarspb.Exemplars gRPC that allows to fetch exemplars from Prometheus.
    19  type Prometheus struct {
    20  	base   *url.URL
    21  	client *promclient.Client
    22  
    23  	extLabels func() labels.Labels
    24  }
    25  
    26  // NewPrometheus creates new exemplars.Prometheus.
    27  func NewPrometheus(base *url.URL, client *promclient.Client, extLabels func() labels.Labels) *Prometheus {
    28  	return &Prometheus{
    29  		base:      base,
    30  		client:    client,
    31  		extLabels: extLabels,
    32  	}
    33  }
    34  
    35  // Exemplars returns all specified exemplars from Prometheus.
    36  func (p *Prometheus) Exemplars(r *exemplarspb.ExemplarsRequest, s exemplarspb.Exemplars_ExemplarsServer) error {
    37  	exemplars, err := p.client.ExemplarsInGRPC(s.Context(), p.base, r.Query, r.Start, r.End)
    38  	if err != nil {
    39  		return err
    40  	}
    41  
    42  	// Prometheus does not add external labels, so we need to add on our own.
    43  	extLset := p.extLabels()
    44  	for _, e := range exemplars {
    45  		// Make sure the returned series labels are sorted.
    46  		e.SetSeriesLabels(labelpb.ExtendSortedLabels(e.SeriesLabels.PromLabels(), extLset))
    47  
    48  		var err error
    49  		tracing.DoInSpan(s.Context(), "send_exemplars_response", func(_ context.Context) {
    50  			err = s.Send(&exemplarspb.ExemplarsResponse{Result: &exemplarspb.ExemplarsResponse_Data{Data: e}})
    51  		})
    52  		if err != nil {
    53  			return err
    54  		}
    55  	}
    56  	return nil
    57  }