mirror of
https://github.com/prometheus/statsd_exporter.git
synced 2024-09-27 13:19:59 +00:00
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"
|
provider: "$2"
|
||||||
outcome: "$3"
|
outcome: "$3"
|
||||||
job: "${1}_server"
|
job: "${1}_server"
|
||||||
quantiles:
|
summary_options:
|
||||||
- quantile: 0.99
|
quantiles:
|
||||||
error: 0.001
|
- quantile: 0.99
|
||||||
- quantile: 0.95
|
error: 0.001
|
||||||
error: 0.01
|
- quantile: 0.95
|
||||||
- quantile: 0.9
|
error: 0.01
|
||||||
error: 0.05
|
- quantile: 0.9
|
||||||
- quantile: 0.5
|
error: 0.05
|
||||||
error: 0.005
|
- quantile: 0.5
|
||||||
|
error: 0.005
|
||||||
```
|
```
|
||||||
|
|
||||||
The default quantiles are 0.99, 0.9, and 0.5.
|
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:
|
mappings:
|
||||||
- match: "test.timing.*.*.*"
|
- match: "test.timing.*.*.*"
|
||||||
timer_type: histogram
|
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"
|
name: "my_timer"
|
||||||
labels:
|
labels:
|
||||||
provider: "$2"
|
provider: "$2"
|
||||||
|
|
|
@ -57,21 +57,31 @@ type MetricMapper struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type MetricMapping struct {
|
type MetricMapping struct {
|
||||||
Match string `yaml:"match"`
|
Match string `yaml:"match"`
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
nameFormatter *fsm.TemplateFormatter
|
nameFormatter *fsm.TemplateFormatter
|
||||||
regex *regexp.Regexp
|
regex *regexp.Regexp
|
||||||
Labels prometheus.Labels `yaml:"labels"`
|
Labels prometheus.Labels `yaml:"labels"`
|
||||||
labelKeys []string
|
labelKeys []string
|
||||||
labelFormatters []*fsm.TemplateFormatter
|
labelFormatters []*fsm.TemplateFormatter
|
||||||
TimerType TimerType `yaml:"timer_type"`
|
TimerType TimerType `yaml:"timer_type"`
|
||||||
Buckets []float64 `yaml:"buckets"`
|
LegacyBuckets []float64 `yaml:"buckets"`
|
||||||
Quantiles []metricObjective `yaml:"quantiles"`
|
LegacyQuantiles []metricObjective `yaml:"quantiles"`
|
||||||
MatchType MatchType `yaml:"match_type"`
|
MatchType MatchType `yaml:"match_type"`
|
||||||
HelpText string `yaml:"help"`
|
HelpText string `yaml:"help"`
|
||||||
Action ActionType `yaml:"action"`
|
Action ActionType `yaml:"action"`
|
||||||
MatchMetricType MetricType `yaml:"match_metric_type"`
|
MatchMetricType MetricType `yaml:"match_metric_type"`
|
||||||
Ttl time.Duration `yaml:"ttl"`
|
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 {
|
type metricObjective struct {
|
||||||
|
@ -172,12 +182,60 @@ func (m *MetricMapper) InitFromYAMLString(fileContents string, cacheSize int) er
|
||||||
currentMapping.TimerType = n.Defaults.TimerType
|
currentMapping.TimerType = n.Defaults.TimerType
|
||||||
}
|
}
|
||||||
|
|
||||||
if currentMapping.Buckets == nil || len(currentMapping.Buckets) == 0 {
|
if currentMapping.LegacyQuantiles != nil &&
|
||||||
currentMapping.Buckets = n.Defaults.Buckets
|
(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 {
|
if currentMapping.LegacyBuckets != nil &&
|
||||||
currentMapping.Quantiles = n.Defaults.Quantiles
|
(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 {
|
if currentMapping.Ttl == 0 && n.Defaults.Ttl > 0 {
|
||||||
|
|
|
@ -496,6 +496,51 @@ mappings:
|
||||||
`,
|
`,
|
||||||
configBad: true,
|
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 with good metric type.
|
||||||
{
|
{
|
||||||
config: `---
|
config: `---
|
||||||
|
@ -777,15 +822,15 @@ mappings:
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(mapping.quantiles) != 0 {
|
if len(mapping.quantiles) != 0 {
|
||||||
if 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.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 {
|
for i, quantile := range mapping.quantiles {
|
||||||
if quantile.Quantile != m.Quantiles[i].Quantile {
|
if quantile.Quantile != m.SummaryOptions.Quantiles[i].Quantile {
|
||||||
t.Fatalf("%d.%q: Expected quantile %v, got %v", i, metric, m.Quantiles[i].Quantile, quantile.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 {
|
if quantile.Error != m.SummaryOptions.Quantiles[i].Error {
|
||||||
t.Fatalf("%d.%q: Expected Error margin %v, got %v", i, metric, m.Quantiles[i].Error, quantile.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 {
|
if vh == nil {
|
||||||
metricsCount.WithLabelValues("histogram").Inc()
|
metricsCount.WithLabelValues("histogram").Inc()
|
||||||
buckets := r.mapper.Defaults.Buckets
|
buckets := r.mapper.Defaults.Buckets
|
||||||
if mapping.Buckets != nil && len(mapping.Buckets) > 0 {
|
if mapping.HistogramOptions != nil && len(mapping.HistogramOptions.Buckets) > 0 {
|
||||||
buckets = mapping.Buckets
|
buckets = mapping.HistogramOptions.Buckets
|
||||||
}
|
}
|
||||||
histogramVec = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
histogramVec = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
||||||
Name: metricName,
|
Name: metricName,
|
||||||
|
@ -325,8 +325,12 @@ func (r *registry) getSummary(metricName string, labels prometheus.Labels, help
|
||||||
if vh == nil {
|
if vh == nil {
|
||||||
metricsCount.WithLabelValues("summary").Inc()
|
metricsCount.WithLabelValues("summary").Inc()
|
||||||
quantiles := r.mapper.Defaults.Quantiles
|
quantiles := r.mapper.Defaults.Quantiles
|
||||||
if mapping != nil && mapping.Quantiles != nil && len(mapping.Quantiles) > 0 {
|
if mapping != nil && mapping.SummaryOptions != nil && len(mapping.SummaryOptions.Quantiles) > 0 {
|
||||||
quantiles = mapping.Quantiles
|
quantiles = mapping.SummaryOptions.Quantiles
|
||||||
|
}
|
||||||
|
summaryOptions := mapper.SummaryOptions{}
|
||||||
|
if mapping != nil && mapping.SummaryOptions != nil {
|
||||||
|
summaryOptions = *mapping.SummaryOptions
|
||||||
}
|
}
|
||||||
objectives := make(map[float64]float64)
|
objectives := make(map[float64]float64)
|
||||||
for _, q := range quantiles {
|
for _, q := range quantiles {
|
||||||
|
|
Loading…
Reference in a new issue