From 97c4780bc8c89b8cc0988c0acee8e22dab6792fb Mon Sep 17 00:00:00 2001 From: Marc Falzon Date: Fri, 1 Mar 2019 16:12:47 +0100 Subject: [PATCH] metrics: add collectd exporter metrics excluding [ch1233] (#5) This change allows the `collectd` metrics exporter to be configured to exclude specific metrics using a pattern matching system. --- README.md | 8 +++++++- metrics/collectd.go | 15 +++++++++++++-- metrics/collectd_test.go | 11 +++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 56fc592..739ecd3 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ It can also be configured through a YAML file. Currently, due to a technical limitation, if a key is unknown, it will just be ignored. Be extra-careful that all keys are correctly spelled. -## Yaml +## Configuration The reporter encompasses the following aspects, each of them having its own subsection: @@ -69,6 +69,11 @@ reporting: metrics: - expvar: listen: 127.0.0.1:8123 + - collectd: + connect: 127.0.0.1:25826 + interval: 10s + exclude: + - go.runtime.* ``` The support outputs are: @@ -107,6 +112,7 @@ The ``collectd`` output supports the following keys: - ``connect`` to specify the target (default to ``127.0.0.1:25826``) - ``interval`` to specify an interval (mandatory) + - ``exclude`` to specify a list of metric names patterns (shell globbing) to exclude from reporting For collectd output to work correctly, you need to append the following to ``types.db`` file:: diff --git a/metrics/collectd.go b/metrics/collectd.go index 29a650a..74c37a7 100644 --- a/metrics/collectd.go +++ b/metrics/collectd.go @@ -3,6 +3,7 @@ package metrics import ( "context" "os" + "path" "strings" "time" @@ -21,6 +22,7 @@ var separator = "." type CollectdConfiguration struct { Connect config.Addr Interval config.Duration + Exclude []string } // UnmarshalYAML parses a configuration for collectd from YAML. @@ -55,7 +57,7 @@ func (c *CollectdConfiguration) initExporter(m *Metrics) error { for { select { case <-tick.C: - collectdReportOnce(m.Registry, client, time.Duration(c.Interval), m.prefix) + collectdReportOnce(m.Registry, client, time.Duration(c.Interval), m.prefix, c.Exclude) case <-m.t.Dying(): break L } @@ -69,7 +71,8 @@ func (c *CollectdConfiguration) initExporter(m *Metrics) error { } // collectdReportOnce will export the current metrics to collectd -func collectdReportOnce(r metrics.Registry, client *network.Client, interval time.Duration, prefix string) { +func collectdReportOnce(r metrics.Registry, client *network.Client, interval time.Duration, + prefix string, excluded []string) { ctx := context.Background() hostname, err := os.Hostname() if err != nil { @@ -78,6 +81,14 @@ func collectdReportOnce(r metrics.Registry, client *network.Client, interval tim now := time.Now() vls := make([]*api.ValueList, 0, 10) r.Each(func(name string, i interface{}) { + // Filter metrics matching any configured pattern + // Any error parsing an exclusion pattern is silently ignored. + for _, pattern := range excluded { + if matched, _ := path.Match(pattern, name); matched { + return + } + } + var identifierType string var values []api.Value switch metric := i.(type) { diff --git a/metrics/collectd_test.go b/metrics/collectd_test.go index 1593704..f897409 100644 --- a/metrics/collectd_test.go +++ b/metrics/collectd_test.go @@ -39,6 +39,7 @@ func TestCollectd(t *testing.T) { configuration[0] = &CollectdConfiguration{ Connect: address, Interval: config.Duration(500 * time.Millisecond), + Exclude: []string{"metrics.test.donot*"}, } m, err := New(configuration, "project") if err != nil { @@ -55,6 +56,9 @@ func TestCollectd(t *testing.T) { metrics.NewUniformSample(10)).Update(1871) metrics.NewRegisteredMeter("metrics.test.meter", m.Registry).Mark(19) + // Create a metric that we'll exclude from reporting + metrics.NewRegisteredGauge("metrics.test.donotwant", m.Registry).Update(13) + // For timer, we would like to test percentiles too. 50 and 75 // percentile will be 16, but others will be 18. tt := metrics.NewRegisteredTimer("metrics.test.timer", m.Registry) @@ -193,6 +197,7 @@ L: }, }, } + for _, c := range cases { found := false var v *api.ValueList @@ -228,4 +233,10 @@ L: t.Errorf("Received metric %+v (-got +want):\n%s", v, diff) } } + + for _, v := range values { + if v.PluginInstance == "donotwant" { + t.Error("Excluded metric found in received metrics") + } + } }