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:
beorn7 2016-11-23 16:08:11 +01:00
parent 7993aa4cbe
commit 9c4b7780d7
8 changed files with 76 additions and 18 deletions

View File

@ -44,6 +44,7 @@ var (
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"},
) )

View File

@ -131,6 +131,7 @@ func BenchmarkSummaryWithLabelValues(b *testing.B) {
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"},
) )
@ -145,6 +146,7 @@ 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()

View File

@ -335,7 +335,8 @@ 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.
@ -373,7 +374,8 @@ 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"},
) )

View File

@ -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"},
) )

View File

@ -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,
) )

View File

@ -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(

View File

@ -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
} }

View File

@ -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()
@ -138,6 +177,7 @@ func TestSummaryConcurrency(t *testing.T) {
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)
@ -225,6 +265,7 @@ func TestSummaryVecConcurrency(t *testing.T) {
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"},
) )