mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-27 14:39:40 -08:00
Merge pull request #209 from prometheus/refactor/protobuf-config
Convert the Prometheus configuration to protocol buffers.
This commit is contained in:
commit
30f0239f96
10
Makefile
10
Makefile
|
@ -39,11 +39,12 @@ advice:
|
||||||
binary: build
|
binary: build
|
||||||
go build $(BUILDFLAGS) -o prometheus.build
|
go build $(BUILDFLAGS) -o prometheus.build
|
||||||
|
|
||||||
build: preparation model web
|
build: preparation config model web
|
||||||
go build $(BUILDFLAGS) .
|
go build $(BUILDFLAGS) .
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C build clean
|
$(MAKE) -C build clean
|
||||||
|
$(MAKE) -C config clean
|
||||||
$(MAKE) -C model clean
|
$(MAKE) -C model clean
|
||||||
$(MAKE) -C web clean
|
$(MAKE) -C web clean
|
||||||
rm -rf $(TEST_ARTIFACTS)
|
rm -rf $(TEST_ARTIFACTS)
|
||||||
|
@ -51,6 +52,9 @@ clean:
|
||||||
-find . -type f -iname '*#' -exec rm '{}' ';'
|
-find . -type f -iname '*#' -exec rm '{}' ';'
|
||||||
-find . -type f -iname '.#*' -exec rm '{}' ';'
|
-find . -type f -iname '.#*' -exec rm '{}' ';'
|
||||||
|
|
||||||
|
config: preparation
|
||||||
|
$(MAKE) -C config
|
||||||
|
|
||||||
documentation: search_index
|
documentation: search_index
|
||||||
godoc -http=:6060 -index -index_files='search_index'
|
godoc -http=:6060 -index -index_files='search_index'
|
||||||
|
|
||||||
|
@ -90,7 +94,7 @@ test: build
|
||||||
go test ./utility/... $(GO_TEST_FLAGS)
|
go test ./utility/... $(GO_TEST_FLAGS)
|
||||||
go test ./web/... $(GO_TEST_FLAGS)
|
go test ./web/... $(GO_TEST_FLAGS)
|
||||||
|
|
||||||
web: preparation model
|
web: preparation config model
|
||||||
$(MAKE) -C web
|
$(MAKE) -C web
|
||||||
|
|
||||||
.PHONY: advice binary build clean documentation format model package preparation run search_index source_path test
|
.PHONY: advice binary build clean config documentation format model package preparation run search_index source_path test
|
||||||
|
|
|
@ -24,7 +24,7 @@ import (
|
||||||
// runtime state. It enables simpler passing of this state to components that
|
// runtime state. It enables simpler passing of this state to components that
|
||||||
// require it.
|
// require it.
|
||||||
type ApplicationState struct {
|
type ApplicationState struct {
|
||||||
Config *config.Config
|
Config config.Config
|
||||||
RuleManager rules.RuleManager
|
RuleManager rules.RuleManager
|
||||||
Storage metric.Storage
|
Storage metric.Storage
|
||||||
TargetManager retrieval.TargetManager
|
TargetManager retrieval.TargetManager
|
||||||
|
|
|
@ -11,13 +11,22 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
all: parser.y.go lexer.l.go
|
all: generated
|
||||||
|
|
||||||
parser.y.go: parser.y
|
SUFFIXES:
|
||||||
go tool yacc -o parser.y.go -v "" parser.y
|
|
||||||
|
|
||||||
lexer.l.go: parser.y.go lexer.l
|
MAKE_ARTIFACTS = generated-stamp
|
||||||
golex lexer.l
|
|
||||||
|
include ../Makefile.INCLUDE
|
||||||
|
|
||||||
|
generated: generated-stamp
|
||||||
|
|
||||||
|
generated-stamp: config.proto
|
||||||
|
protoc --proto_path=$(PREFIX)/include:. --go_out=generated/ config.proto
|
||||||
|
touch $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm lexer.l.go parser.y.go
|
rm -rf generated/*
|
||||||
|
-rm -f $(MAKE_ARTIFACTS)
|
||||||
|
|
||||||
|
.PHONY: generated
|
||||||
|
|
159
config/config.go
159
config/config.go
|
@ -14,114 +14,119 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"code.google.com/p/goprotobuf/proto"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/prometheus/prometheus/model"
|
pb "github.com/prometheus/prometheus/config/generated"
|
||||||
"github.com/prometheus/prometheus/utility"
|
"github.com/prometheus/prometheus/utility"
|
||||||
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var jobNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_-]*$")
|
||||||
|
var labelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")
|
||||||
|
|
||||||
|
// Config encapsulates the configuration of a Prometheus instance. It wraps the
|
||||||
|
// raw configuration protocol buffer to be able to add custom methods to it.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Global *GlobalConfig
|
// The protobuf containing the actual configuration values.
|
||||||
Jobs []JobConfig
|
pb.PrometheusConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
type GlobalConfig struct {
|
// String returns an ASCII serialization of the loaded configuration protobuf.
|
||||||
ScrapeInterval time.Duration
|
func (c Config) String() string {
|
||||||
EvaluationInterval time.Duration
|
return proto.MarshalTextString(&c.PrometheusConfig)
|
||||||
Labels model.LabelSet
|
|
||||||
RuleFiles []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type JobConfig struct {
|
// validateLabels validates whether label names have the correct format.
|
||||||
Name string
|
func (c Config) validateLabels(labels *pb.LabelPairs) error {
|
||||||
ScrapeInterval time.Duration
|
if labels == nil {
|
||||||
Targets []Targets
|
return nil
|
||||||
}
|
|
||||||
|
|
||||||
type Targets struct {
|
|
||||||
Endpoints []string
|
|
||||||
Labels model.LabelSet
|
|
||||||
}
|
|
||||||
|
|
||||||
func New() *Config {
|
|
||||||
return &Config{
|
|
||||||
Global: &GlobalConfig{Labels: model.LabelSet{}},
|
|
||||||
}
|
}
|
||||||
}
|
for _, label := range labels.Label {
|
||||||
|
if !labelNameRE.MatchString(label.GetName()) {
|
||||||
func (config *Config) AddJob(options map[string]string, targets []Targets) error {
|
return fmt.Errorf("Invalid label name '%s'", label.GetName())
|
||||||
name, ok := options["name"]
|
|
||||||
if !ok {
|
|
||||||
return errors.New("Missing job name")
|
|
||||||
}
|
|
||||||
if len(targets) == 0 {
|
|
||||||
return fmt.Errorf("No targets configured for job '%v'", name)
|
|
||||||
}
|
|
||||||
job := JobConfig{
|
|
||||||
Targets: tmpJobTargets,
|
|
||||||
}
|
|
||||||
for option, value := range options {
|
|
||||||
if err := job.SetOption(option, value); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config.Jobs = append(config.Jobs, job)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *Config) GetJobByName(name string) (jobConfig *JobConfig) {
|
// Validate checks an entire parsed Config for the validity of its fields.
|
||||||
for _, job := range config.Jobs {
|
func (c Config) Validate() error {
|
||||||
if job.Name == name {
|
// Check the global configuration section for validity.
|
||||||
jobConfig = &job
|
global := c.Global
|
||||||
|
if _, err := utility.StringToDuration(global.GetScrapeInterval()); err != nil {
|
||||||
|
return fmt.Errorf("Invalid global scrape interval: %s", err)
|
||||||
|
}
|
||||||
|
if _, err := utility.StringToDuration(global.GetEvaluationInterval()); err != nil {
|
||||||
|
return fmt.Errorf("Invalid rule evaluation interval: %s", err)
|
||||||
|
}
|
||||||
|
if err := c.validateLabels(global.Labels); err != nil {
|
||||||
|
return fmt.Errorf("Invalid global labels: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check each job configuration for validity.
|
||||||
|
for _, job := range c.Job {
|
||||||
|
if !jobNameRE.MatchString(job.GetName()) {
|
||||||
|
return fmt.Errorf("Invalid job name '%s'", job.GetName())
|
||||||
|
}
|
||||||
|
if _, err := utility.StringToDuration(job.GetScrapeInterval()); err != nil {
|
||||||
|
return fmt.Errorf("Invalid scrape interval for job '%s': %s", job.GetName(), err)
|
||||||
|
}
|
||||||
|
for _, targetGroup := range job.TargetGroup {
|
||||||
|
if err := c.validateLabels(targetGroup.Labels); err != nil {
|
||||||
|
return fmt.Errorf("Invalid labels for job '%s': %s", job.GetName(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetJobByName finds a job by its name in a Config object.
|
||||||
|
func (c Config) GetJobByName(name string) (jobConfig *JobConfig) {
|
||||||
|
for _, job := range c.Job {
|
||||||
|
if job.GetName() == name {
|
||||||
|
jobConfig = &JobConfig{*job}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *GlobalConfig) SetOption(option string, value string) (err error) {
|
// Jobs returns all the jobs in a Config object.
|
||||||
switch option {
|
func (c Config) Jobs() (jobs []JobConfig) {
|
||||||
case "scrape_interval":
|
for _, job := range c.Job {
|
||||||
config.ScrapeInterval, err = utility.StringToDuration(value)
|
jobs = append(jobs, JobConfig{*job})
|
||||||
return nil
|
|
||||||
case "evaluation_interval":
|
|
||||||
config.EvaluationInterval, err = utility.StringToDuration(value)
|
|
||||||
return err
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("Unrecognized global configuration option '%v'", option)
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *GlobalConfig) SetLabels(labels model.LabelSet) {
|
// stringToDuration converts a string to a duration and dies on invalid format.
|
||||||
for k, v := range labels {
|
func stringToDuration(intervalStr string) time.Duration {
|
||||||
config.Labels[k] = v
|
duration, err := utility.StringToDuration(intervalStr)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
}
|
}
|
||||||
|
return duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *GlobalConfig) AddRuleFiles(ruleFiles []string) {
|
// ScrapeInterval gets the default scrape interval for a Config.
|
||||||
for _, ruleFile := range ruleFiles {
|
func (c Config) ScrapeInterval() time.Duration {
|
||||||
config.RuleFiles = append(config.RuleFiles, ruleFile)
|
return stringToDuration(c.Global.GetScrapeInterval())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (job *JobConfig) SetOption(option string, value string) (err error) {
|
// EvaluationInterval gets the default evaluation interval for a Config.
|
||||||
switch option {
|
func (c Config) EvaluationInterval() time.Duration {
|
||||||
case "name":
|
return stringToDuration(c.Global.GetEvaluationInterval())
|
||||||
job.Name = value
|
|
||||||
case "scrape_interval":
|
|
||||||
job.ScrapeInterval, err = utility.StringToDuration(value)
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("Unrecognized job configuration option '%v'", option)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (job *JobConfig) AddTargets(endpoints []string, labels model.LabelSet) {
|
// JobConfig encapsulates the configuration of a single job. It wraps the raw
|
||||||
targets := Targets{
|
// job protocol buffer to be able to add custom methods to it.
|
||||||
Endpoints: endpoints,
|
type JobConfig struct {
|
||||||
Labels: labels,
|
pb.JobConfig
|
||||||
}
|
}
|
||||||
job.Targets = append(job.Targets, targets)
|
|
||||||
|
// EvaluationInterval gets the scrape interval for a job.
|
||||||
|
func (c JobConfig) ScrapeInterval() time.Duration {
|
||||||
|
return stringToDuration(c.GetScrapeInterval())
|
||||||
}
|
}
|
||||||
|
|
70
config/config.proto
Normal file
70
config/config.proto
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright 2013 Prometheus Team
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package io.prometheus;
|
||||||
|
|
||||||
|
// A label/value pair suitable for attaching to timeseries.
|
||||||
|
message LabelPair {
|
||||||
|
// The name of the label. Must adhere to the regex "[a-zA-Z_][a-zA-Z0-9_]*".
|
||||||
|
optional string name = 1;
|
||||||
|
// The value of the label. May contain any characters.
|
||||||
|
optional string value = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A set of label/value pairs.
|
||||||
|
message LabelPairs {
|
||||||
|
repeated LabelPair label = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The global Prometheus configuration section.
|
||||||
|
message GlobalConfig {
|
||||||
|
// How frequently to scrape targets by default. Must be a valid Prometheus
|
||||||
|
// duration string in the form "[0-9]+[smhdwy]".
|
||||||
|
optional string scrape_interval = 1 [default = "1m"];
|
||||||
|
// How frequently to evaluate rules by default. Must be a valid Prometheus
|
||||||
|
// duration string in the form "[0-9]+[smhdwy]".
|
||||||
|
optional string evaluation_interval = 2 [default = "1m"];
|
||||||
|
// The labels to add to any timeseries that this Prometheus instance scrapes.
|
||||||
|
optional LabelPairs labels = 3;
|
||||||
|
// The list of file names of rule files to load.
|
||||||
|
repeated string rule_file = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A labeled group of targets to scrape for a job.
|
||||||
|
message TargetGroup {
|
||||||
|
// The list of endpoints to scrape via HTTP.
|
||||||
|
repeated string target = 1;
|
||||||
|
// The labels to add to any timeseries scraped for this target group.
|
||||||
|
optional LabelPairs labels = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The configuration for a Prometheus job to scrape.
|
||||||
|
message JobConfig {
|
||||||
|
// The job name. Must adhere to the regex "[a-zA-Z_][a-zA-Z0-9_-]*".
|
||||||
|
required string name = 1;
|
||||||
|
// How frequently to scrape targets from this job. Overrides the global
|
||||||
|
// default.
|
||||||
|
optional string scrape_interval = 2;
|
||||||
|
// List of labeled target groups for this job.
|
||||||
|
repeated TargetGroup target_group = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The top-level Prometheus configuration.
|
||||||
|
message PrometheusConfig {
|
||||||
|
// Global Prometheus configuration options. If omitted, an empty global
|
||||||
|
// configuration with default values (see GlobalConfig definition) will be
|
||||||
|
// created.
|
||||||
|
optional GlobalConfig global = 1;
|
||||||
|
// The list of jobs to scrape.
|
||||||
|
repeated JobConfig job = 2;
|
||||||
|
}
|
|
@ -14,8 +14,6 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -25,37 +23,41 @@ var fixturesPath = "fixtures"
|
||||||
|
|
||||||
var configTests = []struct {
|
var configTests = []struct {
|
||||||
inputFile string
|
inputFile string
|
||||||
printedFile string
|
|
||||||
shouldFail bool
|
shouldFail bool
|
||||||
errContains string
|
errContains string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
inputFile: "minimal.conf.input",
|
inputFile: "minimal.conf.input",
|
||||||
printedFile: "minimal.conf.printed",
|
|
||||||
}, {
|
}, {
|
||||||
inputFile: "sample.conf.input",
|
inputFile: "sample.conf.input",
|
||||||
printedFile: "sample.conf.printed",
|
|
||||||
}, {
|
}, {
|
||||||
// TODO: Options that are not provided should be set to sane defaults or
|
inputFile: "empty.conf.input",
|
||||||
// create errors during config loading (as appropriate). Right now, these
|
},
|
||||||
// options remain at their zero-values, which is probably not what we want.
|
{
|
||||||
inputFile: "empty.conf.input",
|
inputFile: "invalid_proto_format.conf.input",
|
||||||
printedFile: "empty.conf.printed",
|
shouldFail: true,
|
||||||
|
errContains: "unknown field name",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputFile: "invalid_scrape_interval.conf.input",
|
||||||
|
shouldFail: true,
|
||||||
|
errContains: "Invalid global scrape interval",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputFile: "invalid_job_name.conf.input",
|
||||||
|
shouldFail: true,
|
||||||
|
errContains: "Invalid job name",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inputFile: "invalid_label_name.conf.input",
|
||||||
|
shouldFail: true,
|
||||||
|
errContains: "Invalid label name",
|
||||||
},
|
},
|
||||||
// TODO: To enable testing of bad configs, we first need to change config
|
|
||||||
// loading so that it doesn't exit when loading a bad config. Instead, the
|
|
||||||
// configuration error should be passed back all the way to the caller.
|
|
||||||
//
|
|
||||||
//{
|
|
||||||
// inputFile: "bad_job_option.conf.input",
|
|
||||||
// shouldFail: true,
|
|
||||||
// errContains: "Missing job name",
|
|
||||||
//},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConfigs(t *testing.T) {
|
func TestConfigs(t *testing.T) {
|
||||||
for i, configTest := range configTests {
|
for i, configTest := range configTests {
|
||||||
testConfig, err := LoadFromFile(path.Join(fixturesPath, configTest.inputFile))
|
_, err := LoadFromFile(path.Join(fixturesPath, configTest.inputFile))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !configTest.shouldFail {
|
if !configTest.shouldFail {
|
||||||
|
@ -65,22 +67,6 @@ func TestConfigs(t *testing.T) {
|
||||||
t.Fatalf("%d. Expected error containing '%v', got: %v", i, configTest.errContains, err)
|
t.Fatalf("%d. Expected error containing '%v', got: %v", i, configTest.errContains, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
printedConfig, err := ioutil.ReadFile(path.Join(fixturesPath, configTest.printedFile))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("%d. Error reading config %v: %v", i, configTest.inputFile, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
expected := string(printedConfig)
|
|
||||||
actual := testConfig.ToString(0)
|
|
||||||
|
|
||||||
if actual != expected {
|
|
||||||
t.Errorf("%d. %v: printed config doesn't match expected output", i, configTest.inputFile)
|
|
||||||
t.Errorf("Expected:\n%v\n\nActual:\n%v\n", expected, actual)
|
|
||||||
t.Fatalf("Writing expected and actual printed configs to /tmp for diffing (see test source for paths)")
|
|
||||||
ioutil.WriteFile(fmt.Sprintf("/tmp/%s.expected", configTest.printedFile), []byte(expected), 0600)
|
|
||||||
ioutil.WriteFile(fmt.Sprintf("/tmp/%s.actual", configTest.printedFile), []byte(actual), 0600)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
global {
|
|
||||||
scrape_interval = "30s"
|
|
||||||
evaluation_interval = "30s"
|
|
||||||
labels {
|
|
||||||
monitor = "test"
|
|
||||||
}
|
|
||||||
rule_files = [
|
|
||||||
"prometheus.rules"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
job {
|
|
||||||
jobname = "prometheus"
|
|
||||||
scrape_interval = "15s"
|
|
||||||
|
|
||||||
targets {
|
|
||||||
endpoints = [
|
|
||||||
"http://localhost:9090/metrics.json"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
global {
|
|
||||||
scrape_interval = "0y"
|
|
||||||
evaluation_interval = "0y"
|
|
||||||
rule_files = [
|
|
||||||
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
3
config/fixtures/invalid_job_name.conf.input
Normal file
3
config/fixtures/invalid_job_name.conf.input
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
job: <
|
||||||
|
name: "1testjob"
|
||||||
|
>
|
10
config/fixtures/invalid_label_name.conf.input
Normal file
10
config/fixtures/invalid_label_name.conf.input
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
global <
|
||||||
|
scrape_interval: "30s"
|
||||||
|
evaluation_interval: "30s"
|
||||||
|
labels: <
|
||||||
|
label: <
|
||||||
|
name: "monitor-test"
|
||||||
|
value: "test"
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
11
config/fixtures/invalid_proto_format.conf.input
Normal file
11
config/fixtures/invalid_proto_format.conf.input
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
global <
|
||||||
|
scrape_interval: "30s"
|
||||||
|
evaluation_interval: "30s"
|
||||||
|
unknown_field: "foo"
|
||||||
|
labels: <
|
||||||
|
label: <
|
||||||
|
name: "monitor"
|
||||||
|
value: "test"
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
10
config/fixtures/invalid_scrape_interval.conf.input
Normal file
10
config/fixtures/invalid_scrape_interval.conf.input
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
global <
|
||||||
|
scrape_interval: "30"
|
||||||
|
evaluation_interval: "30s"
|
||||||
|
labels: <
|
||||||
|
label: <
|
||||||
|
name: "monitor"
|
||||||
|
value: "test"
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
|
@ -1,21 +1,20 @@
|
||||||
global {
|
global <
|
||||||
scrape_interval = "30s"
|
scrape_interval: "30s"
|
||||||
evaluation_interval = "30s"
|
evaluation_interval: "30s"
|
||||||
labels {
|
labels: <
|
||||||
monitor = "test"
|
label: <
|
||||||
}
|
name: "monitor"
|
||||||
rule_files = [
|
value: "test"
|
||||||
"prometheus.rules"
|
>
|
||||||
]
|
>
|
||||||
}
|
rule_file: "prometheus.rules"
|
||||||
|
>
|
||||||
|
|
||||||
job {
|
job: <
|
||||||
name = "prometheus"
|
name: "prometheus"
|
||||||
scrape_interval = "15s"
|
scrape_interval: "15s"
|
||||||
|
|
||||||
targets {
|
target_group: <
|
||||||
endpoints = [
|
target: "http://localhost:9090/metrics.json"
|
||||||
"http://localhost:9090/metrics.json"
|
>
|
||||||
]
|
>
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
global {
|
|
||||||
scrape_interval = "30s"
|
|
||||||
evaluation_interval = "30s"
|
|
||||||
labels {
|
|
||||||
monitor = "test"
|
|
||||||
}
|
|
||||||
rule_files = [
|
|
||||||
"prometheus.rules"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
job {
|
|
||||||
name = "prometheus"
|
|
||||||
scrape_interval = "15s"
|
|
||||||
targets {
|
|
||||||
endpoints = [
|
|
||||||
"http://localhost:9090/metrics.json"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +1,55 @@
|
||||||
global {
|
global <
|
||||||
scrape_interval = "30s"
|
scrape_interval: "30s"
|
||||||
evaluation_interval = "30s"
|
evaluation_interval: "30s"
|
||||||
labels {
|
labels: <
|
||||||
monitor = "test"
|
label: <
|
||||||
}
|
name: "monitor"
|
||||||
rule_files = [
|
value: "test"
|
||||||
"prometheus.rules"
|
>
|
||||||
]
|
>
|
||||||
}
|
rule_file: "prometheus.rules"
|
||||||
|
>
|
||||||
|
|
||||||
job {
|
job: <
|
||||||
name = "prometheus"
|
name: "prometheus"
|
||||||
scrape_interval = "15s"
|
scrape_interval: "15s"
|
||||||
|
|
||||||
targets {
|
target_group: <
|
||||||
endpoints = [
|
target: "http://localhost:9090/metrics.json"
|
||||||
"http://localhost:9090/metrics.json"
|
labels: <
|
||||||
]
|
label: <
|
||||||
labels {
|
name: "group"
|
||||||
group = "canary"
|
value: "canary"
|
||||||
}
|
>
|
||||||
}
|
>
|
||||||
}
|
>
|
||||||
|
>
|
||||||
|
|
||||||
job {
|
job: <
|
||||||
name = "random"
|
name: "random"
|
||||||
scrape_interval = "30s"
|
scrape_interval: "30s"
|
||||||
|
|
||||||
targets {
|
target_group: <
|
||||||
endpoints = [
|
target: "http://random.com:8080/metrics.json"
|
||||||
"http://random.com:8080/metrics.json",
|
target: "http://random.com:8081/metrics.json"
|
||||||
"http://random.com:8081/metrics.json",
|
target: "http://random.com:8082/metrics.json"
|
||||||
"http://random.com:8082/metrics.json",
|
target: "http://random.com:8083/metrics.json"
|
||||||
"http://random.com:8083/metrics.json",
|
target: "http://random.com:8084/metrics.json"
|
||||||
"http://random.com:8084/metrics.json"
|
labels: <
|
||||||
]
|
label: <
|
||||||
labels {
|
name: "group"
|
||||||
group = "production"
|
value: "production"
|
||||||
}
|
>
|
||||||
}
|
>
|
||||||
targets {
|
>
|
||||||
endpoints = [
|
target_group: <
|
||||||
"http://random.com:8085/metrics.json",
|
target: "http://random.com:8085/metrics.json"
|
||||||
"http://random.com:8086/metrics.json"
|
target: "http://random.com:8086/metrics.json"
|
||||||
]
|
labels: <
|
||||||
labels {
|
label: <
|
||||||
group = "canary"
|
name: "group"
|
||||||
}
|
value: "canary"
|
||||||
}
|
>
|
||||||
}
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
global {
|
|
||||||
scrape_interval = "30s"
|
|
||||||
evaluation_interval = "30s"
|
|
||||||
labels {
|
|
||||||
monitor = "test"
|
|
||||||
}
|
|
||||||
rule_files = [
|
|
||||||
"prometheus.rules"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
job {
|
|
||||||
name = "prometheus"
|
|
||||||
scrape_interval = "15s"
|
|
||||||
targets {
|
|
||||||
endpoints = [
|
|
||||||
"http://localhost:9090/metrics.json"
|
|
||||||
]
|
|
||||||
labels {
|
|
||||||
group = "canary"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
job {
|
|
||||||
name = "random"
|
|
||||||
scrape_interval = "30s"
|
|
||||||
targets {
|
|
||||||
endpoints = [
|
|
||||||
"http://random.com:8080/metrics.json",
|
|
||||||
"http://random.com:8081/metrics.json",
|
|
||||||
"http://random.com:8082/metrics.json",
|
|
||||||
"http://random.com:8083/metrics.json",
|
|
||||||
"http://random.com:8084/metrics.json"
|
|
||||||
]
|
|
||||||
labels {
|
|
||||||
group = "production"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
targets {
|
|
||||||
endpoints = [
|
|
||||||
"http://random.com:8085/metrics.json",
|
|
||||||
"http://random.com:8086/metrics.json"
|
|
||||||
]
|
|
||||||
labels {
|
|
||||||
group = "canary"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
1
config/generated/.gitignore
vendored
Normal file
1
config/generated/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
config.pb.go
|
|
@ -1,67 +0,0 @@
|
||||||
// Copyright 2013 Prometheus Team
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/prometheus/prometheus/model"
|
|
||||||
"log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Unfortunately, more global variables that are needed for parsing.
|
|
||||||
var tmpJobOptions = map[string]string{}
|
|
||||||
var tmpJobTargets = []Targets{}
|
|
||||||
var tmpTargetEndpoints = []string{}
|
|
||||||
var tmpTargetLabels = model.LabelSet{}
|
|
||||||
|
|
||||||
func configError(error string, v ...interface{}) {
|
|
||||||
message := fmt.Sprintf(error, v...)
|
|
||||||
// TODO: Don't just die here. Pass errors back all the way to the caller
|
|
||||||
// instead.
|
|
||||||
log.Fatalf("Line %v, char %v: %s", yyline, yypos, message)
|
|
||||||
}
|
|
||||||
|
|
||||||
func PushJobOption(option string, value string) {
|
|
||||||
tmpJobOptions[option] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
func PushJobTargets() {
|
|
||||||
targets := Targets{
|
|
||||||
Endpoints: tmpTargetEndpoints,
|
|
||||||
Labels: tmpTargetLabels,
|
|
||||||
}
|
|
||||||
tmpJobTargets = append(tmpJobTargets, targets)
|
|
||||||
tmpTargetLabels = model.LabelSet{}
|
|
||||||
tmpTargetEndpoints = []string{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PushTargetEndpoints(endpoints []string) {
|
|
||||||
for _, endpoint := range endpoints {
|
|
||||||
tmpTargetEndpoints = append(tmpTargetEndpoints, endpoint)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PushTargetLabels(labels model.LabelSet) {
|
|
||||||
for k, v := range labels {
|
|
||||||
tmpTargetLabels[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PopJob() {
|
|
||||||
if err := parsedConfig.AddJob(tmpJobOptions, tmpJobTargets); err != nil {
|
|
||||||
configError(err.Error())
|
|
||||||
}
|
|
||||||
tmpJobOptions = map[string]string{}
|
|
||||||
tmpJobTargets = []Targets{}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
/* Copyright 2013 Prometheus Team
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http: *www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License. */
|
|
||||||
|
|
||||||
%{
|
|
||||||
package config
|
|
||||||
%}
|
|
||||||
|
|
||||||
D [0-9]
|
|
||||||
L [a-zA-Z_]
|
|
||||||
|
|
||||||
%s S_GLOBAL S_GLOBAL_LABELS S_JOB S_TARGETS S_TARGET_LABELS
|
|
||||||
%x S_COMMENTS
|
|
||||||
|
|
||||||
%%
|
|
||||||
. { yypos++; REJECT }
|
|
||||||
\n { yyline++; yypos = 1; REJECT }
|
|
||||||
|
|
||||||
"/*" { BEGIN(S_COMMENTS); }
|
|
||||||
<S_COMMENTS>"*/" { BEGIN(0) }
|
|
||||||
<S_COMMENTS>. { /* ignore chars within multi-line comments */ }
|
|
||||||
|
|
||||||
\/\/[^\r\n]*\n { /* gobble up one-line comments */ }
|
|
||||||
|
|
||||||
<0>global { BEGIN(S_GLOBAL); return GLOBAL }
|
|
||||||
<S_GLOBAL>labels { BEGIN(S_GLOBAL_LABELS); return LABELS }
|
|
||||||
<S_GLOBAL>rule_files { return RULE_FILES }
|
|
||||||
<S_GLOBAL_LABELS>"}" { BEGIN(S_GLOBAL); REJECT }
|
|
||||||
<S_GLOBAL>"}" { BEGIN(0); REJECT }
|
|
||||||
|
|
||||||
<0>job { BEGIN(S_JOB); return JOB }
|
|
||||||
<S_JOB>targets { BEGIN(S_TARGETS); return TARGETS }
|
|
||||||
<S_TARGETS>endpoints { return ENDPOINTS }
|
|
||||||
<S_TARGETS>labels { BEGIN(S_TARGET_LABELS); return LABELS }
|
|
||||||
<S_TARGET_LABELS>"}" { BEGIN(S_TARGETS); REJECT }
|
|
||||||
<S_TARGETS>"}" { BEGIN(S_JOB); REJECT }
|
|
||||||
<S_JOB>"}" { BEGIN(0); REJECT }
|
|
||||||
|
|
||||||
{L}({L}|{D})+ { yylval.str = yytext; return IDENTIFIER }
|
|
||||||
|
|
||||||
\"(\\.|[^\\"])*\" { yylval.str = yytext[1:len(yytext) - 1]; return STRING }
|
|
||||||
\'(\\.|[^\\'])*\' { yylval.str = yytext[1:len(yytext) - 1]; return STRING }
|
|
||||||
|
|
||||||
[{}\[\]()=,] { return int(yytext[0]) }
|
|
||||||
. { /* don't print any remaining chars (whitespace) */ }
|
|
||||||
\n { /* don't print any remaining chars (whitespace) */ }
|
|
||||||
%%
|
|
|
@ -1,551 +0,0 @@
|
||||||
// Generated by golex
|
|
||||||
package config
|
|
||||||
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"regexp"
|
|
||||||
"sort"
|
|
||||||
)
|
|
||||||
|
|
||||||
var yyin io.Reader = os.Stdin
|
|
||||||
var yyout io.Writer = os.Stdout
|
|
||||||
|
|
||||||
type yyrule struct {
|
|
||||||
regexp *regexp.Regexp
|
|
||||||
trailing *regexp.Regexp
|
|
||||||
startConds []yystartcondition
|
|
||||||
sol bool
|
|
||||||
action func() yyactionreturn
|
|
||||||
}
|
|
||||||
|
|
||||||
type yyactionreturn struct {
|
|
||||||
userReturn int
|
|
||||||
returnType yyactionreturntype
|
|
||||||
}
|
|
||||||
|
|
||||||
type yyactionreturntype int
|
|
||||||
const (
|
|
||||||
yyRT_FALLTHROUGH yyactionreturntype = iota
|
|
||||||
yyRT_USER_RETURN
|
|
||||||
yyRT_REJECT
|
|
||||||
)
|
|
||||||
|
|
||||||
var yydata string = ""
|
|
||||||
var yyorig string
|
|
||||||
var yyorigidx int
|
|
||||||
|
|
||||||
var yytext string = ""
|
|
||||||
var yytextrepl bool = true
|
|
||||||
func yymore() {
|
|
||||||
yytextrepl = false
|
|
||||||
}
|
|
||||||
|
|
||||||
func yyBEGIN(state yystartcondition) {
|
|
||||||
YY_START = state
|
|
||||||
}
|
|
||||||
|
|
||||||
func yyECHO() {
|
|
||||||
yyout.Write([]byte(yytext))
|
|
||||||
}
|
|
||||||
|
|
||||||
func yyREJECT() {
|
|
||||||
panic("yyREJECT")
|
|
||||||
}
|
|
||||||
|
|
||||||
var yylessed int
|
|
||||||
func yyless(n int) {
|
|
||||||
yylessed = len(yytext) - n
|
|
||||||
}
|
|
||||||
|
|
||||||
func unput(c uint8) {
|
|
||||||
yyorig = yyorig[:yyorigidx] + string(c) + yyorig[yyorigidx:]
|
|
||||||
yydata = yydata[:len(yytext)-yylessed] + string(c) + yydata[len(yytext)-yylessed:]
|
|
||||||
}
|
|
||||||
|
|
||||||
func input() int {
|
|
||||||
if len(yyorig) <= yyorigidx {
|
|
||||||
return EOF
|
|
||||||
}
|
|
||||||
c := yyorig[yyorigidx]
|
|
||||||
yyorig = yyorig[:yyorigidx] + yyorig[yyorigidx+1:]
|
|
||||||
yydata = yydata[:len(yytext)-yylessed] + yydata[len(yytext)-yylessed+1:]
|
|
||||||
return int(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
var EOF int = -1
|
|
||||||
type yystartcondition int
|
|
||||||
|
|
||||||
var INITIAL yystartcondition = 0
|
|
||||||
var YY_START yystartcondition = INITIAL
|
|
||||||
|
|
||||||
type yylexMatch struct {
|
|
||||||
index int
|
|
||||||
matchFunc func() yyactionreturn
|
|
||||||
sortLen int
|
|
||||||
advLen int
|
|
||||||
}
|
|
||||||
|
|
||||||
type yylexMatchList []yylexMatch
|
|
||||||
|
|
||||||
func (ml yylexMatchList) Len() int {
|
|
||||||
return len(ml)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ml yylexMatchList) Less(i, j int) bool {
|
|
||||||
return ml[i].sortLen > ml[j].sortLen && ml[i].index > ml[j].index
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ml yylexMatchList) Swap(i, j int) {
|
|
||||||
ml[i], ml[j] = ml[j], ml[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
func yylex() int {
|
|
||||||
reader := bufio.NewReader(yyin)
|
|
||||||
|
|
||||||
for {
|
|
||||||
line, err := reader.ReadString('\n')
|
|
||||||
if len(line) == 0 && err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
yydata += line
|
|
||||||
}
|
|
||||||
|
|
||||||
yyorig = yydata
|
|
||||||
yyorigidx = 0
|
|
||||||
|
|
||||||
yyactioninline(yyBEGIN)
|
|
||||||
|
|
||||||
for len(yydata) > 0 {
|
|
||||||
matches := yylexMatchList(make([]yylexMatch, 0, 6))
|
|
||||||
excl := yystartconditionexclmap[YY_START]
|
|
||||||
|
|
||||||
for i, v := range yyrules {
|
|
||||||
sol := yyorigidx == 0 || yyorig[yyorigidx-1] == '\n'
|
|
||||||
|
|
||||||
if v.sol && !sol {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check start conditions.
|
|
||||||
ok := false
|
|
||||||
|
|
||||||
// YY_START or '*' must feature in v.startConds
|
|
||||||
for _, c := range v.startConds {
|
|
||||||
if c == YY_START || c == -1 {
|
|
||||||
ok = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !excl {
|
|
||||||
// If v.startConds is empty, this is also acceptable.
|
|
||||||
if len(v.startConds) == 0 {
|
|
||||||
ok = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
idxs := v.regexp.FindStringIndex(yydata)
|
|
||||||
if idxs != nil && idxs[0] == 0 {
|
|
||||||
// Check the trailing context, if any.
|
|
||||||
checksOk := true
|
|
||||||
sortLen := idxs[1]
|
|
||||||
advLen := idxs[1]
|
|
||||||
|
|
||||||
if v.trailing != nil {
|
|
||||||
tridxs := v.trailing.FindStringIndex(yydata[idxs[1]:])
|
|
||||||
if tridxs == nil || tridxs[0] != 0 {
|
|
||||||
checksOk = false
|
|
||||||
} else {
|
|
||||||
sortLen += tridxs[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if checksOk {
|
|
||||||
matches = append(matches, yylexMatch{i, v.action, sortLen, advLen})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if yytextrepl {
|
|
||||||
yytext = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Sort(matches)
|
|
||||||
|
|
||||||
tryMatch:
|
|
||||||
if len(matches) == 0 {
|
|
||||||
yytext += yydata[:1]
|
|
||||||
yydata = yydata[1:]
|
|
||||||
yyorigidx += 1
|
|
||||||
|
|
||||||
yyout.Write([]byte(yytext))
|
|
||||||
} else {
|
|
||||||
m := matches[0]
|
|
||||||
yytext += yydata[:m.advLen]
|
|
||||||
yyorigidx += m.advLen
|
|
||||||
|
|
||||||
yytextrepl, yylessed = true, 0
|
|
||||||
ar := m.matchFunc()
|
|
||||||
|
|
||||||
if ar.returnType != yyRT_REJECT {
|
|
||||||
yydata = yydata[m.advLen-yylessed:]
|
|
||||||
yyorigidx -= yylessed
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ar.returnType {
|
|
||||||
case yyRT_FALLTHROUGH:
|
|
||||||
// Do nothing.
|
|
||||||
case yyRT_USER_RETURN:
|
|
||||||
return ar.userReturn
|
|
||||||
case yyRT_REJECT:
|
|
||||||
matches = matches[1:]
|
|
||||||
yytext = yytext[:len(yytext)-m.advLen]
|
|
||||||
yyorigidx -= m.advLen
|
|
||||||
goto tryMatch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
var S_TARGETS yystartcondition = 1027
|
|
||||||
var S_JOB yystartcondition = 1026
|
|
||||||
var S_GLOBAL yystartcondition = 1024
|
|
||||||
var S_GLOBAL_LABELS yystartcondition = 1025
|
|
||||||
var S_COMMENTS yystartcondition = 1029
|
|
||||||
var S_TARGET_LABELS yystartcondition = 1028
|
|
||||||
var yystartconditionexclmap = map[yystartcondition]bool{S_GLOBAL: false, S_GLOBAL_LABELS: false, S_COMMENTS: true, S_TARGET_LABELS: false, S_TARGETS: false, S_JOB: false, }
|
|
||||||
var yyrules []yyrule = []yyrule{{regexp.MustCompile("[^\\n]"), nil, []yystartcondition{}, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yypos++
|
|
||||||
yyREJECT()
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("\\n"), nil, []yystartcondition{}, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yyline++
|
|
||||||
yypos = 1
|
|
||||||
yyREJECT()
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("/\\*"), nil, []yystartcondition{}, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yyBEGIN(S_COMMENTS)
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("\\*/"), nil, []yystartcondition{S_COMMENTS, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yyBEGIN(0)
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("[^\\n]"), nil, []yystartcondition{S_COMMENTS, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("\\/\\/[^\\r\\n]*\\n"), nil, []yystartcondition{}, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("global"), nil, []yystartcondition{0, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yyBEGIN(S_GLOBAL)
|
|
||||||
return yyactionreturn{GLOBAL, yyRT_USER_RETURN}
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("labels"), nil, []yystartcondition{S_GLOBAL, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yyBEGIN(S_GLOBAL_LABELS)
|
|
||||||
return yyactionreturn{LABELS, yyRT_USER_RETURN}
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("rule_files"), nil, []yystartcondition{S_GLOBAL, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
return yyactionreturn{RULE_FILES, yyRT_USER_RETURN}
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("\\}"), nil, []yystartcondition{S_GLOBAL_LABELS, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yyBEGIN(S_GLOBAL)
|
|
||||||
yyREJECT()
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("\\}"), nil, []yystartcondition{S_GLOBAL, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yyBEGIN(0)
|
|
||||||
yyREJECT()
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("job"), nil, []yystartcondition{0, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yyBEGIN(S_JOB)
|
|
||||||
return yyactionreturn{JOB, yyRT_USER_RETURN}
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("targets"), nil, []yystartcondition{S_JOB, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yyBEGIN(S_TARGETS)
|
|
||||||
return yyactionreturn{TARGETS, yyRT_USER_RETURN}
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("endpoints"), nil, []yystartcondition{S_TARGETS, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
return yyactionreturn{ENDPOINTS, yyRT_USER_RETURN}
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("labels"), nil, []yystartcondition{S_TARGETS, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yyBEGIN(S_TARGET_LABELS)
|
|
||||||
return yyactionreturn{LABELS, yyRT_USER_RETURN}
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("\\}"), nil, []yystartcondition{S_TARGET_LABELS, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yyBEGIN(S_TARGETS)
|
|
||||||
yyREJECT()
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("\\}"), nil, []yystartcondition{S_TARGETS, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yyBEGIN(S_JOB)
|
|
||||||
yyREJECT()
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("\\}"), nil, []yystartcondition{S_JOB, }, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yyBEGIN(0)
|
|
||||||
yyREJECT()
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("([a-zA-Z_])(([a-zA-Z_])|([0-9]))+"), nil, []yystartcondition{}, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yylval.str = yytext
|
|
||||||
return yyactionreturn{IDENTIFIER, yyRT_USER_RETURN}
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("\\\"(\\\\[^\\n]|[^\\\\\"])*\\\""), nil, []yystartcondition{}, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yylval.str = yytext[1 : len(yytext)-1]
|
|
||||||
return yyactionreturn{STRING, yyRT_USER_RETURN}
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("\\'(\\\\[^\\n]|[^\\\\'])*\\'"), nil, []yystartcondition{}, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
yylval.str = yytext[1 : len(yytext)-1]
|
|
||||||
return yyactionreturn{STRING, yyRT_USER_RETURN}
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("[{}\\[\\]()=,]"), nil, []yystartcondition{}, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
return yyactionreturn{int(yytext[0]), yyRT_USER_RETURN}
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("[^\\n]"), nil, []yystartcondition{}, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, {regexp.MustCompile("\\n"), nil, []yystartcondition{}, false, func() (yyar yyactionreturn) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
if r != "yyREJECT" {
|
|
||||||
panic(r)
|
|
||||||
}
|
|
||||||
yyar.returnType = yyRT_REJECT
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
return yyactionreturn{0, yyRT_FALLTHROUGH}
|
|
||||||
}}, }
|
|
||||||
func yyactioninline(BEGIN func(yystartcondition)) {}
|
|
|
@ -14,66 +14,35 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"code.google.com/p/goprotobuf/proto"
|
||||||
"fmt"
|
pb "github.com/prometheus/prometheus/config/generated"
|
||||||
"io"
|
"io/ioutil"
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NOTE: This parser is non-reentrant due to its dependence on global state.
|
func LoadFromString(configStr string) (config Config, err error) {
|
||||||
|
configProto := pb.PrometheusConfig{}
|
||||||
// GoLex sadly needs these global variables for storing temporary token/parsing information.
|
if err = proto.UnmarshalText(configStr, &configProto); err != nil {
|
||||||
var yylval *yySymType // For storing extra token information, like the contents of a string.
|
return
|
||||||
var yyline int // Line number within the current file or buffer.
|
|
||||||
var yypos int // Character position within the current line.
|
|
||||||
var parsedConfig *Config // Temporary variable for storing the parsed configuration.
|
|
||||||
|
|
||||||
type ConfigLexer struct {
|
|
||||||
errors []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lexer *ConfigLexer) Lex(lval *yySymType) int {
|
|
||||||
yylval = lval
|
|
||||||
token_type := yylex()
|
|
||||||
return token_type
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lexer *ConfigLexer) Error(errorStr string) {
|
|
||||||
err := fmt.Sprintf("Error reading config at line %v, char %v: %v", yyline, yypos, errorStr)
|
|
||||||
lexer.errors = append(lexer.errors, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadFromReader(configReader io.Reader) (*Config, error) {
|
|
||||||
parsedConfig = New()
|
|
||||||
yyin = configReader
|
|
||||||
yypos = 1
|
|
||||||
yyline = 1
|
|
||||||
yydata = ""
|
|
||||||
yytext = ""
|
|
||||||
|
|
||||||
lexer := &ConfigLexer{}
|
|
||||||
yyParse(lexer)
|
|
||||||
|
|
||||||
if len(lexer.errors) > 0 {
|
|
||||||
err := errors.New(strings.Join(lexer.errors, "\n"))
|
|
||||||
return &Config{}, err
|
|
||||||
}
|
}
|
||||||
|
if configProto.Global == nil {
|
||||||
return parsedConfig, nil
|
configProto.Global = &pb.GlobalConfig{}
|
||||||
|
}
|
||||||
|
for _, job := range configProto.Job {
|
||||||
|
if job.ScrapeInterval == nil {
|
||||||
|
job.ScrapeInterval = proto.String(configProto.Global.GetScrapeInterval())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config = Config{configProto}
|
||||||
|
err = config.Validate()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadFromString(configString string) (*Config, error) {
|
func LoadFromFile(fileName string) (config Config, err error) {
|
||||||
configReader := strings.NewReader(configString)
|
configStr, err := ioutil.ReadFile(fileName)
|
||||||
return LoadFromReader(configReader)
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadFromFile(fileName string) (*Config, error) {
|
|
||||||
configReader, err := os.Open(fileName)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &Config{}, err
|
return
|
||||||
}
|
}
|
||||||
defer configReader.Close()
|
|
||||||
|
|
||||||
return LoadFromReader(configReader)
|
config, err = LoadFromString(string(configStr))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
115
config/parser.y
115
config/parser.y
|
@ -1,115 +0,0 @@
|
||||||
// Copyright 2013 Prometheus Team
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
%{
|
|
||||||
package config
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
import "github.com/prometheus/prometheus/model"
|
|
||||||
%}
|
|
||||||
|
|
||||||
%union {
|
|
||||||
num model.SampleValue
|
|
||||||
str string
|
|
||||||
stringSlice []string
|
|
||||||
labelSet model.LabelSet
|
|
||||||
}
|
|
||||||
|
|
||||||
%token <str> IDENTIFIER STRING
|
|
||||||
%token GLOBAL JOB
|
|
||||||
%token RULE_FILES
|
|
||||||
%token LABELS TARGETS ENDPOINTS
|
|
||||||
|
|
||||||
%type <stringSlice> string_array string_list rule_files_stat endpoints_stat
|
|
||||||
%type <labelSet> labels_stat label_assign label_assign_list
|
|
||||||
|
|
||||||
%start config
|
|
||||||
|
|
||||||
%%
|
|
||||||
config : /* empty */
|
|
||||||
| config config_stanza
|
|
||||||
;
|
|
||||||
|
|
||||||
config_stanza : GLOBAL '{' global_stat_list '}'
|
|
||||||
| JOB '{' job_stat_list '}'
|
|
||||||
{ PopJob() }
|
|
||||||
;
|
|
||||||
|
|
||||||
global_stat_list : /* empty */
|
|
||||||
| global_stat_list global_stat
|
|
||||||
;
|
|
||||||
|
|
||||||
global_stat : IDENTIFIER '=' STRING
|
|
||||||
{ parsedConfig.Global.SetOption($1, $3) }
|
|
||||||
| labels_stat
|
|
||||||
{ parsedConfig.Global.SetLabels($1) }
|
|
||||||
| rule_files_stat
|
|
||||||
{ parsedConfig.Global.AddRuleFiles($1) }
|
|
||||||
;
|
|
||||||
|
|
||||||
labels_stat : LABELS '{' label_assign_list '}'
|
|
||||||
{ $$ = $3 }
|
|
||||||
| LABELS '{' '}'
|
|
||||||
{ $$ = model.LabelSet{} }
|
|
||||||
;
|
|
||||||
|
|
||||||
label_assign_list : label_assign
|
|
||||||
{ $$ = $1 }
|
|
||||||
| label_assign_list ',' label_assign
|
|
||||||
{ for k, v := range $3 { $$[k] = v } }
|
|
||||||
;
|
|
||||||
|
|
||||||
label_assign : IDENTIFIER '=' STRING
|
|
||||||
{ $$ = model.LabelSet{ model.LabelName($1): model.LabelValue($3) } }
|
|
||||||
;
|
|
||||||
|
|
||||||
rule_files_stat : RULE_FILES '=' string_array
|
|
||||||
{ $$ = $3 }
|
|
||||||
;
|
|
||||||
|
|
||||||
job_stat_list : /* empty */
|
|
||||||
| job_stat_list job_stat
|
|
||||||
;
|
|
||||||
|
|
||||||
job_stat : IDENTIFIER '=' STRING
|
|
||||||
{ PushJobOption($1, $3) }
|
|
||||||
| TARGETS '{' targets_stat_list '}'
|
|
||||||
{ PushJobTargets() }
|
|
||||||
;
|
|
||||||
|
|
||||||
targets_stat_list : /* empty */
|
|
||||||
| targets_stat_list targets_stat
|
|
||||||
;
|
|
||||||
|
|
||||||
targets_stat : endpoints_stat
|
|
||||||
{ PushTargetEndpoints($1) }
|
|
||||||
| labels_stat
|
|
||||||
{ PushTargetLabels($1) }
|
|
||||||
;
|
|
||||||
|
|
||||||
endpoints_stat : ENDPOINTS '=' string_array
|
|
||||||
{ $$ = $3 }
|
|
||||||
;
|
|
||||||
|
|
||||||
string_array : '[' string_list ']'
|
|
||||||
{ $$ = $2 }
|
|
||||||
| '[' ']'
|
|
||||||
{ $$ = []string{} }
|
|
||||||
;
|
|
||||||
|
|
||||||
string_list : STRING
|
|
||||||
{ $$ = []string{$1} }
|
|
||||||
| string_list ',' STRING
|
|
||||||
{ $$ = append($$, $3) }
|
|
||||||
;
|
|
||||||
%%
|
|
|
@ -1,420 +0,0 @@
|
||||||
|
|
||||||
//line parser.y:15
|
|
||||||
package config
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
import "github.com/prometheus/prometheus/model"
|
|
||||||
|
|
||||||
//line parser.y:21
|
|
||||||
type yySymType struct {
|
|
||||||
yys int
|
|
||||||
num model.SampleValue
|
|
||||||
str string
|
|
||||||
stringSlice []string
|
|
||||||
labelSet model.LabelSet
|
|
||||||
}
|
|
||||||
|
|
||||||
const IDENTIFIER = 57346
|
|
||||||
const STRING = 57347
|
|
||||||
const GLOBAL = 57348
|
|
||||||
const JOB = 57349
|
|
||||||
const RULE_FILES = 57350
|
|
||||||
const LABELS = 57351
|
|
||||||
const TARGETS = 57352
|
|
||||||
const ENDPOINTS = 57353
|
|
||||||
|
|
||||||
var yyToknames = []string{
|
|
||||||
"IDENTIFIER",
|
|
||||||
"STRING",
|
|
||||||
"GLOBAL",
|
|
||||||
"JOB",
|
|
||||||
"RULE_FILES",
|
|
||||||
"LABELS",
|
|
||||||
"TARGETS",
|
|
||||||
"ENDPOINTS",
|
|
||||||
}
|
|
||||||
var yyStatenames = []string{}
|
|
||||||
|
|
||||||
const yyEofCode = 1
|
|
||||||
const yyErrCode = 2
|
|
||||||
const yyMaxDepth = 200
|
|
||||||
|
|
||||||
//line parser.y:115
|
|
||||||
|
|
||||||
|
|
||||||
//line yacctab:1
|
|
||||||
var yyExca = []int{
|
|
||||||
-1, 1,
|
|
||||||
1, -1,
|
|
||||||
-2, 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
const yyNprod = 29
|
|
||||||
const yyPrivate = 57344
|
|
||||||
|
|
||||||
var yyTokenNames []string
|
|
||||||
var yyStates []string
|
|
||||||
|
|
||||||
const yyLast = 53
|
|
||||||
|
|
||||||
var yyAct = []int{
|
|
||||||
|
|
||||||
30, 28, 12, 48, 39, 47, 31, 34, 11, 35,
|
|
||||||
49, 36, 15, 14, 29, 18, 38, 9, 14, 23,
|
|
||||||
44, 19, 40, 27, 16, 50, 22, 20, 24, 21,
|
|
||||||
6, 5, 3, 4, 46, 32, 43, 45, 25, 29,
|
|
||||||
41, 33, 17, 10, 8, 7, 2, 1, 26, 42,
|
|
||||||
51, 13, 37,
|
|
||||||
}
|
|
||||||
var yyPact = []int{
|
|
||||||
|
|
||||||
-1000, 26, -1000, 19, 18, -1000, -1000, 4, 11, -1000,
|
|
||||||
-1000, 13, -1000, -1000, 17, 12, -1000, -1000, 5, 16,
|
|
||||||
33, 10, -10, 30, -1000, -1000, -6, -1000, -1000, -3,
|
|
||||||
-1000, -1, -1000, 9, -1000, 35, 29, -12, -1000, -1000,
|
|
||||||
-1000, -1000, -1000, -1000, -4, -1000, -1000, -1000, 20, -10,
|
|
||||||
-1000, -1000,
|
|
||||||
}
|
|
||||||
var yyPgo = []int{
|
|
||||||
|
|
||||||
0, 0, 52, 51, 49, 2, 1, 48, 47, 46,
|
|
||||||
45, 44, 43, 42, 41, 40,
|
|
||||||
}
|
|
||||||
var yyR1 = []int{
|
|
||||||
|
|
||||||
0, 8, 8, 9, 9, 10, 10, 12, 12, 12,
|
|
||||||
5, 5, 7, 7, 6, 3, 11, 11, 13, 13,
|
|
||||||
14, 14, 15, 15, 4, 1, 1, 2, 2,
|
|
||||||
}
|
|
||||||
var yyR2 = []int{
|
|
||||||
|
|
||||||
0, 0, 2, 4, 4, 0, 2, 3, 1, 1,
|
|
||||||
4, 3, 1, 3, 3, 3, 0, 2, 3, 4,
|
|
||||||
0, 2, 1, 1, 3, 3, 2, 1, 3,
|
|
||||||
}
|
|
||||||
var yyChk = []int{
|
|
||||||
|
|
||||||
-1000, -8, -9, 6, 7, 12, 12, -10, -11, 13,
|
|
||||||
-12, 4, -5, -3, 9, 8, 13, -13, 4, 10,
|
|
||||||
14, 12, 14, 14, 12, 5, -7, 13, -6, 4,
|
|
||||||
-1, 16, 5, -14, 13, 15, 14, -2, 17, 5,
|
|
||||||
13, -15, -4, -5, 11, -6, 5, 17, 15, 14,
|
|
||||||
5, -1,
|
|
||||||
}
|
|
||||||
var yyDef = []int{
|
|
||||||
|
|
||||||
1, -2, 2, 0, 0, 5, 16, 0, 0, 3,
|
|
||||||
6, 0, 8, 9, 0, 0, 4, 17, 0, 0,
|
|
||||||
0, 0, 0, 0, 20, 7, 0, 11, 12, 0,
|
|
||||||
15, 0, 18, 0, 10, 0, 0, 0, 26, 27,
|
|
||||||
19, 21, 22, 23, 0, 13, 14, 25, 0, 0,
|
|
||||||
28, 24,
|
|
||||||
}
|
|
||||||
var yyTok1 = []int{
|
|
||||||
|
|
||||||
1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
||||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
||||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
||||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
||||||
3, 3, 3, 3, 15, 3, 3, 3, 3, 3,
|
|
||||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
||||||
3, 14, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
||||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
||||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
||||||
3, 16, 3, 17, 3, 3, 3, 3, 3, 3,
|
|
||||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
||||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
||||||
3, 3, 3, 12, 3, 13,
|
|
||||||
}
|
|
||||||
var yyTok2 = []int{
|
|
||||||
|
|
||||||
2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
|
|
||||||
}
|
|
||||||
var yyTok3 = []int{
|
|
||||||
0,
|
|
||||||
}
|
|
||||||
|
|
||||||
//line yaccpar:1
|
|
||||||
|
|
||||||
/* parser for yacc output */
|
|
||||||
|
|
||||||
var yyDebug = 0
|
|
||||||
|
|
||||||
type yyLexer interface {
|
|
||||||
Lex(lval *yySymType) int
|
|
||||||
Error(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
const yyFlag = -1000
|
|
||||||
|
|
||||||
func yyTokname(c int) string {
|
|
||||||
if c > 0 && c <= len(yyToknames) {
|
|
||||||
if yyToknames[c-1] != "" {
|
|
||||||
return yyToknames[c-1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("tok-%v", c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func yyStatname(s int) string {
|
|
||||||
if s >= 0 && s < len(yyStatenames) {
|
|
||||||
if yyStatenames[s] != "" {
|
|
||||||
return yyStatenames[s]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("state-%v", s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func yylex1(lex yyLexer, lval *yySymType) int {
|
|
||||||
c := 0
|
|
||||||
char := lex.Lex(lval)
|
|
||||||
if char <= 0 {
|
|
||||||
c = yyTok1[0]
|
|
||||||
goto out
|
|
||||||
}
|
|
||||||
if char < len(yyTok1) {
|
|
||||||
c = yyTok1[char]
|
|
||||||
goto out
|
|
||||||
}
|
|
||||||
if char >= yyPrivate {
|
|
||||||
if char < yyPrivate+len(yyTok2) {
|
|
||||||
c = yyTok2[char-yyPrivate]
|
|
||||||
goto out
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i := 0; i < len(yyTok3); i += 2 {
|
|
||||||
c = yyTok3[i+0]
|
|
||||||
if c == char {
|
|
||||||
c = yyTok3[i+1]
|
|
||||||
goto out
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
if c == 0 {
|
|
||||||
c = yyTok2[1] /* unknown char */
|
|
||||||
}
|
|
||||||
if yyDebug >= 3 {
|
|
||||||
fmt.Printf("lex %U %s\n", uint(char), yyTokname(c))
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
func yyParse(yylex yyLexer) int {
|
|
||||||
var yyn int
|
|
||||||
var yylval yySymType
|
|
||||||
var yyVAL yySymType
|
|
||||||
yyS := make([]yySymType, yyMaxDepth)
|
|
||||||
|
|
||||||
Nerrs := 0 /* number of errors */
|
|
||||||
Errflag := 0 /* error recovery flag */
|
|
||||||
yystate := 0
|
|
||||||
yychar := -1
|
|
||||||
yyp := -1
|
|
||||||
goto yystack
|
|
||||||
|
|
||||||
ret0:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
ret1:
|
|
||||||
return 1
|
|
||||||
|
|
||||||
yystack:
|
|
||||||
/* put a state and value onto the stack */
|
|
||||||
if yyDebug >= 4 {
|
|
||||||
fmt.Printf("char %v in %v\n", yyTokname(yychar), yyStatname(yystate))
|
|
||||||
}
|
|
||||||
|
|
||||||
yyp++
|
|
||||||
if yyp >= len(yyS) {
|
|
||||||
nyys := make([]yySymType, len(yyS)*2)
|
|
||||||
copy(nyys, yyS)
|
|
||||||
yyS = nyys
|
|
||||||
}
|
|
||||||
yyS[yyp] = yyVAL
|
|
||||||
yyS[yyp].yys = yystate
|
|
||||||
|
|
||||||
yynewstate:
|
|
||||||
yyn = yyPact[yystate]
|
|
||||||
if yyn <= yyFlag {
|
|
||||||
goto yydefault /* simple state */
|
|
||||||
}
|
|
||||||
if yychar < 0 {
|
|
||||||
yychar = yylex1(yylex, &yylval)
|
|
||||||
}
|
|
||||||
yyn += yychar
|
|
||||||
if yyn < 0 || yyn >= yyLast {
|
|
||||||
goto yydefault
|
|
||||||
}
|
|
||||||
yyn = yyAct[yyn]
|
|
||||||
if yyChk[yyn] == yychar { /* valid shift */
|
|
||||||
yychar = -1
|
|
||||||
yyVAL = yylval
|
|
||||||
yystate = yyn
|
|
||||||
if Errflag > 0 {
|
|
||||||
Errflag--
|
|
||||||
}
|
|
||||||
goto yystack
|
|
||||||
}
|
|
||||||
|
|
||||||
yydefault:
|
|
||||||
/* default state action */
|
|
||||||
yyn = yyDef[yystate]
|
|
||||||
if yyn == -2 {
|
|
||||||
if yychar < 0 {
|
|
||||||
yychar = yylex1(yylex, &yylval)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* look through exception table */
|
|
||||||
xi := 0
|
|
||||||
for {
|
|
||||||
if yyExca[xi+0] == -1 && yyExca[xi+1] == yystate {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
xi += 2
|
|
||||||
}
|
|
||||||
for xi += 2; ; xi += 2 {
|
|
||||||
yyn = yyExca[xi+0]
|
|
||||||
if yyn < 0 || yyn == yychar {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yyn = yyExca[xi+1]
|
|
||||||
if yyn < 0 {
|
|
||||||
goto ret0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if yyn == 0 {
|
|
||||||
/* error ... attempt to resume parsing */
|
|
||||||
switch Errflag {
|
|
||||||
case 0: /* brand new error */
|
|
||||||
yylex.Error("syntax error")
|
|
||||||
Nerrs++
|
|
||||||
if yyDebug >= 1 {
|
|
||||||
fmt.Printf("%s", yyStatname(yystate))
|
|
||||||
fmt.Printf("saw %s\n", yyTokname(yychar))
|
|
||||||
}
|
|
||||||
fallthrough
|
|
||||||
|
|
||||||
case 1, 2: /* incompletely recovered error ... try again */
|
|
||||||
Errflag = 3
|
|
||||||
|
|
||||||
/* find a state where "error" is a legal shift action */
|
|
||||||
for yyp >= 0 {
|
|
||||||
yyn = yyPact[yyS[yyp].yys] + yyErrCode
|
|
||||||
if yyn >= 0 && yyn < yyLast {
|
|
||||||
yystate = yyAct[yyn] /* simulate a shift of "error" */
|
|
||||||
if yyChk[yystate] == yyErrCode {
|
|
||||||
goto yystack
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the current p has no shift on "error", pop stack */
|
|
||||||
if yyDebug >= 2 {
|
|
||||||
fmt.Printf("error recovery pops state %d\n", yyS[yyp].yys)
|
|
||||||
}
|
|
||||||
yyp--
|
|
||||||
}
|
|
||||||
/* there is no state on the stack with an error shift ... abort */
|
|
||||||
goto ret1
|
|
||||||
|
|
||||||
case 3: /* no shift yet; clobber input char */
|
|
||||||
if yyDebug >= 2 {
|
|
||||||
fmt.Printf("error recovery discards %s\n", yyTokname(yychar))
|
|
||||||
}
|
|
||||||
if yychar == yyEofCode {
|
|
||||||
goto ret1
|
|
||||||
}
|
|
||||||
yychar = -1
|
|
||||||
goto yynewstate /* try again in the same state */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reduction by production yyn */
|
|
||||||
if yyDebug >= 2 {
|
|
||||||
fmt.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate))
|
|
||||||
}
|
|
||||||
|
|
||||||
yynt := yyn
|
|
||||||
yypt := yyp
|
|
||||||
_ = yypt // guard against "declared and not used"
|
|
||||||
|
|
||||||
yyp -= yyR2[yyn]
|
|
||||||
yyVAL = yyS[yyp+1]
|
|
||||||
|
|
||||||
/* consult goto table to find next state */
|
|
||||||
yyn = yyR1[yyn]
|
|
||||||
yyg := yyPgo[yyn]
|
|
||||||
yyj := yyg + yyS[yyp].yys + 1
|
|
||||||
|
|
||||||
if yyj >= yyLast {
|
|
||||||
yystate = yyAct[yyg]
|
|
||||||
} else {
|
|
||||||
yystate = yyAct[yyj]
|
|
||||||
if yyChk[yystate] != -yyn {
|
|
||||||
yystate = yyAct[yyg]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// dummy call; replaced with literal code
|
|
||||||
switch yynt {
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
//line parser.y:45
|
|
||||||
{ PopJob() }
|
|
||||||
case 7:
|
|
||||||
//line parser.y:53
|
|
||||||
{ parsedConfig.Global.SetOption(yyS[yypt-2].str, yyS[yypt-0].str) }
|
|
||||||
case 8:
|
|
||||||
//line parser.y:55
|
|
||||||
{ parsedConfig.Global.SetLabels(yyS[yypt-0].labelSet) }
|
|
||||||
case 9:
|
|
||||||
//line parser.y:57
|
|
||||||
{ parsedConfig.Global.AddRuleFiles(yyS[yypt-0].stringSlice) }
|
|
||||||
case 10:
|
|
||||||
//line parser.y:61
|
|
||||||
{ yyVAL.labelSet = yyS[yypt-1].labelSet }
|
|
||||||
case 11:
|
|
||||||
//line parser.y:63
|
|
||||||
{ yyVAL.labelSet = model.LabelSet{} }
|
|
||||||
case 12:
|
|
||||||
//line parser.y:67
|
|
||||||
{ yyVAL.labelSet = yyS[yypt-0].labelSet }
|
|
||||||
case 13:
|
|
||||||
//line parser.y:69
|
|
||||||
{ for k, v := range yyS[yypt-0].labelSet { yyVAL.labelSet[k] = v } }
|
|
||||||
case 14:
|
|
||||||
//line parser.y:73
|
|
||||||
{ yyVAL.labelSet = model.LabelSet{ model.LabelName(yyS[yypt-2].str): model.LabelValue(yyS[yypt-0].str) } }
|
|
||||||
case 15:
|
|
||||||
//line parser.y:77
|
|
||||||
{ yyVAL.stringSlice = yyS[yypt-0].stringSlice }
|
|
||||||
case 18:
|
|
||||||
//line parser.y:85
|
|
||||||
{ PushJobOption(yyS[yypt-2].str, yyS[yypt-0].str) }
|
|
||||||
case 19:
|
|
||||||
//line parser.y:87
|
|
||||||
{ PushJobTargets() }
|
|
||||||
case 22:
|
|
||||||
//line parser.y:95
|
|
||||||
{ PushTargetEndpoints(yyS[yypt-0].stringSlice) }
|
|
||||||
case 23:
|
|
||||||
//line parser.y:97
|
|
||||||
{ PushTargetLabels(yyS[yypt-0].labelSet) }
|
|
||||||
case 24:
|
|
||||||
//line parser.y:101
|
|
||||||
{ yyVAL.stringSlice = yyS[yypt-0].stringSlice }
|
|
||||||
case 25:
|
|
||||||
//line parser.y:105
|
|
||||||
{ yyVAL.stringSlice = yyS[yypt-1].stringSlice }
|
|
||||||
case 26:
|
|
||||||
//line parser.y:107
|
|
||||||
{ yyVAL.stringSlice = []string{} }
|
|
||||||
case 27:
|
|
||||||
//line parser.y:111
|
|
||||||
{ yyVAL.stringSlice = []string{yyS[yypt-0].str} }
|
|
||||||
case 28:
|
|
||||||
//line parser.y:113
|
|
||||||
{ yyVAL.stringSlice = append(yyVAL.stringSlice, yyS[yypt-0].str) }
|
|
||||||
}
|
|
||||||
goto yystack /* stack new state and value */
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
// Copyright 2013 Prometheus Team
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/prometheus/prometheus/model"
|
|
||||||
"github.com/prometheus/prometheus/utility"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func indentStr(indent int, str string, v ...interface{}) string {
|
|
||||||
indentStr := ""
|
|
||||||
for i := 0; i < indent; i++ {
|
|
||||||
indentStr += "\t"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf(indentStr+str, v...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (config *Config) ToString(indent int) string {
|
|
||||||
global := config.Global.ToString(indent)
|
|
||||||
jobs := []string{}
|
|
||||||
for _, job := range config.Jobs {
|
|
||||||
jobs = append(jobs, job.ToString(indent))
|
|
||||||
}
|
|
||||||
return indentStr(indent, "%v\n%v", global, strings.Join(jobs, "\n"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func labelsToString(indent int, labels model.LabelSet) string {
|
|
||||||
str := indentStr(indent, "labels {\n")
|
|
||||||
labelStrings := []string{}
|
|
||||||
for label, value := range labels {
|
|
||||||
labelStrings = append(labelStrings, indentStr(indent+1, "%v = \"%v\"", label, value))
|
|
||||||
}
|
|
||||||
str += strings.Join(labelStrings, ",\n") + "\n"
|
|
||||||
str += indentStr(indent, "}\n")
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringListToString(indent int, list []string) string {
|
|
||||||
listString := []string{}
|
|
||||||
for _, item := range list {
|
|
||||||
listString = append(listString, indentStr(indent, "\"%v\"", item))
|
|
||||||
}
|
|
||||||
return strings.Join(listString, ",\n") + "\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (global *GlobalConfig) ToString(indent int) string {
|
|
||||||
str := indentStr(indent, "global {\n")
|
|
||||||
str += indentStr(indent+1, "scrape_interval = \"%s\"\n", utility.DurationToString(global.ScrapeInterval))
|
|
||||||
str += indentStr(indent+1, "evaluation_interval = \"%s\"\n", utility.DurationToString(global.EvaluationInterval))
|
|
||||||
if len(global.Labels) > 0 {
|
|
||||||
str += labelsToString(indent+1, global.Labels)
|
|
||||||
}
|
|
||||||
str += indentStr(indent+1, "rule_files = [\n")
|
|
||||||
str += stringListToString(indent+2, global.RuleFiles)
|
|
||||||
str += indentStr(indent+1, "]\n")
|
|
||||||
str += indentStr(indent, "}\n")
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
func (job *JobConfig) ToString(indent int) string {
|
|
||||||
str := indentStr(indent, "job {\n")
|
|
||||||
str += indentStr(indent+1, "name = \"%v\"\n", job.Name)
|
|
||||||
str += indentStr(indent+1, "scrape_interval = \"%s\"\n", utility.DurationToString(job.ScrapeInterval))
|
|
||||||
for _, targets := range job.Targets {
|
|
||||||
str += indentStr(indent+1, "targets {\n")
|
|
||||||
str += indentStr(indent+2, "endpoints = [\n")
|
|
||||||
str += stringListToString(indent+3, targets.Endpoints)
|
|
||||||
str += indentStr(indent+2, "]\n")
|
|
||||||
if len(targets.Labels) > 0 {
|
|
||||||
str += labelsToString(indent+2, targets.Labels)
|
|
||||||
}
|
|
||||||
str += indentStr(indent+1, "}\n")
|
|
||||||
}
|
|
||||||
str += indentStr(indent, "}\n")
|
|
||||||
return str
|
|
||||||
}
|
|
2
main.go
2
main.go
|
@ -107,7 +107,7 @@ func main() {
|
||||||
|
|
||||||
ast.SetStorage(ts)
|
ast.SetStorage(ts)
|
||||||
|
|
||||||
ruleManager := rules.NewRuleManager(ruleResults, conf.Global.EvaluationInterval)
|
ruleManager := rules.NewRuleManager(ruleResults, conf.EvaluationInterval())
|
||||||
err = ruleManager.AddRulesFromConfig(conf)
|
err = ruleManager.AddRulesFromConfig(conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error loading rule files: %v", err)
|
log.Fatalf("Error loading rule files: %v", err)
|
||||||
|
|
|
@ -24,10 +24,10 @@ import (
|
||||||
type TargetManager interface {
|
type TargetManager interface {
|
||||||
acquire()
|
acquire()
|
||||||
release()
|
release()
|
||||||
AddTarget(job *config.JobConfig, t Target, defaultScrapeInterval time.Duration)
|
AddTarget(job config.JobConfig, t Target, defaultScrapeInterval time.Duration)
|
||||||
ReplaceTargets(job *config.JobConfig, newTargets []Target, defaultScrapeInterval time.Duration)
|
ReplaceTargets(job config.JobConfig, newTargets []Target, defaultScrapeInterval time.Duration)
|
||||||
Remove(t Target)
|
Remove(t Target)
|
||||||
AddTargetsFromConfig(config *config.Config)
|
AddTargetsFromConfig(config config.Config)
|
||||||
Pools() map[string]*TargetPool
|
Pools() map[string]*TargetPool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,30 +53,27 @@ func (m *targetManager) release() {
|
||||||
<-m.requestAllowance
|
<-m.requestAllowance
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *targetManager) TargetPoolForJob(job *config.JobConfig, defaultScrapeInterval time.Duration) (targetPool *TargetPool) {
|
func (m *targetManager) TargetPoolForJob(job config.JobConfig, defaultScrapeInterval time.Duration) (targetPool *TargetPool) {
|
||||||
targetPool, ok := m.poolsByJob[job.Name]
|
targetPool, ok := m.poolsByJob[job.GetName()]
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
targetPool = NewTargetPool(m)
|
targetPool = NewTargetPool(m)
|
||||||
log.Printf("Pool for job %s does not exist; creating and starting...", job.Name)
|
log.Printf("Pool for job %s does not exist; creating and starting...", job.GetName())
|
||||||
|
|
||||||
interval := job.ScrapeInterval
|
interval := job.ScrapeInterval()
|
||||||
if interval == 0 {
|
m.poolsByJob[job.GetName()] = targetPool
|
||||||
interval = defaultScrapeInterval
|
|
||||||
}
|
|
||||||
m.poolsByJob[job.Name] = targetPool
|
|
||||||
go targetPool.Run(m.results, interval)
|
go targetPool.Run(m.results, interval)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *targetManager) AddTarget(job *config.JobConfig, t Target, defaultScrapeInterval time.Duration) {
|
func (m *targetManager) AddTarget(job config.JobConfig, t Target, defaultScrapeInterval time.Duration) {
|
||||||
targetPool := m.TargetPoolForJob(job, defaultScrapeInterval)
|
targetPool := m.TargetPoolForJob(job, defaultScrapeInterval)
|
||||||
targetPool.AddTarget(t)
|
targetPool.AddTarget(t)
|
||||||
m.poolsByJob[job.Name] = targetPool
|
m.poolsByJob[job.GetName()] = targetPool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *targetManager) ReplaceTargets(job *config.JobConfig, newTargets []Target, defaultScrapeInterval time.Duration) {
|
func (m *targetManager) ReplaceTargets(job config.JobConfig, newTargets []Target, defaultScrapeInterval time.Duration) {
|
||||||
targetPool := m.TargetPoolForJob(job, defaultScrapeInterval)
|
targetPool := m.TargetPoolForJob(job, defaultScrapeInterval)
|
||||||
targetPool.replaceTargets(newTargets)
|
targetPool.replaceTargets(newTargets)
|
||||||
}
|
}
|
||||||
|
@ -85,19 +82,21 @@ func (m targetManager) Remove(t Target) {
|
||||||
panic("not implemented")
|
panic("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *targetManager) AddTargetsFromConfig(config *config.Config) {
|
func (m *targetManager) AddTargetsFromConfig(config config.Config) {
|
||||||
for _, job := range config.Jobs {
|
for _, job := range config.Jobs() {
|
||||||
for _, configTargets := range job.Targets {
|
for _, targetGroup := range job.TargetGroup {
|
||||||
baseLabels := model.LabelSet{
|
baseLabels := model.LabelSet{
|
||||||
model.JobLabel: model.LabelValue(job.Name),
|
model.JobLabel: model.LabelValue(job.GetName()),
|
||||||
}
|
}
|
||||||
for label, value := range configTargets.Labels {
|
if targetGroup.Labels != nil {
|
||||||
baseLabels[label] = value
|
for _, label := range targetGroup.Labels.Label {
|
||||||
|
baseLabels[model.LabelName(label.GetName())] = model.LabelValue(label.GetValue())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, endpoint := range configTargets.Endpoints {
|
for _, endpoint := range targetGroup.Target {
|
||||||
target := NewTarget(endpoint, time.Second*5, baseLabels)
|
target := NewTarget(endpoint, time.Second*5, baseLabels)
|
||||||
m.AddTarget(&job, target, config.Global.ScrapeInterval)
|
m.AddTarget(job, target, config.ScrapeInterval())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,9 @@
|
||||||
package retrieval
|
package retrieval
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"code.google.com/p/goprotobuf/proto"
|
||||||
"github.com/prometheus/prometheus/config"
|
"github.com/prometheus/prometheus/config"
|
||||||
|
pb "github.com/prometheus/prometheus/config/generated"
|
||||||
"github.com/prometheus/prometheus/model"
|
"github.com/prometheus/prometheus/model"
|
||||||
"github.com/prometheus/prometheus/retrieval/format"
|
"github.com/prometheus/prometheus/retrieval/format"
|
||||||
"github.com/prometheus/prometheus/utility/test"
|
"github.com/prometheus/prometheus/utility/test"
|
||||||
|
@ -67,11 +69,17 @@ func (t *fakeTarget) Merge(newTarget Target) {}
|
||||||
func testTargetManager(t test.Tester) {
|
func testTargetManager(t test.Tester) {
|
||||||
results := make(chan format.Result, 5)
|
results := make(chan format.Result, 5)
|
||||||
targetManager := NewTargetManager(results, 3)
|
targetManager := NewTargetManager(results, 3)
|
||||||
testJob1 := &config.JobConfig{
|
testJob1 := config.JobConfig{
|
||||||
Name: "test_job1",
|
JobConfig: pb.JobConfig{
|
||||||
|
Name: proto.String("test_job1"),
|
||||||
|
ScrapeInterval: proto.String("1m"),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
testJob2 := &config.JobConfig{
|
testJob2 := config.JobConfig{
|
||||||
Name: "test_job2",
|
JobConfig: pb.JobConfig{
|
||||||
|
Name: proto.String("test_job2"),
|
||||||
|
ScrapeInterval: proto.String("1m"),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
target1GroupA := &fakeTarget{
|
target1GroupA := &fakeTarget{
|
||||||
|
|
|
@ -27,7 +27,7 @@ type Result struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RuleManager interface {
|
type RuleManager interface {
|
||||||
AddRulesFromConfig(config *config.Config) error
|
AddRulesFromConfig(config config.Config) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type ruleManager struct {
|
type ruleManager struct {
|
||||||
|
@ -87,8 +87,8 @@ func (m *ruleManager) runIteration(results chan *Result) {
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ruleManager) AddRulesFromConfig(config *config.Config) error {
|
func (m *ruleManager) AddRulesFromConfig(config config.Config) error {
|
||||||
for _, ruleFile := range config.Global.RuleFiles {
|
for _, ruleFile := range config.Global.RuleFile {
|
||||||
newRules, err := LoadRulesFromFile(ruleFile)
|
newRules, err := LoadRulesFromFile(ruleFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -34,7 +34,7 @@ func (serv MetricsService) SetTargets(targetGroups []TargetGroup, jobName string
|
||||||
for _, targetGroup := range targetGroups {
|
for _, targetGroup := range targetGroups {
|
||||||
// Do mandatory map type conversion due to Go shortcomings.
|
// Do mandatory map type conversion due to Go shortcomings.
|
||||||
baseLabels := model.LabelSet{
|
baseLabels := model.LabelSet{
|
||||||
model.JobLabel: model.LabelValue(job.Name),
|
model.JobLabel: model.LabelValue(job.GetName()),
|
||||||
}
|
}
|
||||||
for label, value := range targetGroup.BaseLabels {
|
for label, value := range targetGroup.BaseLabels {
|
||||||
baseLabels[model.LabelName(label)] = model.LabelValue(value)
|
baseLabels[model.LabelName(label)] = model.LabelValue(value)
|
||||||
|
@ -45,6 +45,6 @@ func (serv MetricsService) SetTargets(targetGroups []TargetGroup, jobName string
|
||||||
newTargets = append(newTargets, newTarget)
|
newTargets = append(newTargets, newTarget)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
serv.appState.TargetManager.ReplaceTargets(job, newTargets, serv.appState.Config.Global.ScrapeInterval)
|
serv.appState.TargetManager.ReplaceTargets(*job, newTargets, serv.appState.Config.ScrapeInterval())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ func (h *StatusHandler) Run() {
|
||||||
})
|
})
|
||||||
|
|
||||||
h.PrometheusStatus = &PrometheusStatus{
|
h.PrometheusStatus = &PrometheusStatus{
|
||||||
Config: h.appState.Config.ToString(0),
|
Config: h.appState.Config.String(),
|
||||||
Rules: "TODO: list rules here",
|
Rules: "TODO: list rules here",
|
||||||
Status: "TODO: add status information here",
|
Status: "TODO: add status information here",
|
||||||
TargetPools: h.appState.TargetManager.Pools(),
|
TargetPools: h.appState.TargetManager.Pools(),
|
||||||
|
|
Loading…
Reference in a new issue