diff --git a/config/config.go b/config/config.go index eddd44087..46fbc9e75 100644 --- a/config/config.go +++ b/config/config.go @@ -147,6 +147,12 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { if err := unmarshal((*plain)(c)); err != nil { return err } + // If a global block was open but empty the default global config is overwritten. + // We have to restore it here. + if c.GlobalConfig.isZero() { + c.GlobalConfig = DefaultGlobalConfig + } + for _, rf := range c.RuleFiles { if !patRulePath.MatchString(rf) { return fmt.Errorf("invalid rule file path %q", rf) @@ -196,6 +202,14 @@ func (c *GlobalConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { return checkOverflow(c.XXX, "global config") } +// isZero returns true iff the global config is the zero value. +func (c *GlobalConfig) isZero() bool { + return c.Labels == nil && + c.ScrapeInterval == 0 && + c.ScrapeTimeout == 0 && + c.EvaluationInterval == 0 +} + // ScrapeConfig configures a scraping unit for Prometheus. type ScrapeConfig struct { // The job name to which the job label is set by default. diff --git a/config/config_test.go b/config/config_test.go index d7aab0b48..844aef8cd 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -261,3 +261,16 @@ func TestEmptyConfig(t *testing.T) { t.Fatalf("want %v, got %v", exp, c) } } + +func TestEmptyGlobalBlock(t *testing.T) { + c, err := Load("global:\n") + if err != nil { + t.Fatalf("Unexpected error parsing empty config file: %s", err) + } + exp := DefaultConfig + exp.original = "global:\n" + + if !reflect.DeepEqual(*c, exp) { + t.Fatalf("want %v, got %v", exp, c) + } +}