Skip to content
This repository was archived by the owner on Oct 23, 2024. It is now read-only.

Commit 41cf06f

Browse files
authored
Add sql and postgres monitors (#701)
The `sql` monitor will run queries against a relational database (PostgreSQL and MySQL currently supported) and derive metrics from the results. The `postgres` monitor is mostly a wrapper around the `sql` monitor that executes standard queries to pull general information about PostgreSQL server instances. It is meant to replace the `collectd/postgresql` monitor.
1 parent f0b6829 commit 41cf06f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+15057
-42
lines changed

docs/monitor-config.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ These are all of the monitors included in the agent, along with their possible c
9999
- [kubernetes-volumes](./monitors/kubernetes-volumes.md)
100100
- [memory](./monitors/memory.md)
101101
- [net-io](./monitors/net-io.md)
102+
- [postgresql](./monitors/postgresql.md)
102103
- [processlist](./monitors/processlist.md)
103104
- [prometheus-exporter](./monitors/prometheus-exporter.md)
104105
- [prometheus/go](./monitors/prometheus-go.md)
@@ -108,6 +109,7 @@ These are all of the monitors included in the agent, along with their possible c
108109
- [prometheus/prometheus](./monitors/prometheus-prometheus.md)
109110
- [prometheus/redis](./monitors/prometheus-redis.md)
110111
- [python-monitor](./monitors/python-monitor.md)
112+
- [sql](./monitors/sql.md)
111113
- [telegraf/logparser](./monitors/telegraf-logparser.md)
112114
- [telegraf/procstat](./monitors/telegraf-procstat.md)
113115
- [telegraf/snmp](./monitors/telegraf-snmp.md)

docs/monitors/collectd-postgresql.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
# collectd/postgresql
44

5+
**This monitor is deprecated in favor of the [postgresql monitor](./postgresql.md).**
6+
57
Monitors a PostgreSQL database server using collectd's
68
[PostgreSQL plugin](https://collectd.org/wiki/index.php/Plugin:PostgreSQL).
79

docs/monitors/postgresql.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<!--- GENERATED BY gomplate from scripts/docs/monitor-page.md.tmpl --->
2+
3+
# postgresql
4+
5+
This monitor pulls metrics from all PostgreSQL databases from a specific
6+
Postgres server instance. It pulls basic information that is applicable
7+
to any database.
8+
9+
## Metrics about Queries
10+
11+
In order to get metrics about query execution time, you must enable the
12+
`pg_stat_statements` extension. This extension must be specified in the
13+
`shared_preload_libraries` config option in the main PostgreSQL
14+
configuration at server start up. Then the extension must be enabled for
15+
each database by running `CREATE EXTENSION IF NOT EXISTS
16+
pg_stat_statements;` on each database.
17+
18+
Note that in order to get consistent and accurate query execution time
19+
metrics, you must set the [pg_stat_statements.max config
20+
option](https://www.postgresql.org/docs/9.3/pgstatstatements.html#AEN160631)
21+
to larger than the number of distinct queries on the server.
22+
23+
Here is a [sample configuration of Postgres to enable statement tracking](https://www.postgresql.org/docs/9.3/pgstatstatements.html#AEN160631).
24+
25+
Tested with PostgreSQL 9.2+.
26+
27+
If you want to collect additional metrics about PostgreSQL, use the [sql monitor](./sql.md).
28+
29+
30+
Monitor Type: `postgresql`
31+
32+
[Monitor Source Code](https://github.com/signalfx/signalfx-agent/tree/master/internal/monitors/postgresql)
33+
34+
**Accepts Endpoints**: **Yes**
35+
36+
**Multiple Instances Allowed**: Yes
37+
38+
## Configuration
39+
40+
| Config option | Required | Type | Description |
41+
| --- | --- | --- | --- |
42+
| `host` | no | `string` | |
43+
| `port` | no | `integer` | (**default:** `0`) |
44+
| `connectionString` | no | `string` | See https://godoc.org/github.com/lib/pq#hdr-Connection_String_Parameters. |
45+
| `databases` | no | `list of strings` | List of databases to send database-specific metrics about. If omitted, metrics about all databases will be sent. This is an [overridable filter](https://github.com/signalfx/signalfx-agent/blob/master/docs/filtering.md#overridable-filters). (**default:** `[*]`) |
46+
| `databasePollIntervalSeconds` | no | `integer` | How frequently to poll for new/deleted databases in the DB server. Defaults to the same as `intervalSeconds` if not set. (**default:** `0`) |
47+
48+
49+
50+
51+
## Metrics
52+
53+
The following table lists the metrics available for this monitor. Metrics that are marked as Included are standard metrics and are monitored by default.
54+
55+
| Name | Type | Included | Description |
56+
| --- | --- | --- | --- |
57+
| `postgres_sessions` | gauge || Number of sessions currently on the server instance. The `state` dimension will specify which which type of session (see `state` row of [pg_stat_activity](https://www.postgresql.org/docs/9.2/monitoring-stats.html#PG-STAT-ACTIVITY-VIEW)). |
58+
| `postgres_block_hit_ratio` | gauge || The proportion (between 0 and 1, inclusive) of block reads that used the cache and did not have to go to the disk. Is sent for `table`, `index`, and the `database` as a whole. |
59+
| `postgres_database_size` | gauge || Size in bytes of the database on disk |
60+
| `postgres_deadlocks` | cumulative || Total number of deadlocks detected by the system |
61+
| `postgres_query_count` | cumulative | ✔ | Total number of queries executed on the `database`, broken down by
62+
`user`. Note that the accuracy of this metric depends on the
63+
PostgreSQL [pg_stat_statements.max config
64+
option](https://www.postgresql.org/docs/9.3/pgstatstatements.html#AEN160631)
65+
being large enough to hold all queries. |
66+
| `postgres_query_time` | cumulative || Total time taken to execute queries on the `database`, broken down by `user`. |
67+
| `postgres_rows_inserted` | cumulative || Number of rows inserted into the `table`. |
68+
| `postgres_rows_updated` | cumulative || Number of rows updated in the `table`. |
69+
| `postgres_rows_deleted` | cumulative || Number of rows deleted from the `table`. |
70+
| `postgres_sequential_scans` | cumulative || Total number of sequential scans on the `table`. |
71+
| `postgres_index_scans` | cumulative || Total number of index scans on the `table`. |
72+
| `postgres_table_size` | gauge || The size in bytes of the `table` on disk. |
73+
| `postgres_live_rows` | gauge || Number of rows live (not deleted) in the `table`. |
74+
75+
76+
To specify custom metrics you want to monitor, add a `metricsToInclude` filter
77+
to the agent configuration, as shown in the code snippet below. The snippet
78+
lists all available custom metrics. You can copy and paste the snippet into
79+
your configuration file, then delete any custom metrics that you do not want
80+
sent.
81+
82+
Note that some of the custom metrics require you to set a flag as well as add
83+
them to the list. Check the monitor configuration file to see if a flag is
84+
required for gathering additional metrics.
85+
86+
```yaml
87+
88+
metricsToInclude:
89+
- metricNames:
90+
monitorType: postgresql
91+
```
92+
93+
94+
## Dimensions
95+
96+
The following dimensions may occur on metrics emitted by this monitor. Some
97+
dimensions may be specific to certain metrics.
98+
99+
| Name | Description |
100+
| --- | --- |
101+
| `type` | Whether the object (table, index, function, etc.) belongs to the `system` or `user`. |
102+
| `table` | The name of the table to which the metric pertains. |
103+
| `database` | The name of the database within a PostgreSQL server to which the metric pertains. |
104+
| `schemaname` | The name of the schema within which the object being monitored resides (e.g. `public`). |
105+
| `index` | For index metrics, the name of the index |
106+
| `user` | For query metrics, the user name of the user that executed the queries. |
107+
| `tablespace` | For table metrics, the tablespace in which the table belongs, if not null. |
108+
109+
110+

docs/monitors/sql.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<!--- GENERATED BY gomplate from scripts/docs/monitor-page.md.tmpl --->
2+
3+
# sql
4+
5+
Run arbitrary SQL queries against a relational database and use the results to generate dataponts.
6+
7+
For example, if you had a database table `customers` that looked like:
8+
9+
| id | name | country | status |
10+
|----|------------|---------|----------|
11+
| 1 | Bill | USA | active |
12+
| 2 | Mary | USA | inactive |
13+
| 3 | Joe | USA | active |
14+
| 4 | Elizabeth | Germany | active |
15+
16+
You could use the following monitor config to generate metrics about active users and customer counts by country:
17+
18+
```yaml
19+
monitors:
20+
- type: sql
21+
host: localhost
22+
port: 5432
23+
dbDriver: postgres
24+
# The `host` and `port` values from above (or provided through auto-discovery) should be interpolated
25+
# to the connection string as appropriate for your database driver.
26+
connectionString: 'host={{.host}} port={{.port}} dbname=main user=admin password=***** sslmode=disabled'
27+
queries:
28+
- query: 'SELECT COUNT(*) as count, country, status FROM customers GROUP BY country, status;'
29+
metrics:
30+
- metricName: "customers"
31+
valueColumn: "count"
32+
dimensionColumns: ["country", "status"]
33+
```
34+
35+
This would generate a series of timeseries, all with the metric name
36+
`customers` that includes a `county` and `status` dimension. The value
37+
is the number of customers that belong to that combination of `country`
38+
and `status`. You could also specify multiple `metrics` items to
39+
generate more than one metric from a single query.
40+
41+
## Supported Drivers
42+
43+
The `dbDriver` config option must specify the database driver to use.
44+
These are equivalent to the name of the Golang SQL driver used in the
45+
agent. The `connectionString` option will be formatted according to the
46+
driver that is going to receive it. Here is a list of the drivers we
47+
currently support and documentation on the connection string:
48+
49+
- `postgres`: https://godoc.org/github.com/lib/pq#hdr-Connection_String_Parameters
50+
- `mysql`: https://github.com/go-sql-driver/mysql#dsn-data-source-name
51+
- `mssql`: https://github.com/denisenkom/go-mssqldb#connection-parameters-and-dsn
52+
53+
54+
Monitor Type: `sql`
55+
56+
[Monitor Source Code](https://github.com/signalfx/signalfx-agent/tree/master/internal/monitors/sql)
57+
58+
**Accepts Endpoints**: **Yes**
59+
60+
**Multiple Instances Allowed**: Yes
61+
62+
## Configuration
63+
64+
| Config option | Required | Type | Description |
65+
| --- | --- | --- | --- |
66+
| `host` | no | `string` | |
67+
| `port` | no | `integer` | (**default:** `0`) |
68+
| `dbDriver` | no | `string` | The database driver to use, valid values are `postgres` and `mysql`. |
69+
| `connectionString` | no | `string` | A URL or simple option string used to connect to the database. If using PostgreSQL, [see the list of connection string params](https://godoc.org/github.com/lib/pq#hdr-Connection_String_Parameters). |
70+
| `queries` | **yes** | `list of objects (see below)` | A list of queries to make against the database that are used to generate datapoints. |
71+
| `logQueries` | no | `bool` | If true, query results will be logged at the info level. (**default:** `false`) |
72+
73+
74+
The **nested** `queries` config object has the following fields:
75+
76+
| Config option | Required | Type | Description |
77+
| --- | --- | --- | --- |
78+
| `query` | **yes** | `string` | A SQL query text that selects one or more rows from a database |
79+
| `params` | no | `list of any` | Optional parameters that will replace placeholders in the query string. |
80+
| `metrics` | no | `list of objects (see below)` | Metrics that should be generated from the query. |
81+
82+
83+
The **nested** `metrics` config object has the following fields:
84+
85+
| Config option | Required | Type | Description |
86+
| --- | --- | --- | --- |
87+
| `metricName` | **yes** | `string` | The name of the metric as it will appear in SignalFx. |
88+
| `valueColumn` | **yes** | `string` | The column name that holds the datapoint value |
89+
| `dimensionColumns` | no | `list of strings` | The names of the columns that should make up the dimensions of the datapoint. |
90+
| `isCumulative` | no | `bool` | Whether the value is a cumulative counters (true) or gauge (false). If you set this to the wrong value and send in your first datapoint for the metric name with the wrong type, you will have to manually change the type in SignalFx, as it is set in the system based on the first type seen. (**default:** `false`) |
91+
92+
93+
94+
95+
96+
97+
98+

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ require (
3535
github.com/creasty/defaults v0.0.0-00010101000000-000000000000
3636
github.com/dancannon/gorethink v4.0.0+incompatible // indirect
3737
github.com/davecgh/go-spew v1.1.1
38-
github.com/denisenkom/go-mssqldb v0.0.0-20190121005146-b04fd42d9952 // indirect
38+
github.com/denisenkom/go-mssqldb v0.0.0-20190121005146-b04fd42d9952
3939
github.com/dimchansky/utfbom v1.1.0 // indirect
4040
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible // indirect
4141
github.com/docker/docker v0.7.3-0.20190316220345-38005cfc12fb
@@ -55,7 +55,7 @@ require (
5555
github.com/go-ole/go-ole v1.2.1 // indirect
5656
github.com/go-playground/locales v0.11.2 // indirect
5757
github.com/go-playground/universal-translator v0.16.0 // indirect
58-
github.com/go-sql-driver/mysql v1.4.1 // indirect
58+
github.com/go-sql-driver/mysql v1.4.1
5959
github.com/go-stack/stack v1.8.0 // indirect
6060
github.com/go-stomp/stomp v2.0.2+incompatible // indirect
6161
github.com/gobwas/glob v0.2.3
@@ -112,6 +112,7 @@ require (
112112
github.com/keybase/go-crypto v0.0.0-20190312101036-b475f2ecc1fe // indirect
113113
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
114114
github.com/kr/pretty v0.1.0
115+
github.com/lib/pq v1.0.0
115116
github.com/mailru/easyjson v0.0.0-20180606163543-3fdea8d05856
116117
github.com/mattbaird/elastigo v0.0.0-20170123220020-2fe47fd29e4b // indirect
117118
github.com/mattn/go-colorable v0.1.1 // indirect

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ github.com/apache/arrow/go/arrow v0.0.0-20181031164735-a56c009257a7/go.mod h1:Gj
5858
github.com/apache/arrow/go/arrow v0.0.0-20181217213538-e9ed591db9cb/go.mod h1:GjvccvtI06FGFvRU1In/maF7tKp3h7GBV9Sexo5rNPM=
5959
github.com/apache/thrift v0.0.0-20180411174621-858809fad01d h1:FpnuLmy9B8Zv224zDrjobOhrbyXVQDh9ER4BrrkRfvA=
6060
github.com/apache/thrift v0.0.0-20180411174621-858809fad01d/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
61+
github.com/apex/log v1.1.0 h1:J5rld6WVFi6NxA6m8GJ1LJqu3+GiTFIt3mYv27gdQWI=
6162
github.com/apex/log v1.1.0/go.mod h1:yA770aXIDQrhVOIGurT/pVdfCpSq1GQV/auzMN5fzvY=
6263
github.com/araddon/gou v0.0.0-20190110011759-c797efecbb61 h1:Xz25cuW4REGC5W5UtpMU3QItMIImag615HiQcRbxqKQ=
6364
github.com/araddon/gou v0.0.0-20190110011759-c797efecbb61/go.mod h1:ikc1XA58M+Rx7SEbf0bLJCfBkwayZ8T5jBo5FXK8Uz8=

internal/core/dpfilters/negated.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package dpfilters
2+
3+
import "github.com/signalfx/golib/datapoint"
4+
5+
// NegatedDatapointFilter is a datapoint filter whose Matches method is made
6+
// opposite
7+
type NegatedDatapointFilter struct {
8+
DatapointFilter
9+
}
10+
11+
// Matches returns the opposite of what the original filter would have
12+
// returned.
13+
func (n *NegatedDatapointFilter) Matches(dp *datapoint.Datapoint) bool {
14+
return !n.DatapointFilter.Matches(dp)
15+
}
16+
17+
// Negate returns the supplied filter negated such Matches returns the
18+
// opposite.
19+
func Negate(f DatapointFilter) DatapointFilter {
20+
return &NegatedDatapointFilter{
21+
DatapointFilter: f,
22+
}
23+
}

internal/core/dpfilters/set.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ type FilterSet struct {
1313
IncludeFilters []DatapointFilter
1414
}
1515

16+
var _ DatapointFilter = &FilterSet{}
17+
1618
// Matches sends a datapoint through each of the filters in the set and returns
1719
// true if at least one of them matches the datapoint.
1820
func (fs *FilterSet) Matches(dp *datapoint.Datapoint) bool {

internal/core/modules.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
_ "github.com/signalfx/signalfx-agent/internal/monitors/memory"
4040
_ "github.com/signalfx/signalfx-agent/internal/monitors/metadata/hostmetadata"
4141
_ "github.com/signalfx/signalfx-agent/internal/monitors/netio"
42+
_ "github.com/signalfx/signalfx-agent/internal/monitors/postgresql"
4243
_ "github.com/signalfx/signalfx-agent/internal/monitors/processlist"
4344
_ "github.com/signalfx/signalfx-agent/internal/monitors/prometheus/go"
4445
_ "github.com/signalfx/signalfx-agent/internal/monitors/prometheus/nginxvts"
@@ -48,6 +49,7 @@ import (
4849
_ "github.com/signalfx/signalfx-agent/internal/monitors/prometheus/redis"
4950
_ "github.com/signalfx/signalfx-agent/internal/monitors/prometheusexporter"
5051
_ "github.com/signalfx/signalfx-agent/internal/monitors/pyrunner/signalfx"
52+
_ "github.com/signalfx/signalfx-agent/internal/monitors/sql"
5153
_ "github.com/signalfx/signalfx-agent/internal/monitors/telegraf/monitors/mssqlserver"
5254
_ "github.com/signalfx/signalfx-agent/internal/monitors/telegraf/monitors/procstat"
5355
_ "github.com/signalfx/signalfx-agent/internal/monitors/telegraf/monitors/tail"

internal/core/services/endpointcore.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func (e *EndpointCore) IsSelfConfigured() bool {
100100

101101
// Dimensions returns a map of dimensions set on this endpoint
102102
func (e *EndpointCore) Dimensions() map[string]string {
103-
return e.extraDimensions
103+
return utils.CloneStringMap(e.extraDimensions)
104104
}
105105

106106
// AddDimension adds a dimension to this endpoint

internal/monitors/collectd/postgresql/metadata.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
monitors:
22
- dimensions: null
33
doc: |
4+
**This monitor is deprecated in favor of the [postgresql monitor](./postgresql.md).**
5+
46
Monitors a PostgreSQL database server using collectd's
57
[PostgreSQL plugin](https://collectd.org/wiki/index.php/Plugin:PostgreSQL).
68

internal/monitors/manager.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/signalfx/golib/event"
1111
"github.com/signalfx/golib/trace"
1212
"github.com/signalfx/signalfx-agent/internal/core/config"
13+
"github.com/signalfx/signalfx-agent/internal/core/dpfilters"
1314
"github.com/signalfx/signalfx-agent/internal/core/meta"
1415
"github.com/signalfx/signalfx-agent/internal/core/services"
1516
"github.com/signalfx/signalfx-agent/internal/monitors/collectd"
@@ -342,15 +343,16 @@ func (mm *MonitorManager) createAndConfigureNewMonitor(config config.MonitorCust
342343
monitorID: id,
343344
notHostSpecific: config.MonitorConfigCore().DisableHostDimensions,
344345
disableEndpointDimensions: config.MonitorConfigCore().DisableEndpointDimensions,
345-
oldFilter: oldFilter,
346-
newFilter: newFilter,
347-
configHash: configHash,
348-
endpoint: endpoint,
349-
dpChan: mm.DPs,
350-
eventChan: mm.Events,
351-
dimPropChan: mm.DimensionProps,
352-
spanChan: mm.TraceSpans,
353-
extraDims: map[string]string{},
346+
filterSet: &dpfilters.FilterSet{
347+
ExcludeFilters: []dpfilters.DatapointFilter{oldFilter, newFilter},
348+
},
349+
configHash: configHash,
350+
endpoint: endpoint,
351+
dpChan: mm.DPs,
352+
eventChan: mm.Events,
353+
dimPropChan: mm.DimensionProps,
354+
spanChan: mm.TraceSpans,
355+
extraDims: map[string]string{},
354356
}
355357

356358
am := &ActiveMonitor{

0 commit comments

Comments
 (0)