forked from mirror/client_golang
Allow Summaries with empty objectives and deprecate DefObjectives
This also updates all tests and examples to use explicitly set objectives. In v0.10, DefObjectives will be completely removed, and the default Summary will have no objectives then. Fixes #118
This commit is contained in:
parent
7993aa4cbe
commit
9c4b7780d7
|
@ -42,8 +42,9 @@ var (
|
||||||
// differentiated via a "service" label.
|
// differentiated via a "service" label.
|
||||||
rpcDurations = prometheus.NewSummaryVec(
|
rpcDurations = prometheus.NewSummaryVec(
|
||||||
prometheus.SummaryOpts{
|
prometheus.SummaryOpts{
|
||||||
Name: "rpc_durations_seconds",
|
Name: "rpc_durations_seconds",
|
||||||
Help: "RPC latency distributions.",
|
Help: "RPC latency distributions.",
|
||||||
|
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
||||||
},
|
},
|
||||||
[]string{"service"},
|
[]string{"service"},
|
||||||
)
|
)
|
||||||
|
|
|
@ -129,8 +129,9 @@ func BenchmarkGaugeNoLabels(b *testing.B) {
|
||||||
func BenchmarkSummaryWithLabelValues(b *testing.B) {
|
func BenchmarkSummaryWithLabelValues(b *testing.B) {
|
||||||
m := NewSummaryVec(
|
m := NewSummaryVec(
|
||||||
SummaryOpts{
|
SummaryOpts{
|
||||||
Name: "benchmark_summary",
|
Name: "benchmark_summary",
|
||||||
Help: "A summary to benchmark it.",
|
Help: "A summary to benchmark it.",
|
||||||
|
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
||||||
},
|
},
|
||||||
[]string{"one", "two", "three"},
|
[]string{"one", "two", "three"},
|
||||||
)
|
)
|
||||||
|
@ -143,8 +144,9 @@ func BenchmarkSummaryWithLabelValues(b *testing.B) {
|
||||||
|
|
||||||
func BenchmarkSummaryNoLabels(b *testing.B) {
|
func BenchmarkSummaryNoLabels(b *testing.B) {
|
||||||
m := NewSummary(SummaryOpts{
|
m := NewSummary(SummaryOpts{
|
||||||
Name: "benchmark_summary",
|
Name: "benchmark_summary",
|
||||||
Help: "A summary to benchmark it.",
|
Help: "A summary to benchmark it.",
|
||||||
|
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
|
|
|
@ -334,8 +334,9 @@ func ExampleRegister() {
|
||||||
|
|
||||||
func ExampleSummary() {
|
func ExampleSummary() {
|
||||||
temps := prometheus.NewSummary(prometheus.SummaryOpts{
|
temps := prometheus.NewSummary(prometheus.SummaryOpts{
|
||||||
Name: "pond_temperature_celsius",
|
Name: "pond_temperature_celsius",
|
||||||
Help: "The temperature of the frog pond.", // Sorry, we can't measure how badly it smells.
|
Help: "The temperature of the frog pond.",
|
||||||
|
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Simulate some observations.
|
// Simulate some observations.
|
||||||
|
@ -372,8 +373,9 @@ func ExampleSummary() {
|
||||||
func ExampleSummaryVec() {
|
func ExampleSummaryVec() {
|
||||||
temps := prometheus.NewSummaryVec(
|
temps := prometheus.NewSummaryVec(
|
||||||
prometheus.SummaryOpts{
|
prometheus.SummaryOpts{
|
||||||
Name: "pond_temperature_celsius",
|
Name: "pond_temperature_celsius",
|
||||||
Help: "The temperature of the frog pond.", // Sorry, we can't measure how badly it smells.
|
Help: "The temperature of the frog pond.",
|
||||||
|
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
||||||
},
|
},
|
||||||
[]string{"species"},
|
[]string{"species"},
|
||||||
)
|
)
|
||||||
|
|
|
@ -52,6 +52,7 @@ func TestWriteSummary(t *testing.T) {
|
||||||
Name: "name",
|
Name: "name",
|
||||||
Help: "docstring",
|
Help: "docstring",
|
||||||
ConstLabels: prometheus.Labels{"constname": "constvalue"},
|
ConstLabels: prometheus.Labels{"constname": "constvalue"},
|
||||||
|
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
||||||
},
|
},
|
||||||
[]string{"labelname"},
|
[]string{"labelname"},
|
||||||
)
|
)
|
||||||
|
|
|
@ -190,6 +190,7 @@ func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWri
|
||||||
SummaryOpts{
|
SummaryOpts{
|
||||||
Subsystem: "http",
|
Subsystem: "http",
|
||||||
ConstLabels: Labels{"handler": handlerName},
|
ConstLabels: Labels{"handler": handlerName},
|
||||||
|
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
||||||
},
|
},
|
||||||
handlerFunc,
|
handlerFunc,
|
||||||
)
|
)
|
||||||
|
|
|
@ -44,6 +44,7 @@ func TestInstrumentHandler(t *testing.T) {
|
||||||
opts := SummaryOpts{
|
opts := SummaryOpts{
|
||||||
Subsystem: "http",
|
Subsystem: "http",
|
||||||
ConstLabels: Labels{"handler": "test-handler"},
|
ConstLabels: Labels{"handler": "test-handler"},
|
||||||
|
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
||||||
}
|
}
|
||||||
|
|
||||||
reqCnt := NewCounterVec(
|
reqCnt := NewCounterVec(
|
||||||
|
|
|
@ -54,6 +54,9 @@ type Summary interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefObjectives are the default Summary quantile values.
|
// DefObjectives are the default Summary quantile values.
|
||||||
|
//
|
||||||
|
// Deprecated: DefObjectives will not be used as the default objectives in
|
||||||
|
// v0.10 of the library. The default Summary will have no quantiles then.
|
||||||
var (
|
var (
|
||||||
DefObjectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}
|
DefObjectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}
|
||||||
|
|
||||||
|
@ -113,9 +116,15 @@ type SummaryOpts struct {
|
||||||
ConstLabels Labels
|
ConstLabels Labels
|
||||||
|
|
||||||
// Objectives defines the quantile rank estimates with their respective
|
// Objectives defines the quantile rank estimates with their respective
|
||||||
// absolute error. If Objectives[q] = e, then the value reported
|
// absolute error. If Objectives[q] = e, then the value reported for q
|
||||||
// for q will be the φ-quantile value for some φ between q-e and q+e.
|
// will be the φ-quantile value for some φ between q-e and q+e. The
|
||||||
// The default value is DefObjectives.
|
// default value is DefObjectives. It is used if Objectives is left at
|
||||||
|
// its zero value (i.e. nil). To create a Summary without Objectives,
|
||||||
|
// set it to an empty map (i.e. map[float64]float64{}).
|
||||||
|
//
|
||||||
|
// Deprecated: Note that the current value of DefObjectives is
|
||||||
|
// deprecated. It will be replaced by an empty map in v0.10 of the
|
||||||
|
// library. Please explicitly set Objectives to the desired value.
|
||||||
Objectives map[float64]float64
|
Objectives map[float64]float64
|
||||||
|
|
||||||
// MaxAge defines the duration for which an observation stays relevant
|
// MaxAge defines the duration for which an observation stays relevant
|
||||||
|
@ -183,7 +192,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(opts.Objectives) == 0 {
|
if opts.Objectives == nil {
|
||||||
opts.Objectives = DefObjectives
|
opts.Objectives = DefObjectives
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,45 @@ import (
|
||||||
dto "github.com/prometheus/client_model/go"
|
dto "github.com/prometheus/client_model/go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestSummaryWithDefaultObjectives(t *testing.T) {
|
||||||
|
reg := NewRegistry()
|
||||||
|
summaryWithDefaultObjectives := NewSummary(SummaryOpts{
|
||||||
|
Name: "default_objectives",
|
||||||
|
Help: "Test help.",
|
||||||
|
})
|
||||||
|
if err := reg.Register(summaryWithDefaultObjectives); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m := &dto.Metric{}
|
||||||
|
if err := summaryWithDefaultObjectives.Write(m); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if len(m.GetSummary().Quantile) != len(DefObjectives) {
|
||||||
|
t.Error("expected default objectives in summary")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSummaryWithoutObjectives(t *testing.T) {
|
||||||
|
reg := NewRegistry()
|
||||||
|
summaryWithEmptyObjectives := NewSummary(SummaryOpts{
|
||||||
|
Name: "empty_objectives",
|
||||||
|
Help: "Test help.",
|
||||||
|
Objectives: map[float64]float64{},
|
||||||
|
})
|
||||||
|
if err := reg.Register(summaryWithEmptyObjectives); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m := &dto.Metric{}
|
||||||
|
if err := summaryWithEmptyObjectives.Write(m); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if len(m.GetSummary().Quantile) != 0 {
|
||||||
|
t.Error("expected no objectives in summary")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func benchmarkSummaryObserve(w int, b *testing.B) {
|
func benchmarkSummaryObserve(w int, b *testing.B) {
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
|
|
||||||
|
@ -136,8 +175,9 @@ func TestSummaryConcurrency(t *testing.T) {
|
||||||
end.Add(concLevel)
|
end.Add(concLevel)
|
||||||
|
|
||||||
sum := NewSummary(SummaryOpts{
|
sum := NewSummary(SummaryOpts{
|
||||||
Name: "test_summary",
|
Name: "test_summary",
|
||||||
Help: "helpless",
|
Help: "helpless",
|
||||||
|
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
||||||
})
|
})
|
||||||
|
|
||||||
allVars := make([]float64, total)
|
allVars := make([]float64, total)
|
||||||
|
@ -223,8 +263,9 @@ func TestSummaryVecConcurrency(t *testing.T) {
|
||||||
|
|
||||||
sum := NewSummaryVec(
|
sum := NewSummaryVec(
|
||||||
SummaryOpts{
|
SummaryOpts{
|
||||||
Name: "test_summary",
|
Name: "test_summary",
|
||||||
Help: "helpless",
|
Help: "helpless",
|
||||||
|
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
||||||
},
|
},
|
||||||
[]string{"label"},
|
[]string{"label"},
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue