retrieval: avoid race conditions

This commit is contained in:
Fabian Reinartz 2015-07-08 21:27:52 +02:00
parent 1d6d39a9ed
commit d53cc7935d

View file

@ -142,20 +142,17 @@ func (ts *TargetStatus) setLastError(err error) {
type Target struct { type Target struct {
// The status object for the target. It is only set once on initialization. // The status object for the target. It is only set once on initialization.
status *TargetStatus status *TargetStatus
// The HTTP client used to scrape the target's endpoint.
httpClient *http.Client
// Closing scraperStopping signals that scraping should stop. // Closing scraperStopping signals that scraping should stop.
scraperStopping chan struct{} scraperStopping chan struct{}
// Closing scraperStopped signals that scraping has been stopped. // Closing scraperStopped signals that scraping has been stopped.
scraperStopped chan struct{} scraperStopped chan struct{}
// Channel to buffer ingested samples. // Channel to buffer ingested samples.
ingestedSamples chan clientmodel.Samples ingestedSamples chan clientmodel.Samples
// Metric relabel configuration.
metricRelabelConfigs []*config.RelabelConfig
// Mutex protects the members below. // Mutex protects the members below.
sync.RWMutex sync.RWMutex
// The HTTP client used to scrape the target's endpoint.
httpClient *http.Client
// url is the URL to be scraped. Its host is immutable. // url is the URL to be scraped. Its host is immutable.
url *url.URL url *url.URL
// Labels before any processing. // Labels before any processing.
@ -169,6 +166,8 @@ type Target struct {
// Whether the target's labels have precedence over the base labels // Whether the target's labels have precedence over the base labels
// assigned by the scraping instance. // assigned by the scraping instance.
honorLabels bool honorLabels bool
// Metric relabel configuration.
metricRelabelConfigs []*config.RelabelConfig
} }
// NewTarget creates a reasonably configured target for querying. // NewTarget creates a reasonably configured target for querying.
@ -331,6 +330,14 @@ func (t *Target) scrape(sampleAppender storage.SampleAppender) (err error) {
start := time.Now() start := time.Now()
baseLabels := t.BaseLabels() baseLabels := t.BaseLabels()
t.RLock()
var (
honorLabels = t.honorLabels
httpClient = t.httpClient
metricRelabelConfigs = t.metricRelabelConfigs
)
t.RUnlock()
defer func() { defer func() {
t.status.setLastError(err) t.status.setLastError(err)
recordScrapeHealth(sampleAppender, clientmodel.TimestampFromTime(start), baseLabels, t.status.Health(), time.Since(start)) recordScrapeHealth(sampleAppender, clientmodel.TimestampFromTime(start), baseLabels, t.status.Health(), time.Since(start))
@ -342,7 +349,7 @@ func (t *Target) scrape(sampleAppender storage.SampleAppender) (err error) {
} }
req.Header.Add("Accept", acceptHeader) req.Header.Add("Accept", acceptHeader)
resp, err := t.httpClient.Do(req) resp, err := httpClient.Do(req)
if err != nil { if err != nil {
return err return err
} }
@ -368,7 +375,7 @@ func (t *Target) scrape(sampleAppender storage.SampleAppender) (err error) {
for samples := range t.ingestedSamples { for samples := range t.ingestedSamples {
for _, s := range samples { for _, s := range samples {
if t.honorLabels { if honorLabels {
// Merge the metric with the baseLabels for labels not already set in the // Merge the metric with the baseLabels for labels not already set in the
// metric. This also considers labels explicitly set to the empty string. // metric. This also considers labels explicitly set to the empty string.
for ln, lv := range baseLabels { for ln, lv := range baseLabels {
@ -387,10 +394,10 @@ func (t *Target) scrape(sampleAppender storage.SampleAppender) (err error) {
} }
} }
// Avoid the copy in Relabel if there are no configs. // Avoid the copy in Relabel if there are no configs.
if len(t.metricRelabelConfigs) > 0 { if len(metricRelabelConfigs) > 0 {
labels, err := Relabel(clientmodel.LabelSet(s.Metric), t.metricRelabelConfigs...) labels, err := Relabel(clientmodel.LabelSet(s.Metric), metricRelabelConfigs...)
if err != nil { if err != nil {
log.Errorf("Error while relabeling metric %s of instance %s: %s", s.Metric, t.url, err) log.Errorf("Error while relabeling metric %s of instance %s: %s", s.Metric, req.URL, err)
continue continue
} }
// Check if the timeseries was dropped. // Check if the timeseries was dropped.