forked from mirror/client_golang
Merge pull request #708 from prometheus/beorn7/exemplars
Pull out ...WithExemplar methods into separate interfaces
This commit is contained in:
commit
e951d7bae9
|
@ -90,9 +90,13 @@ func main() {
|
||||||
for {
|
for {
|
||||||
v := (rand.NormFloat64() * *normDomain) + *normMean
|
v := (rand.NormFloat64() * *normDomain) + *normMean
|
||||||
rpcDurations.WithLabelValues("normal").Observe(v)
|
rpcDurations.WithLabelValues("normal").Observe(v)
|
||||||
rpcDurationsHistogram.ObserveWithExemplar(
|
// Demonstrate exemplar support with a dummy ID. This
|
||||||
// Demonstrate exemplar support with a dummy ID. This would be
|
// would be something like a trace ID in a real
|
||||||
// something like a trace ID in a real application.
|
// 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))},
|
v, prometheus.Labels{"dummyID": fmt.Sprint(rand.Intn(100000))},
|
||||||
)
|
)
|
||||||
time.Sleep(time.Duration(75*oscillationFactor()) * time.Millisecond)
|
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 <
|
// Add adds the given value to the counter. It panics if the value is <
|
||||||
// 0.
|
// 0.
|
||||||
Add(float64)
|
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
|
// ExemplarAdder is implemented by Counters that offer the option of adding a
|
||||||
// will lead to a valid (label-less) exemplar. But if Labels is nil, the
|
// value to the Counter together with an exemplar. Its AddWithExemplar method
|
||||||
// current exemplar is left in place. This method panics if the value is
|
// works like the Add method of the Counter interface but also replaces the
|
||||||
// < 0, if any of the provided labels are invalid, or if the provided
|
// currently saved exemplar (if any) with a new one, created from the provided
|
||||||
// labels contain more than 64 runes in total.
|
// 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)
|
AddWithExemplar(value float64, exemplar Labels)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +61,9 @@ type CounterOpts Opts
|
||||||
|
|
||||||
// NewCounter creates a new Counter based on the provided CounterOpts.
|
// 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
|
// 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
|
// 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
|
// 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 adds a single observation to the histogram.
|
||||||
Observe(float64)
|
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
|
// 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
|
// NewHistogram creates a new Histogram based on the provided HistogramOpts. It
|
||||||
// panics if the buckets in HistogramOpts are not in strictly increasing order.
|
// 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 {
|
func NewHistogram(opts HistogramOpts) Histogram {
|
||||||
return newHistogram(
|
return newHistogram(
|
||||||
NewDesc(
|
NewDesc(
|
||||||
|
|
|
@ -189,7 +189,7 @@ func TestHistogramConcurrency(t *testing.T) {
|
||||||
if n%2 == 0 {
|
if n%2 == 0 {
|
||||||
sum.Observe(v)
|
sum.Observe(v)
|
||||||
} else {
|
} else {
|
||||||
sum.ObserveWithExemplar(v, Labels{"foo": "bar"})
|
sum.(ExemplarObserver).ObserveWithExemplar(v, Labels{"foo": "bar"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end.Done()
|
end.Done()
|
||||||
|
|
|
@ -50,3 +50,15 @@ type ObserverVec interface {
|
||||||
|
|
||||||
Collector
|
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