/* Create a http.HandlerFunc that is tied to r Registry such that requests against it generate a representation of the housed metrics. */ func (registry *Registry) YieldExporter() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var instrumentable metrics.InstrumentableCall = func() { requestCount.Increment(nil) url := r.URL if strings.HasSuffix(url.Path, jsonSuffix) { header := w.Header() header.Set(ProtocolVersionHeader, APIVersion) header.Set(contentTypeHeader, jsonContentType) writer := decorateWriter(r, w) // TODO(matt): Migrate to ioutil.NopCloser. if closer, ok := writer.(io.Closer); ok { defer closer.Close() } registry.dumpToWriter(writer) } else { w.WriteHeader(http.StatusNotFound) } } metrics.InstrumentCall(instrumentable, requestLatencyAccumulator) } }
func (t *target) Scrape(earliest time.Time, results chan format.Result) (err error) { defer func() { futureState := t.state switch err { case nil: futureState = ALIVE default: futureState = UNREACHABLE } t.scheduler.Reschedule(earliest, futureState) t.state = futureState }() done := make(chan bool) request := func() { defer func() { done <- true }() var resp *http.Response // Don't shadow "err" from the enclosing function. resp, err = http.Get(t.Address()) if err != nil { return } defer resp.Body.Close() processor, err := format.DefaultRegistry.ProcessorForRequestHeader(resp.Header) if err != nil { return } // XXX: This is a wart; we need to handle this more gracefully down the // road, especially once we have service discovery support. baseLabels := model.LabelSet{instance: model.LabelValue(t.Address())} for baseLabel, baseValue := range t.baseLabels { baseLabels[baseLabel] = baseValue } err = processor.Process(resp.Body, baseLabels, results) if err != nil { return } } accumulator := func(d time.Duration) { ms := float64(d) / float64(time.Millisecond) labels := map[string]string{address: t.Address(), outcome: success} if err != nil { labels[outcome] = failure } targetOperationLatencies.Add(labels, ms) targetOperations.Increment(labels) } go metrics.InstrumentCall(request, accumulator) select { case <-done: break case <-time.After(t.Deadline): err = fmt.Errorf("Target %s exceeded %s deadline.", t, t.Deadline) } return }