Merge pull request #262 from prometheus/beorn7/summary

Allow Summaries with empty objectives and deprecate DefObjectives
This commit is contained in:
Björn Rabenstein 2016-11-24 16:57:32 +01:00 committed by GitHub
commit 575f371f78
8 changed files with 76 additions and 18 deletions

View File

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

View File

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

View File

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

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