|
|
|
@ -212,7 +212,9 @@ func (t *Target) Update(cfg *config.ScrapeConfig, baseLabels, metaLabels model.L
|
|
|
|
|
|
|
|
|
|
t.url.Scheme = string(baseLabels[model.SchemeLabel])
|
|
|
|
|
t.url.Path = string(baseLabels[model.MetricsPathLabel])
|
|
|
|
|
|
|
|
|
|
params := url.Values{}
|
|
|
|
|
|
|
|
|
|
for k, v := range cfg.Params {
|
|
|
|
|
params[k] = make([]string, len(v))
|
|
|
|
|
copy(params[k], v)
|
|
|
|
@ -402,22 +404,41 @@ func (t *Target) ingest(s model.Vector) error {
|
|
|
|
|
|
|
|
|
|
const acceptHeader = `application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited;q=0.7,text/plain;version=0.0.4;q=0.3,application/json;schema="prometheus/telemetry";version=0.0.2;q=0.2,*/*;q=0.1`
|
|
|
|
|
|
|
|
|
|
func (t *Target) scrape(sampleAppender storage.SampleAppender) (err error) {
|
|
|
|
|
func (t *Target) scrape(appender storage.SampleAppender) (err error) {
|
|
|
|
|
start := time.Now()
|
|
|
|
|
baseLabels := t.BaseLabels()
|
|
|
|
|
|
|
|
|
|
defer func(appender storage.SampleAppender) {
|
|
|
|
|
t.status.setLastError(err)
|
|
|
|
|
recordScrapeHealth(appender, start, baseLabels, t.status.Health(), time.Since(start))
|
|
|
|
|
}(appender)
|
|
|
|
|
|
|
|
|
|
t.RLock()
|
|
|
|
|
var (
|
|
|
|
|
honorLabels = t.honorLabels
|
|
|
|
|
httpClient = t.httpClient
|
|
|
|
|
metricRelabelConfigs = t.metricRelabelConfigs
|
|
|
|
|
)
|
|
|
|
|
t.RUnlock()
|
|
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
|
t.status.setLastError(err)
|
|
|
|
|
recordScrapeHealth(sampleAppender, start, baseLabels, t.status.Health(), time.Since(start))
|
|
|
|
|
}()
|
|
|
|
|
// The relabelAppender has to be inside the label-modifying appenders
|
|
|
|
|
// so the relabeling rules are applied to the correct label set.
|
|
|
|
|
if len(t.metricRelabelConfigs) > 0 {
|
|
|
|
|
appender = relabelAppender{
|
|
|
|
|
app: appender,
|
|
|
|
|
relabelings: t.metricRelabelConfigs,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if t.honorLabels {
|
|
|
|
|
appender = honorLabelsAppender{
|
|
|
|
|
app: appender,
|
|
|
|
|
labels: baseLabels,
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
appender = ruleLabelsAppender{
|
|
|
|
|
app: appender,
|
|
|
|
|
labels: baseLabels,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
httpClient := t.httpClient
|
|
|
|
|
|
|
|
|
|
t.RUnlock()
|
|
|
|
|
|
|
|
|
|
req, err := http.NewRequest("GET", t.URL().String(), nil)
|
|
|
|
|
if err != nil {
|
|
|
|
@ -450,7 +471,7 @@ func (t *Target) scrape(sampleAppender storage.SampleAppender) (err error) {
|
|
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
|
for {
|
|
|
|
|
// TODO(fabxc): Changex the SampleAppender interface to return an error
|
|
|
|
|
// TODO(fabxc): Change the SampleAppender interface to return an error
|
|
|
|
|
// so we can proceed based on the status and don't leak goroutines trying
|
|
|
|
|
// to append a single sample after dropping all the other ones.
|
|
|
|
|
//
|
|
|
|
@ -468,38 +489,7 @@ func (t *Target) scrape(sampleAppender storage.SampleAppender) (err error) {
|
|
|
|
|
|
|
|
|
|
for samples := range t.ingestedSamples {
|
|
|
|
|
for _, s := range samples {
|
|
|
|
|
if honorLabels {
|
|
|
|
|
// Merge the metric with the baseLabels for labels not already set in the
|
|
|
|
|
// metric. This also considers labels explicitly set to the empty string.
|
|
|
|
|
for ln, lv := range baseLabels {
|
|
|
|
|
if _, ok := s.Metric[ln]; !ok {
|
|
|
|
|
s.Metric[ln] = lv
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Merge the ingested metric with the base label set. On a collision the
|
|
|
|
|
// value of the label is stored in a label prefixed with the exported prefix.
|
|
|
|
|
for ln, lv := range baseLabels {
|
|
|
|
|
if v, ok := s.Metric[ln]; ok && v != "" {
|
|
|
|
|
s.Metric[model.ExportedLabelPrefix+ln] = v
|
|
|
|
|
}
|
|
|
|
|
s.Metric[ln] = lv
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Avoid the copy in Relabel if there are no configs.
|
|
|
|
|
if len(metricRelabelConfigs) > 0 {
|
|
|
|
|
labels, err := Relabel(model.LabelSet(s.Metric), metricRelabelConfigs...)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("Error while relabeling metric %s of instance %s: %s", s.Metric, req.URL, err)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
// Check if the timeseries was dropped.
|
|
|
|
|
if labels == nil {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
s.Metric = model.Metric(labels)
|
|
|
|
|
}
|
|
|
|
|
sampleAppender.Append(s)
|
|
|
|
|
appender.Append(s)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -509,10 +499,69 @@ func (t *Target) scrape(sampleAppender storage.SampleAppender) (err error) {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Merges the ingested sample's metric with the label set. On a collision the
|
|
|
|
|
// value of the ingested label is stored in a label prefixed with 'exported_'.
|
|
|
|
|
type ruleLabelsAppender struct {
|
|
|
|
|
app storage.SampleAppender
|
|
|
|
|
labels model.LabelSet
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (app ruleLabelsAppender) Append(s *model.Sample) {
|
|
|
|
|
for ln, lv := range app.labels {
|
|
|
|
|
if v, ok := s.Metric[ln]; ok && v != "" {
|
|
|
|
|
s.Metric[model.ExportedLabelPrefix+ln] = v
|
|
|
|
|
}
|
|
|
|
|
s.Metric[ln] = lv
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
app.app.Append(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type honorLabelsAppender struct {
|
|
|
|
|
app storage.SampleAppender
|
|
|
|
|
labels model.LabelSet
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Merges the sample's metric with the given labels if the label is not
|
|
|
|
|
// already present in the metric.
|
|
|
|
|
// This also considers labels explicitly set to the empty string.
|
|
|
|
|
func (app honorLabelsAppender) Append(s *model.Sample) {
|
|
|
|
|
for ln, lv := range app.labels {
|
|
|
|
|
if _, ok := s.Metric[ln]; !ok {
|
|
|
|
|
s.Metric[ln] = lv
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
app.app.Append(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Applies a set of relabel configurations to the sample's metric
|
|
|
|
|
// before actually appending it.
|
|
|
|
|
type relabelAppender struct {
|
|
|
|
|
app storage.SampleAppender
|
|
|
|
|
relabelings []*config.RelabelConfig
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (app relabelAppender) Append(s *model.Sample) {
|
|
|
|
|
labels, err := Relabel(model.LabelSet(s.Metric), app.relabelings...)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("Error while relabeling metric %s: %s", s.Metric, err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// Check if the timeseries was dropped.
|
|
|
|
|
if labels == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
s.Metric = model.Metric(labels)
|
|
|
|
|
|
|
|
|
|
app.app.Append(s)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// URL returns a copy of the target's URL.
|
|
|
|
|
func (t *Target) URL() *url.URL {
|
|
|
|
|
t.RLock()
|
|
|
|
|
defer t.RUnlock()
|
|
|
|
|
|
|
|
|
|
u := &url.URL{}
|
|
|
|
|
*u = *t.url
|
|
|
|
|
return u
|
|
|
|
|