From a66f0b54751e95a83c5c2d50cee375b5411d36fb Mon Sep 17 00:00:00 2001 From: Calle Pettersson Date: Sat, 4 Mar 2017 12:44:47 +0100 Subject: [PATCH] Add [defaults] placeholder support to collectors.enabled --- exporter.go | 27 ++++++++++++++++++++++---- exporter_test.go | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 exporter_test.go diff --git a/exporter.go b/exporter.go index e5837752..190b0274 100644 --- a/exporter.go +++ b/exporter.go @@ -25,8 +25,9 @@ type WmiCollector struct { } const ( - defaultCollectors = "cpu,cs,logical_disk,net,os,service,system" - serviceName = "wmi_exporter" + defaultCollectors = "cpu,cs,logical_disk,net,os,service,system" + defaultCollectorsPlaceholder = "[defaults]" + serviceName = "wmi_exporter" ) var ( @@ -90,9 +91,27 @@ func execute(name string, c collector.Collector, ch chan<- prometheus.Metric) { scrapeDurations.WithLabelValues(name, result).Observe(duration.Seconds()) } +func expandEnabledCollectors(enabled string) []string { + expanded := strings.Replace(enabled, defaultCollectorsPlaceholder, defaultCollectors, -1) + separated := strings.Split(expanded, ",") + unique := map[string]bool{} + for _, s := range separated { + if s != "" { + unique[s] = true + } + } + result := make([]string, 0, len(unique)) + for s, _ := range unique { + result = append(result, s) + } + return result +} + func loadCollectors(list string) (map[string]collector.Collector, error) { collectors := map[string]collector.Collector{} - for _, name := range strings.Split(list, ",") { + enabled := expandEnabledCollectors(list) + + for _, name := range enabled { fn, ok := collector.Factories[name] if !ok { return nil, fmt.Errorf("collector '%s' not available", name) @@ -115,7 +134,7 @@ func main() { showVersion = flag.Bool("version", false, "Print version information.") listenAddress = flag.String("telemetry.addr", ":9182", "host:port for WMI exporter.") metricsPath = flag.String("telemetry.path", "/metrics", "URL path for surfacing collected metrics.") - enabledCollectors = flag.String("collectors.enabled", filterAvailableCollectors(defaultCollectors), "Comma-separated list of collectors to use.") + enabledCollectors = flag.String("collectors.enabled", filterAvailableCollectors(defaultCollectors), "Comma-separated list of collectors to use. Use '[default]' as a placeholder for all the collectors enabled by default") printCollectors = flag.Bool("collectors.print", false, "If true, print available collectors and exit.") ) flag.Parse() diff --git a/exporter_test.go b/exporter_test.go new file mode 100644 index 00000000..475e09a1 --- /dev/null +++ b/exporter_test.go @@ -0,0 +1,49 @@ +package main + +import ( + "sort" + "strings" + "testing" +) + +type expansionTestCase struct { + input string + expectedOutput []string +} + +func TestExpandEnabled(t *testing.T) { + expansionTests := []expansionTestCase{ + {"", []string{}}, + // Default case + {"cs,os", []string{"cs", "os"}}, + // Placeholder expansion + {defaultCollectorsPlaceholder, strings.Split(defaultCollectors, ",")}, + // De-duplication + {"cs,cs", []string{"cs"}}, + // De-duplicate placeholder + {defaultCollectorsPlaceholder + "," + defaultCollectorsPlaceholder, strings.Split(defaultCollectors, ",")}, + // Composite case + {"foo," + defaultCollectorsPlaceholder + ",bar", append(strings.Split(defaultCollectors, ","), "foo", "bar")}, + } + + for _, testCase := range expansionTests { + output := expandEnabledCollectors(testCase.input) + sort.Strings(output) + + success := true + if len(output) != len(testCase.expectedOutput) { + success = false + } else { + sort.Strings(testCase.expectedOutput) + for idx := range output { + if output[idx] != testCase.expectedOutput[idx] { + success = false + break + } + } + } + if !success { + t.Error("For", testCase.input, "expected", testCase.expectedOutput, "got", output) + } + } +}