Pull out ...WithExemplar methods into separate interfaces
This is, sadly, the only way to avoid a breaking change. The cost is that anyone using exemplars has to perform a type assertion. This is, however, a common pattern where interfaces turn out to need additional methods in a stable library or only some implementations can provide the additional methods (AKA "interface upgrade"). Needless to say that in v2 of this library, we'll do things in a more straight forward way. Signed-off-by: beorn7 <beorn@grafana.com>
This commit is contained in:
parent
ba7901740d
commit
f34b09877c
|
@ -90,9 +90,13 @@ func main() {
|
|||
for {
|
||||
v := (rand.NormFloat64() * *normDomain) + *normMean
|
||||
rpcDurations.WithLabelValues("normal").Observe(v)
|
||||
rpcDurationsHistogram.ObserveWithExemplar(
|
||||
// Demonstrate exemplar support with a dummy ID. This would be
|
||||
// something like a trace ID in a real application.
|
||||
// Demonstrate exemplar support with a dummy ID. This
|
||||
// would be something like a trace ID in a real
|
||||
// application. Note the necessary type assertion. We
|
||||
// already know that rpcDurationsHistogram implements
|
||||
// the ExemplarObserver interface and thus don't need to
|
||||
// check the outcome of the tipe assertion.
|
||||
rpcDurationsHistogram.(prometheus.ExemplarObserver).ObserveWithExemplar(
|
||||
v, prometheus.Labels{"dummyID": fmt.Sprint(rand.Intn(100000))},
|
||||
)
|
||||
time.Sleep(time.Duration(75*oscillationFactor()) * time.Millisecond)
|
||||
|
|
|
@ -41,13 +41,18 @@ type Counter interface {
|
|||
// Add adds the given value to the counter. It panics if the value is <
|
||||
// 0.
|
||||
Add(float64)
|
||||
// AddWithExemplar works like Add but also replaces the currently saved
|
||||
// exemplar (if any) with a new one, created from the provided value,
|
||||
// the current time as timestamp, and the provided labels. Empty Labels
|
||||
// will lead to a valid (label-less) exemplar. But if Labels is nil, the
|
||||
// current exemplar is left in place. This method panics if the value is
|
||||
// < 0, if any of the provided labels are invalid, or if the provided
|
||||
// labels contain more than 64 runes in total.
|
||||
}
|
||||
|
||||
// ExemplarAdder is implemented by Counters that offer the option of adding a
|
||||
// value to the Counter together with an exemplar. Its AddWithExemplar method
|
||||
// works like the Add method of the Counter interface but also replaces the
|
||||
// currently saved exemplar (if any) with a new one, created from the provided
|
||||
// value, the current time as timestamp, and the provided labels. Empty Labels
|
||||
// will lead to a valid (label-less) exemplar. But if Labels is nil, the current
|
||||
// exemplar is left in place. AddWithExemplar panics if the value is < 0, if any
|
||||
// of the provided labels are invalid, or if the provided labels contain more
|
||||
// than 64 runes in total.
|
||||
type ExemplarAdder interface {
|
||||
AddWithExemplar(value float64, exemplar Labels)
|
||||
}
|
||||
|
||||
|
@ -56,6 +61,9 @@ type CounterOpts Opts
|
|||
|
||||
// NewCounter creates a new Counter based on the provided CounterOpts.
|
||||
//
|
||||
// The returned implementation also implements ExemplarAdder. It is safe to
|
||||
// perform the corresponding type assertion.
|
||||
//
|
||||
// The returned implementation tracks the counter value in two separate
|
||||
// variables, a float64 and a uint64. The latter is used to track calls of the
|
||||
// Inc method and calls of the Add method with a value that can be represented
|
||||
|
|
|
@ -48,15 +48,6 @@ type Histogram interface {
|
|||
|
||||
// Observe adds a single observation to the histogram.
|
||||
Observe(float64)
|
||||
// ObserveWithExemplar works like Observe but also replaces the
|
||||
// currently saved exemplar for the relevant bucket (possibly none) with
|
||||
// a new one, created from the provided value, the current time as
|
||||
// timestamp, and the provided Labels. Empty Labels will lead to a valid
|
||||
// (label-less) exemplar. But if Labels is nil, the current exemplar in
|
||||
// the relevant bucket is left in place. This method panics if any of
|
||||
// the provided labels are invalid or if the provided labels contain
|
||||
// more than 64 runes in total.
|
||||
ObserveWithExemplar(value float64, exemplar Labels)
|
||||
}
|
||||
|
||||
// bucketLabel is used for the label that defines the upper bound of a
|
||||
|
@ -161,6 +152,10 @@ type HistogramOpts struct {
|
|||
|
||||
// NewHistogram creates a new Histogram based on the provided HistogramOpts. It
|
||||
// panics if the buckets in HistogramOpts are not in strictly increasing order.
|
||||
//
|
||||
// The returned implementation also implements ExemplarObserver. It is safe to
|
||||
// perform the corresponding type assertion. Exemplars are tracked separately
|
||||
// for each bucket.
|
||||
func NewHistogram(opts HistogramOpts) Histogram {
|
||||
return newHistogram(
|
||||
NewDesc(
|
||||
|
|
|
@ -189,7 +189,7 @@ func TestHistogramConcurrency(t *testing.T) {
|
|||
if n%2 == 0 {
|
||||
sum.Observe(v)
|
||||
} else {
|
||||
sum.ObserveWithExemplar(v, Labels{"foo": "bar"})
|
||||
sum.(ExemplarObserver).ObserveWithExemplar(v, Labels{"foo": "bar"})
|
||||
}
|
||||
}
|
||||
end.Done()
|
||||
|
|
|
@ -50,3 +50,15 @@ type ObserverVec interface {
|
|||
|
||||
Collector
|
||||
}
|
||||
|
||||
// ExemplarObserver is implemented by Observers that offer the option of
|
||||
// observing a value together with an exemplar. Its ObserveWithExemplar method
|
||||
// works like the Observe method of an Observer but also replaces the currently
|
||||
// saved exemplar (if any) with a new one, created from the provided value, the
|
||||
// current time as timestamp, and the provided Labels. Empty Labels will lead to
|
||||
// a valid (label-less) exemplar. But if Labels is nil, the current exemplar is
|
||||
// left in place. ObserveWithExemplar panics if any of the provided labels are
|
||||
// invalid or if the provided labels contain more than 64 runes in total.
|
||||
type ExemplarObserver interface {
|
||||
ObserveWithExemplar(value float64, exemplar Labels)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue