lib/promscrape: follow-up after baa1c24b36

This commit is contained in:
Aliaksandr Valialkin 2022-04-16 14:25:54 +03:00
parent baa1c24b36
commit ebaa1c7ad5
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
6 changed files with 97 additions and 35 deletions

View file

@ -25,10 +25,10 @@ import (
type Group struct { type Group struct {
Type datasource.Type `yaml:"type,omitempty"` Type datasource.Type `yaml:"type,omitempty"`
File string File string
Name string `yaml:"name"` Name string `yaml:"name"`
Interval promutils.Duration `yaml:"interval"` Interval *promutils.Duration `yaml:"interval,omitempty"`
Rules []Rule `yaml:"rules"` Rules []Rule `yaml:"rules"`
Concurrency int `yaml:"concurrency"` Concurrency int `yaml:"concurrency"`
// ExtraFilterLabels is a list label filters applied to every rule // ExtraFilterLabels is a list label filters applied to every rule
// request withing a group. Is compatible only with VM datasources. // request withing a group. Is compatible only with VM datasources.
// See https://docs.victoriametrics.com#prometheus-querying-api-enhancements // See https://docs.victoriametrics.com#prometheus-querying-api-enhancements
@ -127,12 +127,12 @@ func (g *Group) Validate(validateAnnotations, validateExpressions bool) error {
// recording rule or alerting rule. // recording rule or alerting rule.
type Rule struct { type Rule struct {
ID uint64 ID uint64
Record string `yaml:"record,omitempty"` Record string `yaml:"record,omitempty"`
Alert string `yaml:"alert,omitempty"` Alert string `yaml:"alert,omitempty"`
Expr string `yaml:"expr"` Expr string `yaml:"expr"`
For promutils.Duration `yaml:"for"` For *promutils.Duration `yaml:"for,omitempty"`
Labels map[string]string `yaml:"labels,omitempty"` Labels map[string]string `yaml:"labels,omitempty"`
Annotations map[string]string `yaml:"annotations,omitempty"` Annotations map[string]string `yaml:"annotations,omitempty"`
// Catches all undefined fields and must be empty after parsing. // Catches all undefined fields and must be empty after parsing.
XXX map[string]interface{} `yaml:",inline"` XXX map[string]interface{} `yaml:",inline"`

View file

@ -44,7 +44,7 @@ type Config struct {
// AlertRelabelConfigs contains list of relabeling rules alert labels // AlertRelabelConfigs contains list of relabeling rules alert labels
AlertRelabelConfigs []promrelabel.RelabelConfig `yaml:"alert_relabel_configs,omitempty"` AlertRelabelConfigs []promrelabel.RelabelConfig `yaml:"alert_relabel_configs,omitempty"`
// The timeout used when sending alerts. // The timeout used when sending alerts.
Timeout promutils.Duration `yaml:"timeout,omitempty"` Timeout *promutils.Duration `yaml:"timeout,omitempty"`
// Checksum stores the hash of yaml definition for the config. // Checksum stores the hash of yaml definition for the config.
// May be used to detect any changes to the config file. // May be used to detect any changes to the config file.

View file

@ -18,6 +18,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
* FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert.html): add support for DNS-based discovery for notifiers in the same way as Prometheus does. See [these docs](https://docs.victoriametrics.com/vmalert.html#notifier-configuration-file) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2460). * FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert.html): add support for DNS-based discovery for notifiers in the same way as Prometheus does. See [these docs](https://docs.victoriametrics.com/vmalert.html#notifier-configuration-file) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2460).
* BUGFIX: [vmctl](https://docs.victoriametrics.com/vmctl.html): return non-zero exit code on error. This allows handling `vmctl` errors in shell scripts. Previously `vmctl` was returning 0 exit code on error. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2322). * BUGFIX: [vmctl](https://docs.victoriametrics.com/vmctl.html): return non-zero exit code on error. This allows handling `vmctl` errors in shell scripts. Previously `vmctl` was returning 0 exit code on error. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2322).
* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): properly show `scrape_timeout` and `scrape_interval` options at `http://vmagent:8429/config` page. Previously these options weren't displayed even if they were set in `-promscrape.config`.
## [v1.76.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.76.1) ## [v1.76.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.76.1)

View file

@ -83,6 +83,19 @@ type Config struct {
baseDir string baseDir string
} }
func (cfg *Config) unmarshal(data []byte, isStrict bool) error {
data = envtemplate.Replace(data)
var err error
if isStrict {
if err = yaml.UnmarshalStrict(data, cfg); err != nil {
err = fmt.Errorf("%w; pass -promscrape.config.strictParse=false command-line flag for ignoring unknown fields in yaml config", err)
}
} else {
err = yaml.Unmarshal(data, cfg)
}
return err
}
func (cfg *Config) marshal() []byte { func (cfg *Config) marshal() []byte {
data, err := yaml.Marshal(cfg) data, err := yaml.Marshal(cfg)
if err != nil { if err != nil {
@ -124,9 +137,9 @@ func (cfg *Config) getJobNames() []string {
// //
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/ // See https://prometheus.io/docs/prometheus/latest/configuration/configuration/
type GlobalConfig struct { type GlobalConfig struct {
ScrapeInterval promutils.Duration `yaml:"scrape_interval,omitempty"` ScrapeInterval *promutils.Duration `yaml:"scrape_interval,omitempty"`
ScrapeTimeout promutils.Duration `yaml:"scrape_timeout,omitempty"` ScrapeTimeout *promutils.Duration `yaml:"scrape_timeout,omitempty"`
ExternalLabels map[string]string `yaml:"external_labels,omitempty"` ExternalLabels map[string]string `yaml:"external_labels,omitempty"`
} }
// ScrapeConfig represents essential parts for `scrape_config` section of Prometheus config. // ScrapeConfig represents essential parts for `scrape_config` section of Prometheus config.
@ -134,8 +147,8 @@ type GlobalConfig struct {
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config // See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config
type ScrapeConfig struct { type ScrapeConfig struct {
JobName string `yaml:"job_name"` JobName string `yaml:"job_name"`
ScrapeInterval promutils.Duration `yaml:"scrape_interval"` ScrapeInterval *promutils.Duration `yaml:"scrape_interval,omitempty"`
ScrapeTimeout promutils.Duration `yaml:"scrape_timeout"` ScrapeTimeout *promutils.Duration `yaml:"scrape_timeout,omitempty"`
MetricsPath string `yaml:"metrics_path,omitempty"` MetricsPath string `yaml:"metrics_path,omitempty"`
HonorLabels bool `yaml:"honor_labels,omitempty"` HonorLabels bool `yaml:"honor_labels,omitempty"`
HonorTimestamps *bool `yaml:"honor_timestamps,omitempty"` HonorTimestamps *bool `yaml:"honor_timestamps,omitempty"`
@ -168,8 +181,8 @@ type ScrapeConfig struct {
DisableCompression bool `yaml:"disable_compression,omitempty"` DisableCompression bool `yaml:"disable_compression,omitempty"`
DisableKeepAlive bool `yaml:"disable_keepalive,omitempty"` DisableKeepAlive bool `yaml:"disable_keepalive,omitempty"`
StreamParse bool `yaml:"stream_parse,omitempty"` StreamParse bool `yaml:"stream_parse,omitempty"`
ScrapeAlignInterval promutils.Duration `yaml:"scrape_align_interval"` ScrapeAlignInterval *promutils.Duration `yaml:"scrape_align_interval,omitempty"`
ScrapeOffset promutils.Duration `yaml:"scrape_offset"` ScrapeOffset *promutils.Duration `yaml:"scrape_offset,omitempty"`
SeriesLimit int `yaml:"series_limit,omitempty"` SeriesLimit int `yaml:"series_limit,omitempty"`
ProxyClientConfig promauth.ProxyClientConfig `yaml:",inline"` ProxyClientConfig promauth.ProxyClientConfig `yaml:",inline"`
@ -309,7 +322,7 @@ func IsDryRun() bool {
} }
func (cfg *Config) parseData(data []byte, path string) ([]byte, error) { func (cfg *Config) parseData(data []byte, path string) ([]byte, error) {
if err := unmarshalMaybeStrict(data, cfg); err != nil { if err := cfg.unmarshal(data, *strictParse); err != nil {
return nil, fmt.Errorf("cannot unmarshal data: %w", err) return nil, fmt.Errorf("cannot unmarshal data: %w", err)
} }
absPath, err := filepath.Abs(path) absPath, err := filepath.Abs(path)
@ -349,19 +362,6 @@ func (cfg *Config) parseData(data []byte, path string) ([]byte, error) {
return dataNew, nil return dataNew, nil
} }
func unmarshalMaybeStrict(data []byte, dst interface{}) error {
data = envtemplate.Replace(data)
var err error
if *strictParse {
if err = yaml.UnmarshalStrict(data, dst); err != nil {
err = fmt.Errorf("%w; pass -promscrape.config.strictParse=false command-line flag for ignoring unknown fields in yaml config", err)
}
} else {
err = yaml.Unmarshal(data, dst)
}
return err
}
func getSWSByJob(sws []*ScrapeWork) map[string][]*ScrapeWork { func getSWSByJob(sws []*ScrapeWork) map[string][]*ScrapeWork {
m := make(map[string][]*ScrapeWork) m := make(map[string][]*ScrapeWork)
for _, sw := range sws { for _, sw := range sws {

View file

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"reflect" "reflect"
"strconv" "strconv"
"strings"
"testing" "testing"
"time" "time"
@ -13,6 +14,63 @@ import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/proxy" "github.com/VictoriaMetrics/VictoriaMetrics/lib/proxy"
) )
func TestScrapeConfigUnmarshalMarshal(t *testing.T) {
f := func(data string) {
t.Helper()
var cfg Config
data = strings.TrimSpace(data)
if err := cfg.unmarshal([]byte(data), true); err != nil {
t.Fatalf("parse error: %s\ndata:\n%s", err, data)
}
resultData := string(cfg.marshal())
result := strings.TrimSpace(resultData)
if result != data {
t.Fatalf("unexpected marshaled config:\ngot\n%s\nwant\n%s", result, data)
}
}
f(`
global:
scrape_interval: 10s
`)
f(`
scrape_config_files:
- foo
- bar
`)
f(`
scrape_configs:
- job_name: foo
scrape_timeout: 1.5s
static_configs:
- targets:
- foo
- bar
labels:
foo: bar
`)
f(`
scrape_configs:
- job_name: foo
honor_labels: true
honor_timestamps: false
scheme: https
params:
foo:
- x
authorization:
type: foobar
relabel_configs:
- source_labels: [abc]
static_configs:
- targets:
- foo
relabel_debug: true
scrape_align_interval: 1h30m0s
proxy_bearer_token_file: file.txt
`)
}
func TestNeedSkipScrapeWork(t *testing.T) { func TestNeedSkipScrapeWork(t *testing.T) {
f := func(key string, membersCount, replicationFactor, memberNum int, needSkipExpected bool) { f := func(key string, membersCount, replicationFactor, memberNum int, needSkipExpected bool) {
t.Helper() t.Helper()

View file

@ -12,8 +12,8 @@ type Duration struct {
} }
// NewDuration returns Duration for given d. // NewDuration returns Duration for given d.
func NewDuration(d time.Duration) Duration { func NewDuration(d time.Duration) *Duration {
return Duration{ return &Duration{
d: d, d: d,
} }
} }
@ -38,7 +38,10 @@ func (pd *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error {
} }
// Duration returns duration for pd. // Duration returns duration for pd.
func (pd Duration) Duration() time.Duration { func (pd *Duration) Duration() time.Duration {
if pd == nil {
return 0
}
return pd.d return pd.d
} }