The Prometheus monitoring system and time series database.
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

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
}