mirror of https://github.com/prometheus/prometheus
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
359 lines
11 KiB
359 lines
11 KiB
package config |
|
|
|
import ( |
|
"fmt" |
|
"io/ioutil" |
|
"regexp" |
|
"strings" |
|
"time" |
|
|
|
"gopkg.in/yaml.v2" |
|
|
|
clientmodel "github.com/prometheus/client_golang/model" |
|
|
|
"github.com/prometheus/prometheus/utility" |
|
) |
|
|
|
var jobNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_-]*$") |
|
|
|
// Load parses the YAML input s into a Config. |
|
func Load(s string) (*Config, error) { |
|
cfg := &Config{ |
|
original: s, |
|
} |
|
err := yaml.Unmarshal([]byte(s), cfg) |
|
if err != nil { |
|
return nil, err |
|
} |
|
return cfg, nil |
|
} |
|
|
|
// LoadFromFile parses the given YAML file into a Config. |
|
func LoadFromFile(filename string) (*Config, error) { |
|
content, err := ioutil.ReadFile(filename) |
|
if err != nil { |
|
return nil, err |
|
} |
|
return Load(string(content)) |
|
} |
|
|
|
// The defaults applied before parsing the respective config sections. |
|
var ( |
|
// The default top-level configuration. |
|
DefaultConfig = DefaultedConfig{ |
|
GlobalConfig: &GlobalConfig{DefaultGlobalConfig}, |
|
} |
|
|
|
// The default global configuration. |
|
DefaultGlobalConfig = DefaultedGlobalConfig{ |
|
ScrapeInterval: Duration(10 * time.Second), |
|
ScrapeTimeout: Duration(10 * time.Second), |
|
EvaluationInterval: Duration(1 * time.Minute), |
|
} |
|
|
|
// Te default scrape configuration. |
|
DefaultScrapeConfig = DefaultedScrapeConfig{ |
|
// ScrapeTimeout and ScrapeInterval default to the |
|
// configured globals. |
|
MetricsPath: "/metrics", |
|
Scheme: "http", |
|
} |
|
|
|
// The default Relabel configuration. |
|
DefaultRelabelConfig = DefaultedRelabelConfig{ |
|
Action: RelabelReplace, |
|
Separator: ";", |
|
} |
|
|
|
// The default DNS SD configuration. |
|
DefaultDNSConfig = DefaultedDNSConfig{ |
|
RefreshInterval: Duration(30 * time.Second), |
|
} |
|
) |
|
|
|
// Config is the top-level configuration for Prometheus's config files. |
|
type Config struct { |
|
// DefaultedConfig contains the actual fields of Config. |
|
DefaultedConfig `yaml:",inline"` |
|
|
|
// original is the input from which the config was parsed. |
|
original string |
|
} |
|
|
|
func (c *Config) String() string { |
|
if c.original != "" { |
|
return c.original |
|
} |
|
b, err := yaml.Marshal(c) |
|
if err != nil { |
|
return fmt.Sprintf("<error creating config string: %s>", err) |
|
} |
|
return string(b) |
|
} |
|
|
|
// UnmarshalYAML implements the yaml.Unmarshaller interface. |
|
func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { |
|
c.DefaultedConfig = DefaultConfig |
|
if err := unmarshal(&c.DefaultedConfig); err != nil { |
|
return err |
|
} |
|
// Do global overrides and validate unique names. |
|
jobNames := map[string]struct{}{} |
|
for _, scfg := range c.ScrapeConfigs { |
|
if scfg.ScrapeInterval == 0 { |
|
scfg.ScrapeInterval = c.GlobalConfig.ScrapeInterval |
|
} |
|
if scfg.ScrapeTimeout == 0 { |
|
scfg.ScrapeTimeout = c.GlobalConfig.ScrapeTimeout |
|
} |
|
|
|
if _, ok := jobNames[scfg.JobName]; ok { |
|
return fmt.Errorf("found multiple scrape configs with job name %q", scfg.JobName) |
|
} |
|
jobNames[scfg.JobName] = struct{}{} |
|
} |
|
return nil |
|
} |
|
|
|
// DefaultedConfig is a proxy type for Config. |
|
type DefaultedConfig struct { |
|
GlobalConfig *GlobalConfig `yaml:"global_config"` |
|
RuleFiles []string `yaml:"rule_files,omitempty"` |
|
ScrapeConfigs []*ScrapeConfig `yaml:"scrape_configs,omitempty"` |
|
} |
|
|
|
// GlobalConfig configures values that used across other configuration |
|
// objects. |
|
type GlobalConfig struct { |
|
// DefaultedGlobalConfig contains the actual fields for GlobalConfig. |
|
DefaultedGlobalConfig `yaml:",inline"` |
|
} |
|
|
|
// UnmarshalYAML implements the yaml.Unmarshaller interface. |
|
func (c *GlobalConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { |
|
c.DefaultedGlobalConfig = DefaultGlobalConfig |
|
if err := unmarshal(&c.DefaultedGlobalConfig); err != nil { |
|
return err |
|
} |
|
return nil |
|
} |
|
|
|
// DefaultedGlobalConfig is a proxy type for GlobalConfig. |
|
type DefaultedGlobalConfig struct { |
|
// How frequently to scrape targets by default. |
|
ScrapeInterval Duration `yaml:"scrape_interval"` |
|
// The default timeout when scraping targets. |
|
ScrapeTimeout Duration `yaml:"scrape_timeout"` |
|
// How frequently to evaluate rules by default. |
|
EvaluationInterval Duration `yaml:"evaluation_interval"` |
|
|
|
// The labels to add to any timeseries that this Prometheus instance scrapes. |
|
Labels clientmodel.LabelSet `yaml:"labels,omitempty"` |
|
} |
|
|
|
// ScrapeConfig configures a scraping unit for Prometheus. |
|
type ScrapeConfig struct { |
|
// DefaultedScrapeConfig contains the actual fields for ScrapeConfig. |
|
DefaultedScrapeConfig `yaml:",inline"` |
|
} |
|
|
|
// UnmarshalYAML implements the yaml.Unmarshaller interface. |
|
func (c *ScrapeConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { |
|
c.DefaultedScrapeConfig = DefaultScrapeConfig |
|
err := unmarshal(&c.DefaultedScrapeConfig) |
|
if err != nil { |
|
return err |
|
} |
|
if !jobNameRE.MatchString(c.JobName) { |
|
return fmt.Errorf("%q is not a valid job name", c.JobName) |
|
} |
|
return nil |
|
} |
|
|
|
// DefaultedScrapeConfig is a proxy type for ScrapeConfig. |
|
type DefaultedScrapeConfig struct { |
|
// The job name to which the job label is set by default. |
|
JobName string `yaml:"job_name"` |
|
// How frequently to scrape the targets of this scrape config. |
|
ScrapeInterval Duration `yaml:"scrape_interval"` |
|
// The timeout for scraping targets of this config. |
|
ScrapeTimeout Duration `yaml:"scrape_timeout"` |
|
// The HTTP resource path on which to fetch metrics from targets. |
|
MetricsPath string `yaml:"metrics_path"` |
|
// The URL scheme with which to fetch metrics from targets. |
|
Scheme string `yaml:"scheme"` |
|
|
|
// List of labeled target groups for this job. |
|
TargetGroups []*TargetGroup `yaml:"target_groups,omitempty"` |
|
// List of DNS service discovery configurations. |
|
DNSConfigs []*DNSConfig `yaml:"dns_configs,omitempty"` |
|
// List of relabel configurations. |
|
RelabelConfigs []*RelabelConfig `yaml:"relabel_configs,omitempty"` |
|
} |
|
|
|
// A labeled group of targets to scrape for a job. |
|
type TargetGroup struct { |
|
// Targets is a list of targets identified by a label set. Each target is |
|
// uniquely identifiable in the group by its address label. |
|
Targets []clientmodel.LabelSet `yaml:"targets,omitempty" json:"targets,omitempty"` |
|
// Labels is a set of labels that is common across all targets in the group. |
|
Labels clientmodel.LabelSet `yaml:"labels,omitempty" json:"labels,omitempty"` |
|
|
|
// Source is an identifier that describes a group of targets. |
|
Source string `yaml:"-", json:"-"` |
|
} |
|
|
|
func (tg *TargetGroup) String() string { |
|
return tg.Source |
|
} |
|
|
|
// UnmarshalYAML implements the yaml.Unmarshaller interface. |
|
func (tg *TargetGroup) UnmarshalYAML(unmarshal func(interface{}) error) error { |
|
g := struct { |
|
Targets []string `yaml:"targets"` |
|
Labels clientmodel.LabelSet `yaml:"labels"` |
|
}{} |
|
if err := unmarshal(&g); err != nil { |
|
return err |
|
} |
|
tg.Targets = make([]clientmodel.LabelSet, 0, len(g.Targets)) |
|
for _, t := range g.Targets { |
|
if strings.Contains(t, "/") { |
|
return fmt.Errorf("%q is not a valid hostname", t) |
|
} |
|
tg.Targets = append(tg.Targets, clientmodel.LabelSet{ |
|
clientmodel.AddressLabel: clientmodel.LabelValue(t), |
|
}) |
|
} |
|
tg.Labels = g.Labels |
|
return nil |
|
} |
|
|
|
// DNSConfig is the configuration for DNS based service discovery. |
|
type DNSConfig struct { |
|
// DefaultedDNSConfig contains the actual fields for DNSConfig. |
|
DefaultedDNSConfig `yaml:",inline"` |
|
} |
|
|
|
// UnmarshalYAML implements the yaml.Unmarshaller interface. |
|
func (c *DNSConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { |
|
c.DefaultedDNSConfig = DefaultDNSConfig |
|
err := unmarshal(&c.DefaultedDNSConfig) |
|
if err != nil { |
|
return err |
|
} |
|
if len(c.Names) == 0 { |
|
return fmt.Errorf("DNS config must contain at least one SRV server name") |
|
} |
|
return nil |
|
} |
|
|
|
// DefaultedDNSConfig is a proxy type for DNSConfig. |
|
type DefaultedDNSConfig struct { |
|
Names []string `yaml:"names"` |
|
RefreshInterval Duration `yaml:"refresh_interval"` |
|
} |
|
|
|
// RelabelAction is the action to be performed on relabeling. |
|
type RelabelAction string |
|
|
|
const ( |
|
// Performs a regex replacement. |
|
RelabelReplace RelabelAction = "replace" |
|
// Drops targets for which the input does not match the regex. |
|
RelabelKeep = "keep" |
|
// Drops targets for which the input does match the regex. |
|
RelabelDrop = "drop" |
|
) |
|
|
|
// UnmarshalYAML implements the yaml.Unmarshaller interface. |
|
func (a *RelabelAction) UnmarshalYAML(unmarshal func(interface{}) error) error { |
|
var s string |
|
if err := unmarshal(&s); err != nil { |
|
return err |
|
} |
|
switch act := RelabelAction(strings.ToLower(s)); act { |
|
case RelabelReplace, RelabelKeep, RelabelDrop: |
|
*a = act |
|
return nil |
|
} |
|
return fmt.Errorf("unknown relabel action %q", s) |
|
} |
|
|
|
// RelabelConfig is the configuration for relabeling of target label sets. |
|
type RelabelConfig struct { |
|
// DefaultedRelabelConfig contains the actual fields for RelabelConfig. |
|
DefaultedRelabelConfig `yaml:",inline"` |
|
} |
|
|
|
// UnmarshalYAML implements the yaml.Unmarshaller interface. |
|
func (c *RelabelConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { |
|
c.DefaultedRelabelConfig = DefaultRelabelConfig |
|
return unmarshal(&c.DefaultedRelabelConfig) |
|
} |
|
|
|
// DefaultedRelabelConfig is a proxy type for RelabelConfig. |
|
type DefaultedRelabelConfig struct { |
|
// A list of labels from which values are taken and concatenated |
|
// with the configured separator in order. |
|
SourceLabels clientmodel.LabelNames `yaml:"source_labels,flow"` |
|
// Separator is the string between concatenated values from the source labels. |
|
Separator string `yaml:"separator"` |
|
// Regex against which the concatenation is matched. |
|
Regex *Regexp `yaml:"regex"` |
|
// The label to which the resulting string is written in a replacement. |
|
TargetLabel clientmodel.LabelName `yaml:"target_label,omitempty"` |
|
// Replacement is the regex replacement pattern to be used. |
|
Replacement string `yaml:"replacement,omitempty"` |
|
// Action is the action to be performed for the relabeling. |
|
Action RelabelAction `yaml:"action"` |
|
} |
|
|
|
// Regexp encapsulates a regexp.Regexp and makes it YAML marshallable. |
|
type Regexp struct { |
|
regexp.Regexp |
|
} |
|
|
|
// UnmarshalYAML implements the yaml.Unmarshaller interface. |
|
func (re *Regexp) UnmarshalYAML(unmarshal func(interface{}) error) error { |
|
var s string |
|
if err := unmarshal(&s); err != nil { |
|
return err |
|
} |
|
regex, err := regexp.Compile(s) |
|
if err != nil { |
|
return err |
|
} |
|
re.Regexp = *regex |
|
return nil |
|
} |
|
|
|
// MarshalYAML implements the yaml.Marshaller interface. |
|
func (re *Regexp) MarshalYAML() (interface{}, error) { |
|
return re.String(), nil |
|
} |
|
|
|
// Duration encapsulates a time.Duration and makes it YAML marshallable. |
|
// |
|
// TODO(fabxc): Since we have custom types for most things, including timestamps, |
|
// we might want to move this into our model as well, eventually. |
|
type Duration time.Duration |
|
|
|
// UnmarshalYAML implements the yaml.Unmarshaller interface. |
|
func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error { |
|
var s string |
|
if err := unmarshal(&s); err != nil { |
|
return err |
|
} |
|
dur, err := utility.StringToDuration(s) |
|
if err != nil { |
|
return err |
|
} |
|
*d = Duration(dur) |
|
return nil |
|
} |
|
|
|
// MarshalYAML implements the yaml.Marshaller interface. |
|
func (d Duration) MarshalYAML() (interface{}, error) { |
|
return utility.DurationToString(time.Duration(d)), nil |
|
}
|
|
|