Retrieval: Make it possible to relabel query params

This only allows relabelling the first value
for a given parameter, this should be sufficient in practice.
This commit is contained in:
Brian Brazil 2015-07-05 20:25:45 +01:00
parent 17eebbc3b4
commit d8875d17d8
6 changed files with 91 additions and 15 deletions

12
Godeps/Godeps.json generated
View File

@ -44,23 +44,19 @@
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/extraction", "ImportPath": "github.com/prometheus/client_golang/extraction",
"Comment": "0.7.0", "Rev": "3a499bf7fc46bc58337ce612d0cbb29c550b8118"
"Rev": "6dbab8106ed3ed77359ac85d9cf08e30290df864"
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/model", "ImportPath": "github.com/prometheus/client_golang/model",
"Comment": "0.7.0", "Rev": "3a499bf7fc46bc58337ce612d0cbb29c550b8118"
"Rev": "6dbab8106ed3ed77359ac85d9cf08e30290df864"
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/prometheus", "ImportPath": "github.com/prometheus/client_golang/prometheus",
"Comment": "0.7.0", "Rev": "3a499bf7fc46bc58337ce612d0cbb29c550b8118"
"Rev": "6dbab8106ed3ed77359ac85d9cf08e30290df864"
}, },
{ {
"ImportPath": "github.com/prometheus/client_golang/text", "ImportPath": "github.com/prometheus/client_golang/text",
"Comment": "0.7.0", "Rev": "3a499bf7fc46bc58337ce612d0cbb29c550b8118"
"Rev": "6dbab8106ed3ed77359ac85d9cf08e30290df864"
}, },
{ {
"ImportPath": "github.com/prometheus/client_model/go", "ImportPath": "github.com/prometheus/client_model/go",

View File

@ -46,6 +46,10 @@ const (
// will not be attached to time series. // will not be attached to time series.
MetaLabelPrefix = "__meta_" MetaLabelPrefix = "__meta_"
// ParamLabelPrefix is a prefix for labels that provide URL parameters
// used to scrape a target.
ParamLabelPrefix = "__param_"
// JobLabel is the label name indicating the job from which a timeseries // JobLabel is the label name indicating the job from which a timeseries
// was scraped. // was scraped.
JobLabel LabelName = "job" JobLabel LabelName = "job"

View File

@ -197,10 +197,24 @@ func (t *Target) Update(cfg *config.ScrapeConfig, baseLabels, metaLabels clientm
t.url.Scheme = cfg.Scheme t.url.Scheme = cfg.Scheme
t.url.Path = string(baseLabels[clientmodel.MetricsPathLabel]) t.url.Path = string(baseLabels[clientmodel.MetricsPathLabel])
params := url.Values{}
for k, v := range cfg.Params {
params[k] = make([]string, len(v))
copy(params[k], v)
}
for k, v := range baseLabels {
if strings.HasPrefix(string(k), clientmodel.ParamLabelPrefix) {
if len(params[string(k[len(clientmodel.ParamLabelPrefix):])]) > 0 {
params[string(k[len(clientmodel.ParamLabelPrefix):])][0] = string(v)
} else {
params[string(k[len(clientmodel.ParamLabelPrefix):])] = []string{string(v)}
}
}
}
t.url.RawQuery = params.Encode()
if cfg.BasicAuth != nil { if cfg.BasicAuth != nil {
t.url.User = url.UserPassword(cfg.BasicAuth.Username, cfg.BasicAuth.Password) t.url.User = url.UserPassword(cfg.BasicAuth.Username, cfg.BasicAuth.Password)
} }
t.url.RawQuery = cfg.Params.Encode()
t.scrapeInterval = time.Duration(cfg.ScrapeInterval) t.scrapeInterval = time.Duration(cfg.ScrapeInterval)
t.deadline = time.Duration(cfg.ScrapeTimeout) t.deadline = time.Duration(cfg.ScrapeTimeout)

View File

@ -390,6 +390,49 @@ func BenchmarkScrape(b *testing.B) {
} }
} }
func TestURLParams(t *testing.T) {
server := httptest.NewServer(
http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", `text/plain; version=0.0.4`)
w.Write([]byte{})
r.ParseForm()
if r.Form["foo"][0] != "bar" {
t.Fatalf("URL parameter 'foo' had unexpected first value '%v'", r.Form["foo"][0])
}
if r.Form["foo"][1] != "baz" {
t.Fatalf("URL parameter 'foo' had unexpected second value '%v'", r.Form["foo"][1])
}
},
),
)
defer server.Close()
serverURL, err := url.Parse(server.URL)
if err != nil {
t.Fatal(err)
}
target := NewTarget(
&config.ScrapeConfig{
JobName: "test_job1",
ScrapeInterval: config.Duration(1 * time.Minute),
ScrapeTimeout: config.Duration(1 * time.Second),
Scheme: serverURL.Scheme,
Params: url.Values{
"foo": []string{"bar", "baz"},
},
},
clientmodel.LabelSet{
clientmodel.AddressLabel: clientmodel.LabelValue(serverURL.Host),
"__param_foo": "bar",
},
nil)
app := &collectResultAppender{}
if err = target.scrape(app); err != nil {
t.Fatal(err)
}
}
func newTestTarget(targetURL string, deadline time.Duration, baseLabels clientmodel.LabelSet) *Target { func newTestTarget(targetURL string, deadline time.Duration, baseLabels clientmodel.LabelSet) *Target {
t := &Target{ t := &Target{
url: &url.URL{ url: &url.URL{

View File

@ -329,6 +329,11 @@ func (tm *TargetManager) targetsFromGroup(tg *config.TargetGroup, cfg *config.Sc
} }
labels[clientmodel.AddressLabel] = clientmodel.LabelValue(addr) labels[clientmodel.AddressLabel] = clientmodel.LabelValue(addr)
} }
for k, v := range cfg.Params {
if len(v) > 0 {
labels[clientmodel.LabelName(clientmodel.ParamLabelPrefix+k)] = clientmodel.LabelValue(v[0])
}
}
// Copy labels into the labelset for the target if they are not // Copy labels into the labelset for the target if they are not
// set already. Apply the labelsets in order of decreasing precedence. // set already. Apply the labelsets in order of decreasing precedence.
labelsets := []clientmodel.LabelSet{ labelsets := []clientmodel.LabelSet{

View File

@ -14,6 +14,7 @@
package retrieval package retrieval
import ( import (
"net/url"
"reflect" "reflect"
"regexp" "regexp"
"testing" "testing"
@ -157,12 +158,25 @@ func TestTargetManagerConfigUpdate(t *testing.T) {
testJob1 := &config.ScrapeConfig{ testJob1 := &config.ScrapeConfig{
JobName: "test_job1", JobName: "test_job1",
ScrapeInterval: config.Duration(1 * time.Minute), ScrapeInterval: config.Duration(1 * time.Minute),
Params: url.Values{
"testParam": []string{"paramValue", "secondValue"},
},
TargetGroups: []*config.TargetGroup{{ TargetGroups: []*config.TargetGroup{{
Targets: []clientmodel.LabelSet{ Targets: []clientmodel.LabelSet{
{clientmodel.AddressLabel: "example.org:80"}, {clientmodel.AddressLabel: "example.org:80"},
{clientmodel.AddressLabel: "example.com:80"}, {clientmodel.AddressLabel: "example.com:80"},
}, },
}}, }},
RelabelConfigs: []*config.RelabelConfig{
{
// Copy out the URL parameter.
SourceLabels: clientmodel.LabelNames{"__param_testParam"},
Regex: &config.Regexp{*regexp.MustCompile("^(.*)$")},
TargetLabel: "testParam",
Replacement: "$1",
Action: config.RelabelReplace,
},
},
} }
testJob2 := &config.ScrapeConfig{ testJob2 := &config.ScrapeConfig{
JobName: "test_job2", JobName: "test_job2",
@ -226,24 +240,24 @@ func TestTargetManagerConfigUpdate(t *testing.T) {
scrapeConfigs: []*config.ScrapeConfig{testJob1}, scrapeConfigs: []*config.ScrapeConfig{testJob1},
expected: map[string][]clientmodel.LabelSet{ expected: map[string][]clientmodel.LabelSet{
"test_job1:static:0": { "test_job1:static:0": {
{clientmodel.JobLabel: "test_job1", clientmodel.InstanceLabel: "example.org:80"}, {clientmodel.JobLabel: "test_job1", clientmodel.InstanceLabel: "example.org:80", "testParam": "paramValue"},
{clientmodel.JobLabel: "test_job1", clientmodel.InstanceLabel: "example.com:80"}, {clientmodel.JobLabel: "test_job1", clientmodel.InstanceLabel: "example.com:80", "testParam": "paramValue"},
}, },
}, },
}, { }, {
scrapeConfigs: []*config.ScrapeConfig{testJob1}, scrapeConfigs: []*config.ScrapeConfig{testJob1},
expected: map[string][]clientmodel.LabelSet{ expected: map[string][]clientmodel.LabelSet{
"test_job1:static:0": { "test_job1:static:0": {
{clientmodel.JobLabel: "test_job1", clientmodel.InstanceLabel: "example.org:80"}, {clientmodel.JobLabel: "test_job1", clientmodel.InstanceLabel: "example.org:80", "testParam": "paramValue"},
{clientmodel.JobLabel: "test_job1", clientmodel.InstanceLabel: "example.com:80"}, {clientmodel.JobLabel: "test_job1", clientmodel.InstanceLabel: "example.com:80", "testParam": "paramValue"},
}, },
}, },
}, { }, {
scrapeConfigs: []*config.ScrapeConfig{testJob1, testJob2}, scrapeConfigs: []*config.ScrapeConfig{testJob1, testJob2},
expected: map[string][]clientmodel.LabelSet{ expected: map[string][]clientmodel.LabelSet{
"test_job1:static:0": { "test_job1:static:0": {
{clientmodel.JobLabel: "test_job1", clientmodel.InstanceLabel: "example.org:80"}, {clientmodel.JobLabel: "test_job1", clientmodel.InstanceLabel: "example.org:80", "testParam": "paramValue"},
{clientmodel.JobLabel: "test_job1", clientmodel.InstanceLabel: "example.com:80"}, {clientmodel.JobLabel: "test_job1", clientmodel.InstanceLabel: "example.com:80", "testParam": "paramValue"},
}, },
"test_job2:static:0": { "test_job2:static:0": {
{clientmodel.JobLabel: "test_job2", clientmodel.InstanceLabel: "example.org:8080", "foo": "bar", "new": "ox-ba"}, {clientmodel.JobLabel: "test_job2", clientmodel.InstanceLabel: "example.org:8080", "foo": "bar", "new": "ox-ba"},