Skip to content

Commit

Permalink
Make Prometheus Collector Filter Custom Metrics
Browse files Browse the repository at this point in the history
Previously, the Prometheus collector ignored the
`MetricsConfig` field of the custom metrics specification,
simply storing all exposed metrics.  Now, if the `MetricsConfig`
field contains any metric names, only those metrics will be stored
and exposed.

Fixes google#1005
  • Loading branch information
DirectXMan12 committed Dec 10, 2015
1 parent 97ad511 commit d11dd29
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 1 deletion.
8 changes: 8 additions & 0 deletions collector/config/sample_config_prometheus_filtered.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"endpoint" : "http://localhost:8080/metrics",
"polling_frequency" : 10,
"metrics_config" : [
"go_goroutines"
]
}

21 changes: 20 additions & 1 deletion collector/prometheus_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ type PrometheusCollector struct {

//holds information extracted from the config file for a collector
configFile Prometheus

// the metrics to gather (uses a map as a set)
metricsSet map[string]bool
}

//Returns a new collector using the information extracted from the configfile
Expand All @@ -54,11 +57,20 @@ func NewPrometheusCollector(collectorName string, configFile []byte) (*Prometheu
minPollingFrequency = minSupportedFrequency
}

var metricsSet map[string]bool
if len(configInJSON.MetricsConfig) > 0 {
metricsSet = make(map[string]bool, len(configInJSON.MetricsConfig))
for _, name := range configInJSON.MetricsConfig {
metricsSet[name] = true
}
}

//TODO : Add checks for validity of config file (eg : Accurate JSON fields)
return &PrometheusCollector{
name: collectorName,
pollingFrequency: minPollingFrequency,
configFile: configInJSON,
metricsSet: metricsSet,
}, nil
}

Expand Down Expand Up @@ -100,8 +112,12 @@ func (collector *PrometheusCollector) GetSpec() []v1.MetricSpec {
if stopIndex == -1 {
stopIndex = strings.Index(lines[i+2], " ")
}
name := strings.TrimSpace(lines[i+2][0:stopIndex])
if _, ok := collector.metricsSet[name]; collector.metricsSet != nil && !ok {
continue
}
spec := v1.MetricSpec{
Name: strings.TrimSpace(lines[i+2][0:stopIndex]),
Name: name,
Type: v1.MetricType(getMetricData(lines[i+1])),
Format: "float",
Units: getMetricData(lines[i]),
Expand Down Expand Up @@ -145,6 +161,9 @@ func (collector *PrometheusCollector) Collect(metrics map[string][]v1.MetricVal)
}

metName := strings.TrimSpace(line[0:startLabelIndex])
if _, ok := collector.metricsSet[metName]; collector.metricsSet != nil && !ok {
continue
}

if startLabelIndex+1 <= spaceIndex-1 {
metLabel = strings.TrimSpace(line[(startLabelIndex + 1):(spaceIndex - 1)])
Expand Down
35 changes: 35 additions & 0 deletions collector/prometheus_collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,38 @@ func TestPrometheus(t *testing.T) {
goRoutines := metrics["go_goroutines"]
assert.Equal(goRoutines[0].FloatValue, 16)
}

func TestPrometheusFiltersMetrics(t *testing.T) {
assert := assert.New(t)

//Create a prometheus collector using the config file 'sample_config_prometheus_filtered.json'
configFile, err := ioutil.ReadFile("config/sample_config_prometheus_filtered.json")
collector, err := NewPrometheusCollector("Prometheus", configFile)
assert.NoError(err)
assert.Equal(collector.name, "Prometheus")
assert.Equal(collector.configFile.Endpoint, "http://localhost:8080/metrics")

tempServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

text := "# HELP go_gc_duration_seconds A summary of the GC invocation durations.\n"
text += "# TYPE go_gc_duration_seconds summary\n"
text += "go_gc_duration_seconds{quantile=\"0\"} 5.8348000000000004e-05\n"
text += "go_gc_duration_seconds{quantile=\"1\"} 0.000499764\n"
text += "# HELP go_goroutines Number of goroutines that currently exist.\n"
text += "# TYPE go_goroutines gauge\n"
text += "go_goroutines 16"
fmt.Fprintln(w, text)
}))

defer tempServer.Close()

collector.configFile.Endpoint = tempServer.URL
metrics := map[string][]v1.MetricVal{}
_, metrics, errMetric := collector.Collect(metrics)

assert.NoError(errMetric)
assert.Len(metrics, 1)

goRoutines := metrics["go_goroutines"]
assert.Equal(goRoutines[0].FloatValue, 16)
}

0 comments on commit d11dd29

Please sign in to comment.