From e7899d4dc531b547b74caea8a550d95461dad4c6 Mon Sep 17 00:00:00 2001 From: Nathan D Acuff Date: Wed, 7 Sep 2016 04:39:55 -0400 Subject: [PATCH] Postgresql database blacklist configuration option (#1699) * separate hello and authenticate functions, force connection close at end of write cycle so we don't hold open idle connections, which has the benefit of mostly removing the chance of getting hopelessly connection lost * update changelog, though this will need to be updated again to merge into telegraf master * bump instrumental agent version * fix test to deal with better better connect/reconnect logic and changed ident & auth handshake * Update CHANGELOG.md correct URL from instrumental fork to origin and put the change in the correct part of the file * go fmt * Split out Instrumental tests for invalid metric and value. * Ensure nothing remains on the wire after final test. * Force valid metric names by replacing invalid parts with underscores. * Multiple invalid characters being joined into a single udnerscore. * Adjust comment to what happens. * undo split hello and auth commands, to reduce roundtrips * Add ignored_databases option to postgresql configuration files, to enable easy filtering of system databases without needing to whitelist all the databases on the server. Add tests for database whitelist and blacklist. * run go fmt on new postgresql database whitelist/blacklist code * add postgresql database blacklist option to changelog * remove a bad merge from the changelog --- CHANGELOG.md | 1 + plugins/inputs/postgresql/postgresql.go | 12 +++- plugins/inputs/postgresql/postgresql_test.go | 72 ++++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3084fc3a..65216e9f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - [#1599](https://github.com/influxdata/telegraf/pull/1599): Add server hostname for each docker measurements. - [#1697](https://github.com/influxdata/telegraf/pull/1697): Add NATS output plugin. - [#1407](https://github.com/influxdata/telegraf/pull/1407): HTTP service listener input plugin. +- [#1699](https://github.com/influxdata/telegraf/pull/1699): Add database blacklist option for Postgresql ### Bugfixes diff --git a/plugins/inputs/postgresql/postgresql.go b/plugins/inputs/postgresql/postgresql.go index da8ee8001..0e7cdb509 100644 --- a/plugins/inputs/postgresql/postgresql.go +++ b/plugins/inputs/postgresql/postgresql.go @@ -17,6 +17,7 @@ import ( type Postgresql struct { Address string Databases []string + IgnoredDatabases []string OrderedColumns []string AllColumns []string sanitizedAddress string @@ -40,8 +41,12 @@ var sampleConfig = ` ## address = "host=localhost user=postgres sslmode=disable" + ## A list of databases to explicitly ignore. If not specified, metrics for all + ## databases are gathered. Do NOT use with the 'databases' option. + # ignored_databases = ["postgres", "template0", "template1"] + ## A list of databases to pull metrics about. If not specified, metrics for all - ## databases are gathered. + ## databases are gathered. Do NOT use with the 'ignore_databases' option. # databases = ["app_production", "testing"] ` @@ -73,8 +78,11 @@ func (p *Postgresql) Gather(acc telegraf.Accumulator) error { defer db.Close() - if len(p.Databases) == 0 { + if len(p.Databases) == 0 && len(p.IgnoredDatabases) == 0 { query = `SELECT * FROM pg_stat_database` + } else if len(p.IgnoredDatabases) != 0 { + query = fmt.Sprintf(`SELECT * FROM pg_stat_database WHERE datname NOT IN ('%s')`, + strings.Join(p.IgnoredDatabases, "','")) } else { query = fmt.Sprintf(`SELECT * FROM pg_stat_database WHERE datname IN ('%s')`, strings.Join(p.Databases, "','")) diff --git a/plugins/inputs/postgresql/postgresql_test.go b/plugins/inputs/postgresql/postgresql_test.go index 552b18cdb..64926f61e 100644 --- a/plugins/inputs/postgresql/postgresql_test.go +++ b/plugins/inputs/postgresql/postgresql_test.go @@ -150,3 +150,75 @@ func TestPostgresqlIgnoresUnwantedColumns(t *testing.T) { assert.False(t, acc.HasMeasurement(col)) } } + +func TestPostgresqlDatabaseWhitelistTest(t *testing.T) { + if testing.Short() { + t.Skip("Skipping integration test in short mode") + } + + p := &Postgresql{ + Address: fmt.Sprintf("host=%s user=postgres sslmode=disable", + testutil.GetLocalHost()), + Databases: []string{"template0"}, + } + + var acc testutil.Accumulator + + err := p.Gather(&acc) + require.NoError(t, err) + + var foundTemplate0 = false + var foundTemplate1 = false + + for _, pnt := range acc.Metrics { + if pnt.Measurement == "postgresql" { + if pnt.Tags["db"] == "template0" { + foundTemplate0 = true + } + } + if pnt.Measurement == "postgresql" { + if pnt.Tags["db"] == "template1" { + foundTemplate1 = true + } + } + } + + assert.True(t, foundTemplate0) + assert.False(t, foundTemplate1) +} + +func TestPostgresqlDatabaseBlacklistTest(t *testing.T) { + if testing.Short() { + t.Skip("Skipping integration test in short mode") + } + + p := &Postgresql{ + Address: fmt.Sprintf("host=%s user=postgres sslmode=disable", + testutil.GetLocalHost()), + IgnoredDatabases: []string{"template0"}, + } + + var acc testutil.Accumulator + + err := p.Gather(&acc) + require.NoError(t, err) + + var foundTemplate0 = false + var foundTemplate1 = false + + for _, pnt := range acc.Metrics { + if pnt.Measurement == "postgresql" { + if pnt.Tags["db"] == "template0" { + foundTemplate0 = true + } + } + if pnt.Measurement == "postgresql" { + if pnt.Tags["db"] == "template1" { + foundTemplate1 = true + } + } + } + + assert.False(t, foundTemplate0) + assert.True(t, foundTemplate1) +}