Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable sliding window #122

Merged
merged 5 commits into from
Aug 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ metrics:
match: '%{DATE} %{TIME} %{USER:user} %{NUMBER:val}'
value: '{{.val}}'
quantiles: {0.5: 0.05, 0.9: 0.01, 0.99: 0.001}
max_age: 10m
labels:
user: '{{.user}}'
```
Expand All @@ -594,8 +595,7 @@ The configuration is as follows:
* `type` is `summary`.
* `name`, `help`, `match`, `labels`, and `value` have the same meaning as for `gauge` metrics.
* `quantiles` is a list of quantiles to be observed. `grok_exporter` does not provide exact values for the quantiles, but only estimations. For each quantile, you also specify an uncertainty that is tolerated for the estimation. In the example, we measure the median (0.5 quantile) with uncertainty 5%, the 90% quantile with uncertainty 1%, and the 99% quantile with uncertainty 0.1%. `quantiles` is optional, the default value is `{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}`.

Summaries represent a sliding time window of 10 minutes, i.e. if you observe a 0.5 quantile (median) of _x_, the value _x_ represents the median within the last 10 minutes. The time window is moved forward every 2 minutes.
* `max_age` is a summary sliding window. By default, summaries represent a sliding time window of 10 minutes, i.e. if you observe a 0.5 quantile (median) of _x_, the value _x_ represents the median within the last 10 minutes. The time window is moved forward every 2 minutes.

Output for the example log lines above::

Expand Down
20 changes: 14 additions & 6 deletions config/v3/configV3.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ type MetricConfig struct {
Cumulative bool `yaml:",omitempty"`
Buckets []float64 `yaml:",flow,omitempty"`
Quantiles map[float64]float64 `yaml:",flow,omitempty"`
MaxAge time.Duration `yaml:"max_age,omitempty"`
Labels map[string]string `yaml:",omitempty"`
LabelTemplates []template.Template `yaml:"-"` // parsed version of Labels, will not be serialized to yaml.
ValueTemplate template.Template `yaml:"-"` // parsed version of Value, will not be serialized to yaml.
Expand All @@ -147,6 +148,7 @@ type DefaultConfig struct {
Retention time.Duration `yaml:",omitempty"` // implicitly parsed with time.ParseDuration()
Buckets []float64 `yaml:",flow,omitempty"`
Quantiles map[float64]float64 `yaml:",flow,omitempty"`
MaxAge time.Duration `yaml:"max_age,omitempty"`
Labels map[string]string `yaml:",omitempty"`
}

Expand Down Expand Up @@ -211,6 +213,9 @@ func applyImportDefaults(metricConfig *MetricConfig, defaults DefaultConfig) {
if metricConfig.Type == "summary" && len(metricConfig.Quantiles) == 0 {
metricConfig.Quantiles = defaults.Quantiles
}
if metricConfig.Type == "summary" && metricConfig.MaxAge == 0 {
metricConfig.MaxAge = defaults.MaxAge
}
if metricConfig.Type == "histogram" && len(metricConfig.Buckets) == 0 {
metricConfig.Buckets = defaults.Buckets
}
Expand Down Expand Up @@ -416,6 +421,7 @@ func (c ImportConfig) validate() error {
{"retention", c.Defaults.Retention != 0},
{"buckets", len(c.Defaults.Buckets) > 0},
{"quantiles", len(c.Defaults.Quantiles) > 0},
{"max_age", c.Defaults.MaxAge != 0},
{"labels", len(c.Defaults.Labels) > 0},
} {
if field.present {
Expand Down Expand Up @@ -496,16 +502,16 @@ func (c *MetricConfig) validate() error {
if err != nil {
return err
}
var cumulativeAllowed, bucketsAllowed, quantilesAllowed bool
var cumulativeAllowed, bucketsAllowed, quantilesAllowed, maxAgeAllowed bool
switch c.Type {
case "counter":
cumulativeAllowed, bucketsAllowed, quantilesAllowed = false, false, false
cumulativeAllowed, bucketsAllowed, quantilesAllowed, maxAgeAllowed = false, false, false, false
case "gauge":
cumulativeAllowed, bucketsAllowed, quantilesAllowed = true, false, false
cumulativeAllowed, bucketsAllowed, quantilesAllowed, maxAgeAllowed = true, false, false, false
case "histogram":
cumulativeAllowed, bucketsAllowed, quantilesAllowed = false, true, false
cumulativeAllowed, bucketsAllowed, quantilesAllowed, maxAgeAllowed = false, true, false, false
case "summary":
cumulativeAllowed, bucketsAllowed, quantilesAllowed = false, false, true
cumulativeAllowed, bucketsAllowed, quantilesAllowed, maxAgeAllowed = false, false, true, true
default:
return fmt.Errorf("Invalid 'metrics.type': '%v'. We currently only support 'counter' and 'gauge'.", c.Type)
}
Expand All @@ -517,7 +523,9 @@ func (c *MetricConfig) validate() error {
case !bucketsAllowed && len(c.Buckets) > 0:
return fmt.Errorf("Invalid metric configuration: 'metrics.buckets' cannot be used for %v metrics.", c.Type)
case !quantilesAllowed && len(c.Quantiles) > 0:
return fmt.Errorf("Invalid metric configuration: 'metrics.buckets' cannot be used for %v metrics.", c.Type)
return fmt.Errorf("Invalid metric configuration: 'metrics.quantiles' cannot be used for %v metrics.", c.Type)
case !maxAgeAllowed && c.MaxAge != 0:
return fmt.Errorf("Invalid metric configuration: 'metrics.max_age' cannot be used for %v metrics.", c.Type)
}
if len(c.DeleteMatch) > 0 && len(c.Labels) == 0 {
return fmt.Errorf("Invalid metric configuration: 'metrics.delete_match' is only supported for metrics with labels.")
Expand Down
3 changes: 3 additions & 0 deletions exporter/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,9 @@ func NewSummaryMetric(cfg *configuration.MetricConfig, regex *oniguruma.Regex, d
if len(cfg.Quantiles) > 0 {
summaryOpts.Objectives = cfg.Quantiles
}
if cfg.MaxAge != 0 {
summaryOpts.MaxAge = cfg.MaxAge
}
if len(cfg.Labels) == 0 {
return &summaryMetric{
observeMetric: newObserveMetric(cfg, regex, deleteRegex),
Expand Down