diff --git a/retrieval/target.go b/retrieval/target.go index ddd0a0eb4..b0aaaf630 100644 --- a/retrieval/target.go +++ b/retrieval/target.go @@ -17,6 +17,7 @@ import ( "fmt" "math/rand" "net/http" + "net/url" "os" "strings" "sync" @@ -114,6 +115,8 @@ type Target interface { // points in this interface, this one is the best candidate to change given // the ways to express the endpoint. URL() string + // Used to populate the `instance` label in metrics. + InstanceIdentifier() string // The URL as seen from other hosts. References to localhost are resolved // to the address of the prometheus server. GlobalURL() string @@ -186,8 +189,8 @@ func (t *target) recordScrapeHealth(ingester extraction.Ingester, timestamp clie } healthMetric[clientmodel.MetricNameLabel] = clientmodel.LabelValue(scrapeHealthMetricName) durationMetric[clientmodel.MetricNameLabel] = clientmodel.LabelValue(scrapeDurationMetricName) - healthMetric[InstanceLabel] = clientmodel.LabelValue(t.URL()) - durationMetric[InstanceLabel] = clientmodel.LabelValue(t.URL()) + healthMetric[InstanceLabel] = clientmodel.LabelValue(t.InstanceIdentifier()) + durationMetric[InstanceLabel] = clientmodel.LabelValue(t.InstanceIdentifier()) healthValue := clientmodel.SampleValue(0) if healthy { @@ -320,7 +323,7 @@ func (t *target) scrape(ingester extraction.Ingester) (err error) { return err } - baseLabels := clientmodel.LabelSet{InstanceLabel: clientmodel.LabelValue(t.URL())} + baseLabels := clientmodel.LabelSet{InstanceLabel: clientmodel.LabelValue(t.InstanceIdentifier())} for baseLabel, baseValue := range t.baseLabels { baseLabels[baseLabel] = baseValue } @@ -363,6 +366,28 @@ func (t *target) URL() string { return t.url } +// InstanceIdentifier implements Target. +func (t *target) InstanceIdentifier() string { + u, err := url.Parse(t.url) + if err != nil { + glog.Warningf("Could not parse instance URL when generating identifier, using raw URL: %s", err) + return t.url + } + // If we are given a port in the host port, use that. + if strings.Contains(u.Host, ":") { + return u.Host + } + // Otherwise, deduce port based on protocol. + if u.Scheme == "http" { + return fmt.Sprintf("%s:80", u.Host) + } else if u.Scheme == "https" { + return fmt.Sprintf("%s:443", u.Host) + } + + glog.Warningf("Unknown scheme %s when generating identifier, using raw URL.", u.Scheme) + return t.url +} + // GlobalURL implements Target. func (t *target) GlobalURL() string { url := t.url diff --git a/retrieval/target_test.go b/retrieval/target_test.go index cb84ef7e4..ddea75ec4 100644 --- a/retrieval/target_test.go +++ b/retrieval/target_test.go @@ -34,6 +34,26 @@ func (i *collectResultIngester) Ingest(s clientmodel.Samples) error { return nil } +func TestTargetHidesURLAuth(t *testing.T) { + testVectors := []string{"http://secret:data@host.com/query?args#fragment", "https://example.net/foo", "http://foo.com:31337/bar"} + testResults := []string{"host.com:80", "example.net:443", "foo.com:31337"} + if len(testVectors) != len(testResults) { + t.Errorf("Test vector length does not match test result length.") + } + + for i := 0; i < len(testVectors); i++ { + testTarget := target{ + state: Unknown, + url: testVectors[i], + httpClient: utility.NewDeadlineClient(0), + } + u := testTarget.InstanceIdentifier() + if u != testResults[i] { + t.Errorf("Expected InstanceIdentifier to be %v, actual %v", testResults[i], u) + } + } +} + func TestTargetScrapeUpdatesState(t *testing.T) { testTarget := target{ state: Unknown, @@ -93,7 +113,7 @@ func TestTargetRecordScrapeHealth(t *testing.T) { expected := &clientmodel.Sample{ Metric: clientmodel.Metric{ clientmodel.MetricNameLabel: scrapeHealthMetricName, - InstanceLabel: "http://example.url", + InstanceLabel: "example.url:80", clientmodel.JobLabel: "testjob", }, Timestamp: now, @@ -108,7 +128,7 @@ func TestTargetRecordScrapeHealth(t *testing.T) { expected = &clientmodel.Sample{ Metric: clientmodel.Metric{ clientmodel.MetricNameLabel: scrapeDurationMetricName, - InstanceLabel: "http://example.url", + InstanceLabel: "example.url:80", clientmodel.JobLabel: "testjob", }, Timestamp: now, diff --git a/retrieval/targetmanager_test.go b/retrieval/targetmanager_test.go index fe1e97d49..e323a665b 100644 --- a/retrieval/targetmanager_test.go +++ b/retrieval/targetmanager_test.go @@ -42,6 +42,10 @@ func (t fakeTarget) URL() string { return "fake" } +func (t fakeTarget) InstanceIdentifier() string { + return "fake" +} + func (t fakeTarget) GlobalURL() string { return t.URL() }