forked from mirrors/statsd_exporter
create sub-hierarchies for summary and histogram options
Currently the Buckets and Quantiles settings are top level settings per metric in the yaml. In a subsequent commit we're going to allow adding more such options for summaries, at which point having them all at the top level gets confusing. Split the options out into separate hierarchies to allow adding more options, without adding confusion. We preserve backwards compatibility by still accepting the old option, but warning when it is present. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
This commit is contained in:
parent
c9c23a4f9e
commit
80b77513a6
4 changed files with 148 additions and 39 deletions
22
README.md
22
README.md
|
@ -247,15 +247,16 @@ mappings:
|
|||
provider: "$2"
|
||||
outcome: "$3"
|
||||
job: "${1}_server"
|
||||
quantiles:
|
||||
- quantile: 0.99
|
||||
error: 0.001
|
||||
- quantile: 0.95
|
||||
error: 0.01
|
||||
- quantile: 0.9
|
||||
error: 0.05
|
||||
- quantile: 0.5
|
||||
error: 0.005
|
||||
summary_options:
|
||||
quantiles:
|
||||
- quantile: 0.99
|
||||
error: 0.001
|
||||
- quantile: 0.95
|
||||
error: 0.01
|
||||
- quantile: 0.9
|
||||
error: 0.05
|
||||
- quantile: 0.5
|
||||
error: 0.005
|
||||
```
|
||||
|
||||
The default quantiles are 0.99, 0.9, and 0.5.
|
||||
|
@ -268,7 +269,8 @@ to set the timer type for a single metric:
|
|||
mappings:
|
||||
- match: "test.timing.*.*.*"
|
||||
timer_type: histogram
|
||||
buckets: [ 0.01, 0.025, 0.05, 0.1 ]
|
||||
histogram_options:
|
||||
buckets: [ 0.01, 0.025, 0.05, 0.1 ]
|
||||
name: "my_timer"
|
||||
labels:
|
||||
provider: "$2"
|
||||
|
|
|
@ -57,21 +57,31 @@ type MetricMapper struct {
|
|||
}
|
||||
|
||||
type MetricMapping struct {
|
||||
Match string `yaml:"match"`
|
||||
Name string `yaml:"name"`
|
||||
nameFormatter *fsm.TemplateFormatter
|
||||
regex *regexp.Regexp
|
||||
Labels prometheus.Labels `yaml:"labels"`
|
||||
labelKeys []string
|
||||
labelFormatters []*fsm.TemplateFormatter
|
||||
TimerType TimerType `yaml:"timer_type"`
|
||||
Buckets []float64 `yaml:"buckets"`
|
||||
Quantiles []metricObjective `yaml:"quantiles"`
|
||||
MatchType MatchType `yaml:"match_type"`
|
||||
HelpText string `yaml:"help"`
|
||||
Action ActionType `yaml:"action"`
|
||||
MatchMetricType MetricType `yaml:"match_metric_type"`
|
||||
Ttl time.Duration `yaml:"ttl"`
|
||||
Match string `yaml:"match"`
|
||||
Name string `yaml:"name"`
|
||||
nameFormatter *fsm.TemplateFormatter
|
||||
regex *regexp.Regexp
|
||||
Labels prometheus.Labels `yaml:"labels"`
|
||||
labelKeys []string
|
||||
labelFormatters []*fsm.TemplateFormatter
|
||||
TimerType TimerType `yaml:"timer_type"`
|
||||
LegacyBuckets []float64 `yaml:"buckets"`
|
||||
LegacyQuantiles []metricObjective `yaml:"quantiles"`
|
||||
MatchType MatchType `yaml:"match_type"`
|
||||
HelpText string `yaml:"help"`
|
||||
Action ActionType `yaml:"action"`
|
||||
MatchMetricType MetricType `yaml:"match_metric_type"`
|
||||
Ttl time.Duration `yaml:"ttl"`
|
||||
SummaryOptions *SummaryOptions `yaml:"summary_options"`
|
||||
HistogramOptions *HistogramOptions `yaml:"histogram_options"`
|
||||
}
|
||||
|
||||
type SummaryOptions struct {
|
||||
Quantiles []metricObjective `yaml:"quantiles"`
|
||||
}
|
||||
|
||||
type HistogramOptions struct {
|
||||
Buckets []float64 `yaml:"buckets"`
|
||||
}
|
||||
|
||||
type metricObjective struct {
|
||||
|
@ -172,12 +182,60 @@ func (m *MetricMapper) InitFromYAMLString(fileContents string, cacheSize int) er
|
|||
currentMapping.TimerType = n.Defaults.TimerType
|
||||
}
|
||||
|
||||
if currentMapping.Buckets == nil || len(currentMapping.Buckets) == 0 {
|
||||
currentMapping.Buckets = n.Defaults.Buckets
|
||||
if currentMapping.LegacyQuantiles != nil &&
|
||||
(currentMapping.SummaryOptions == nil || currentMapping.SummaryOptions.Quantiles != nil) {
|
||||
log.Warn("using the top level quantiles is deprecated. Please use quantiles in the summary_options hierarchy")
|
||||
}
|
||||
|
||||
if currentMapping.Quantiles == nil || len(currentMapping.Quantiles) == 0 {
|
||||
currentMapping.Quantiles = n.Defaults.Quantiles
|
||||
if currentMapping.LegacyBuckets != nil &&
|
||||
(currentMapping.HistogramOptions == nil || currentMapping.HistogramOptions.Buckets != nil) {
|
||||
log.Warn("using the top level buckets is deprecated. Please use buckets in the histogram_options hierarchy")
|
||||
}
|
||||
|
||||
if currentMapping.SummaryOptions != nil &&
|
||||
currentMapping.LegacyQuantiles != nil &&
|
||||
currentMapping.SummaryOptions.Quantiles != nil {
|
||||
return fmt.Errorf("cannot use quantiles in both the top level and summary options at the same time in %s", currentMapping.Match)
|
||||
}
|
||||
|
||||
if currentMapping.HistogramOptions != nil &&
|
||||
currentMapping.LegacyBuckets != nil &&
|
||||
currentMapping.HistogramOptions.Buckets != nil {
|
||||
return fmt.Errorf("cannot use buckets in both the top level and histogram options at the same time in %s", currentMapping.Match)
|
||||
}
|
||||
|
||||
if currentMapping.TimerType == TimerTypeHistogram {
|
||||
if currentMapping.SummaryOptions != nil {
|
||||
return fmt.Errorf("cannot use histogram timer and summary options at the same time")
|
||||
}
|
||||
if currentMapping.HistogramOptions == nil {
|
||||
currentMapping.HistogramOptions = &HistogramOptions{}
|
||||
}
|
||||
if currentMapping.LegacyBuckets != nil && len(currentMapping.LegacyBuckets) != 0 {
|
||||
currentMapping.HistogramOptions.Buckets = currentMapping.LegacyBuckets
|
||||
}
|
||||
if currentMapping.HistogramOptions.Buckets == nil || len(currentMapping.HistogramOptions.Buckets) == 0 {
|
||||
currentMapping.HistogramOptions.Buckets = n.Defaults.Buckets
|
||||
}
|
||||
}
|
||||
|
||||
if currentMapping.TimerType == TimerTypeSummary {
|
||||
if currentMapping.HistogramOptions != nil {
|
||||
return fmt.Errorf("cannot use summary timer and histogram options at the same time")
|
||||
}
|
||||
if currentMapping.SummaryOptions == nil {
|
||||
currentMapping.SummaryOptions = &SummaryOptions{}
|
||||
}
|
||||
}
|
||||
|
||||
if currentMapping.LegacyQuantiles == nil || len(currentMapping.LegacyQuantiles) == 0 {
|
||||
currentMapping.LegacyQuantiles = n.Defaults.Quantiles
|
||||
if currentMapping.LegacyQuantiles != nil && len(currentMapping.LegacyQuantiles) != 0 {
|
||||
currentMapping.SummaryOptions.Quantiles = currentMapping.LegacyQuantiles
|
||||
}
|
||||
if currentMapping.SummaryOptions.Quantiles == nil || len(currentMapping.SummaryOptions.Quantiles) == 0 {
|
||||
currentMapping.SummaryOptions.Quantiles = n.Defaults.Quantiles
|
||||
}
|
||||
}
|
||||
|
||||
if currentMapping.Ttl == 0 && n.Defaults.Ttl > 0 {
|
||||
|
|
|
@ -496,6 +496,51 @@ mappings:
|
|||
`,
|
||||
configBad: true,
|
||||
},
|
||||
// new style quantiles
|
||||
{
|
||||
config: `---
|
||||
mappings:
|
||||
- match: test.*.*
|
||||
timer_type: summary
|
||||
name: "foo"
|
||||
labels: {}
|
||||
summary_options:
|
||||
quantiles:
|
||||
- quantile: 0.42
|
||||
error: 0.04
|
||||
- quantile: 0.7
|
||||
error: 0.002
|
||||
`,
|
||||
mappings: mappings{
|
||||
{
|
||||
statsdMetric: "test.*.*",
|
||||
name: "foo",
|
||||
labels: map[string]string{},
|
||||
quantiles: []metricObjective{
|
||||
{Quantile: 0.42, Error: 0.04},
|
||||
{Quantile: 0.7, Error: 0.002},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// duplicate quantiles are bad
|
||||
{
|
||||
config: `---
|
||||
mappings:
|
||||
- match: test.*.*
|
||||
timer_type: summary
|
||||
name: "foo"
|
||||
labels: {}
|
||||
quantiles:
|
||||
- quantile: 0.42
|
||||
error: 0.04
|
||||
summary_options:
|
||||
quantiles:
|
||||
- quantile: 0.42
|
||||
error: 0.04
|
||||
`,
|
||||
configBad: true,
|
||||
},
|
||||
// Config with good metric type.
|
||||
{
|
||||
config: `---
|
||||
|
@ -777,15 +822,15 @@ mappings:
|
|||
}
|
||||
|
||||
if len(mapping.quantiles) != 0 {
|
||||
if len(mapping.quantiles) != len(m.Quantiles) {
|
||||
t.Fatalf("%d.%q: Expected %d quantiles, got %d", i, metric, len(mapping.quantiles), len(m.Quantiles))
|
||||
if len(mapping.quantiles) != len(m.SummaryOptions.Quantiles) {
|
||||
t.Fatalf("%d.%q: Expected %d quantiles, got %d", i, metric, len(mapping.quantiles), len(m.SummaryOptions.Quantiles))
|
||||
}
|
||||
for i, quantile := range mapping.quantiles {
|
||||
if quantile.Quantile != m.Quantiles[i].Quantile {
|
||||
t.Fatalf("%d.%q: Expected quantile %v, got %v", i, metric, m.Quantiles[i].Quantile, quantile.Quantile)
|
||||
if quantile.Quantile != m.SummaryOptions.Quantiles[i].Quantile {
|
||||
t.Fatalf("%d.%q: Expected quantile %v, got %v", i, metric, m.SummaryOptions.Quantiles[i].Quantile, quantile.Quantile)
|
||||
}
|
||||
if quantile.Error != m.Quantiles[i].Error {
|
||||
t.Fatalf("%d.%q: Expected Error margin %v, got %v", i, metric, m.Quantiles[i].Error, quantile.Error)
|
||||
if quantile.Error != m.SummaryOptions.Quantiles[i].Error {
|
||||
t.Fatalf("%d.%q: Expected Error margin %v, got %v", i, metric, m.SummaryOptions.Quantiles[i].Error, quantile.Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
12
registry.go
12
registry.go
|
@ -278,8 +278,8 @@ func (r *registry) getHistogram(metricName string, labels prometheus.Labels, hel
|
|||
if vh == nil {
|
||||
metricsCount.WithLabelValues("histogram").Inc()
|
||||
buckets := r.mapper.Defaults.Buckets
|
||||
if mapping.Buckets != nil && len(mapping.Buckets) > 0 {
|
||||
buckets = mapping.Buckets
|
||||
if mapping.HistogramOptions != nil && len(mapping.HistogramOptions.Buckets) > 0 {
|
||||
buckets = mapping.HistogramOptions.Buckets
|
||||
}
|
||||
histogramVec = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
||||
Name: metricName,
|
||||
|
@ -325,8 +325,12 @@ func (r *registry) getSummary(metricName string, labels prometheus.Labels, help
|
|||
if vh == nil {
|
||||
metricsCount.WithLabelValues("summary").Inc()
|
||||
quantiles := r.mapper.Defaults.Quantiles
|
||||
if mapping != nil && mapping.Quantiles != nil && len(mapping.Quantiles) > 0 {
|
||||
quantiles = mapping.Quantiles
|
||||
if mapping != nil && mapping.SummaryOptions != nil && len(mapping.SummaryOptions.Quantiles) > 0 {
|
||||
quantiles = mapping.SummaryOptions.Quantiles
|
||||
}
|
||||
summaryOptions := mapper.SummaryOptions{}
|
||||
if mapping != nil && mapping.SummaryOptions != nil {
|
||||
summaryOptions = *mapping.SummaryOptions
|
||||
}
|
||||
objectives := make(map[float64]float64)
|
||||
for _, q := range quantiles {
|
||||
|
|
Loading…
Reference in a new issue