diff --git a/README.md b/README.md index 53751f44..159fc7cf 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,21 @@ Name | Description | Enabled by default See the linked documentation on each collector for more information on reported metrics, configuration settings and usage examples. +### Filtering enabled collectors + +The `windows_exporter` will expose all metrics from enabled collectors by default. This is the recommended way to collect metrics to avoid errors when comparing metrics of different families. + +For advanced use the `windows_exporter` can be passed an optional list of collectors to filter metrics. The `collect[]` parameter may be used multiple times. In Prometheus configuration you can use this syntax under the [scrape config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#). + +``` + params: + collect[]: + - foo + - bar +``` + +This can be useful for having different Prometheus servers collect specific metrics from nodes. + ## Flags windows_exporter accepts flags to configure certain behaviours. The ones configuring the global behaviour of the exporter are listed below, while collector-specific ones are documented in the respective collector documentation above. diff --git a/exporter.go b/exporter.go index 9ecdb2da..1ef8b180 100644 --- a/exporter.go +++ b/exporter.go @@ -339,9 +339,21 @@ func main() { h := &metricsHandler{ timeoutMargin: *timeoutMargin, - collectorFactory: func(timeout time.Duration) *windowsCollector { - return &windowsCollector{ - collectors: collectors, + collectorFactory: func(timeout time.Duration, requestedCollectors []string) (error, *windowsCollector) { + filteredCollectors := make(map[string]collector.Collector) + // scrape all enabled collectors if no collector is requested + if len(requestedCollectors) == 0 { + filteredCollectors = collectors + } + for _, name := range requestedCollectors { + col, exists := collectors[name] + if !exists { + return fmt.Errorf("unavailable collector: %s", name), nil + } + filteredCollectors[name] = col + } + return nil, &windowsCollector{ + collectors: filteredCollectors, maxScrapeDuration: timeout, } }, @@ -455,7 +467,7 @@ loop: type metricsHandler struct { timeoutMargin float64 - collectorFactory func(timeout time.Duration) *windowsCollector + collectorFactory func(timeout time.Duration, requestedCollectors []string) (error, *windowsCollector) } func (mh *metricsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -475,7 +487,14 @@ func (mh *metricsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { timeoutSeconds = timeoutSeconds - mh.timeoutMargin reg := prometheus.NewRegistry() - reg.MustRegister(mh.collectorFactory(time.Duration(timeoutSeconds * float64(time.Second)))) + err, wc := mh.collectorFactory(time.Duration(timeoutSeconds*float64(time.Second)), r.URL.Query()["collect[]"]) + if err != nil { + log.Warnln("Couldn't create filtered metrics handler: ", err) + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(fmt.Sprintf("Couldn't create filtered metrics handler: %s", err))) + return + } + reg.MustRegister(wc) reg.MustRegister( prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}), prometheus.NewGoCollector(),