mirror of
https://github.com/prometheus/statsd_exporter.git
synced 2024-12-25 23:10:29 +00:00
allow setting granularity for summary metrics
The Go client for prometheus aggregates summary metrics over 10 minutes by default, in 5 buckets. This is not always the behaviour we want. Allow tweaking those settings in `statsd_exporter`, so we can aggregate summary metrics over more or less time, with more or fewer buckets, and set the cap for the bucket as well. Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
This commit is contained in:
parent
80b77513a6
commit
dae5d782a6
4 changed files with 63 additions and 6 deletions
12
README.md
12
README.md
|
@ -236,7 +236,8 @@ mappings:
|
|||
|
||||
By default, statsd timers are represented as a Prometheus summary with
|
||||
quantiles. You may optionally configure the [quantiles and acceptable
|
||||
error](https://prometheus.io/docs/practices/histograms/#quantiles):
|
||||
error](https://prometheus.io/docs/practices/histograms/#quantiles), as
|
||||
well as adjusting how the summary metric is aggregated:
|
||||
|
||||
```yaml
|
||||
mappings:
|
||||
|
@ -257,10 +258,19 @@ mappings:
|
|||
error: 0.05
|
||||
- quantile: 0.5
|
||||
error: 0.005
|
||||
max_summary_age: 30s
|
||||
summary_age_buckets: 3
|
||||
stream_buffer_size: 1000
|
||||
```
|
||||
|
||||
The default quantiles are 0.99, 0.9, and 0.5.
|
||||
|
||||
The default summary age is 10 minutes, the default number of buckets
|
||||
is 5 and the default buffer size is 500. See also the
|
||||
[`golang_client` docs](https://godoc.org/github.com/prometheus/client_golang/prometheus#SummaryOpts).
|
||||
The `max_summary_age` corresponds to `SummaryOptions.MaxAge`, `summary_age_buckets`
|
||||
to `SummaryOptions.AgeBuckets` and `stream_buffer_size` to `SummaryOptions.BufCap`.
|
||||
|
||||
In the configuration, one may also set the timer type to "histogram". The
|
||||
default is "summary" as in the plain text configuration format. For example,
|
||||
to set the timer type for a single metric:
|
||||
|
|
|
@ -77,7 +77,10 @@ type MetricMapping struct {
|
|||
}
|
||||
|
||||
type SummaryOptions struct {
|
||||
Quantiles []metricObjective `yaml:"quantiles"`
|
||||
Quantiles []metricObjective `yaml:"quantiles"`
|
||||
MaxAge time.Duration `yaml:"max_age"`
|
||||
AgeBuckets uint32 `yaml:"age_buckets"`
|
||||
BufCap uint32 `yaml:"buf_cap"`
|
||||
}
|
||||
|
||||
type HistogramOptions struct {
|
||||
|
@ -226,10 +229,6 @@ func (m *MetricMapper) InitFromYAMLString(fileContents string, cacheSize int) er
|
|||
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
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ type mappings []struct {
|
|||
notPresent bool
|
||||
ttl time.Duration
|
||||
metricType MetricType
|
||||
maxAge time.Duration
|
||||
ageBuckets uint32
|
||||
bufCap uint32
|
||||
}
|
||||
|
||||
func TestMetricMapperYAML(t *testing.T) {
|
||||
|
@ -523,6 +526,39 @@ mappings:
|
|||
},
|
||||
},
|
||||
},
|
||||
// Config with summary configuration.
|
||||
{
|
||||
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
|
||||
max_age: 5m
|
||||
age_buckets: 2
|
||||
buf_cap: 1000
|
||||
`,
|
||||
mappings: mappings{
|
||||
{
|
||||
statsdMetric: "test.*.*",
|
||||
name: "foo",
|
||||
labels: map[string]string{},
|
||||
quantiles: []metricObjective{
|
||||
{Quantile: 0.42, Error: 0.04},
|
||||
{Quantile: 0.7, Error: 0.002},
|
||||
},
|
||||
maxAge: 5 * time.Minute,
|
||||
ageBuckets: 2,
|
||||
bufCap: 1000,
|
||||
},
|
||||
},
|
||||
},
|
||||
// duplicate quantiles are bad
|
||||
{
|
||||
config: `---
|
||||
|
@ -834,6 +870,15 @@ mappings:
|
|||
}
|
||||
}
|
||||
}
|
||||
if mapping.maxAge != 0 && mapping.maxAge != m.SummaryOptions.MaxAge {
|
||||
t.Fatalf("%d.%q: Expected max age %v, got %v", i, metric, mapping.maxAge, m.SummaryOptions.MaxAge)
|
||||
}
|
||||
if mapping.ageBuckets != 0 && mapping.ageBuckets != m.SummaryOptions.AgeBuckets {
|
||||
t.Fatalf("%d.%q: Expected max age %v, got %v", i, metric, mapping.ageBuckets, m.SummaryOptions.AgeBuckets)
|
||||
}
|
||||
if mapping.bufCap != 0 && mapping.bufCap != m.SummaryOptions.BufCap {
|
||||
t.Fatalf("%d.%q: Expected max age %v, got %v", i, metric, mapping.bufCap, m.SummaryOptions.BufCap)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -344,6 +344,9 @@ func (r *registry) getSummary(metricName string, labels prometheus.Labels, help
|
|||
Name: metricName,
|
||||
Help: help,
|
||||
Objectives: objectives,
|
||||
MaxAge: summaryOptions.MaxAge,
|
||||
AgeBuckets: summaryOptions.AgeBuckets,
|
||||
BufCap: summaryOptions.BufCap,
|
||||
}, labelNames)
|
||||
|
||||
if err := prometheus.Register(uncheckedCollector{summaryVec}); err != nil {
|
||||
|
|
Loading…
Reference in a new issue