newrelic_postgres_plugin 0.1.10 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9963116cf3fcb09cc1a828c0ec7f42da61e06565
4
- data.tar.gz: d6c729e2ff896425a3d9b71fe84af67a50913ef9
3
+ metadata.gz: 42e010eea7c25bffabade08f52c80b7d30d97c93
4
+ data.tar.gz: 7483bf38fad8a1843f1cd0e8b3e78f1b52e00eb7
5
5
  SHA512:
6
- metadata.gz: 94d5fe44288f1606c4d26b06aa8ee4d46bde9f5643d28f80e9b67a2fb454e18ff38c9e8e9b070e8c3b7e64aa33a96a06d5632fb781e42f8b1680bff803fd712c
7
- data.tar.gz: 39f0650e1cca644fef715560493a6d8d1e82ceded511c521cf04867426b685dd6e0e4be9fa31a47c6128590e60de10098bed580f886febe4b6d96e2ad73a5a67
6
+ metadata.gz: b2f5837b91fa26beae34557ecaf5e933d67daf122ce6591d64284c8dd1e51471dd66822b61afbc5c4071cf1d142a9999f923ae9c7c47473596453eb75d13812e
7
+ data.tar.gz: b9506081e2b0fdf1ec3e0a1ae5b19d4f52b383213197012514f55bc1517312d2dcd877cabf26db35231988bc487508fdbd5967bec8963b7cc68f6bc3fda5cec3
data/Gemfile.lock CHANGED
@@ -1,21 +1,17 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- newrelic_postgres_plugin (0.1.6)
5
- newrelic_plugin (~> 1.0.2)
4
+ newrelic_postgres_plugin (0.1.10)
5
+ newrelic_plugin (~> 1.3)
6
6
  pg (>= 0.15.1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- faraday (0.8.8)
12
- multipart-post (~> 1.2.0)
13
- json (1.8.0)
14
- multipart-post (1.2.0)
15
- newrelic_plugin (1.0.3)
16
- faraday (>= 0.8.1)
11
+ json (1.8.1)
12
+ newrelic_plugin (1.3.1)
17
13
  json
18
- pg (0.16.0)
14
+ pg (0.17.1)
19
15
 
20
16
  PLATFORMS
21
17
  ruby
data/README.md CHANGED
@@ -5,8 +5,8 @@ A NewRelic Platform Postgres Plugin
5
5
 
6
6
  The New Relic Postgres Plugin enables integrated monitoring of your Postgres database in a custom NewRelic dashboard. Currently the following metrics are recorded:
7
7
 
8
- * Index size, hit rate, and count
9
- * Cache hit rate
8
+ * Index size, miss rate, and count
9
+ * Cache miss rate
10
10
  * Idle and active connection counts
11
11
  * BGWriter metrics
12
12
  * Tuple metrics
@@ -17,14 +17,14 @@ The New Relic Postgres Plugin enables integrated monitoring of your Postgres dat
17
17
  ### Proxy host
18
18
 
19
19
  You need a host to install the plugin on that is able to poll the desired Postgres database. That
20
- host also needs Ruby (tested with 2.0.0), and support for rubygems.
20
+ host also needs Ruby (tested with 2.0.0), and support for rubygems. Heroku is a great choice for this. A fully deployable example app is provided.
21
21
 
22
+ https://github.com/GoBoundless/heroku_postgres_monitor
22
23
 
23
24
  ### Postgres
24
25
 
25
26
  This plugin has been tested with with a few different Postgres version and should work with any version compatible with the pg gem.
26
27
 
27
-
28
28
  ## Installation and Running
29
29
 
30
30
  1. Install this gem from RubyGems:
@@ -37,7 +37,7 @@ This plugin has been tested with with a few different Postgres version and shoul
37
37
  ```pg_monitor install -l LICENSE_KEY```
38
38
 
39
39
  using the license key from your New Relic account.
40
- 4. Edit the +config/newrelic_plugin.yml+ file generated in step 4. Setup host/port/user/password/dbname for your postgres connection.
40
+ 4. Edit the `config/newrelic_plugin.yml` file generated in step 4. Setup host/port/user/password/dbname for your postgres connection.
41
41
  5. Execute
42
42
 
43
43
  ```pg_monitor run```
@@ -61,4 +61,4 @@ Please use Github issue for support. We will do our best to address issues in a
61
61
 
62
62
  ```bundle install```
63
63
 
64
- 3. Run <b><tt>rake -T</tt></b> to see rake options, including tests.
64
+ 3. Run `rake -T` to see rake options, including tests.
@@ -76,7 +76,6 @@ module NewRelic::PostgresPlugin
76
76
  @previous_metrics[name] = value
77
77
  end
78
78
 
79
-
80
79
  def report_backend_metrics
81
80
  @connection.exec(backend_query) do |result|
82
81
  report_metric "Backends/Active", 'connections', result[0]['backends_active']
@@ -87,22 +86,23 @@ module NewRelic::PostgresPlugin
87
86
  def report_database_metrics
88
87
  @connection.exec(database_query) do |result|
89
88
  result.each do |row|
90
- database_name = row['datname']
91
- if database_name == dbname
92
- report_metric "Database/Backends", '', row['numbackends'].to_i
93
- report_derived_metric "Database/Transactions/Committed", '', row['xact_commit'].to_i
94
- report_derived_metric "Database/Transactions/Rolled Back", '', row['xact_rollback'].to_i
95
- report_derived_metric "Database/Tuples/Read from Disk", '', row['blks_read'].to_i
96
- report_derived_metric "Database/Tuples/Read Cache Hit", '', row['blks_hit'].to_i
97
- report_derived_metric "Database/Tuples/Returned/From Sequential", '', row['tup_returned'].to_i
98
- report_derived_metric "Database/Tuples/Returned/From Bitmap", '', row['tup_fetched'].to_i
99
- report_derived_metric "Database/Tuples/Writes/Inserts", '', row['tup_inserted'].to_i
100
- report_derived_metric "Database/Tuples/Writes/Updates", '', row['tup_updated'].to_i
101
- report_derived_metric "Database/Tuples/Writes/Deletes", '', row['tup_deleted'].to_i
102
- report_derived_metric "Database/Conflicts", '', row['conflicts'].to_i
103
- end
89
+ report_metric "Database/Backends", '', row['numbackends'].to_i
90
+ report_derived_metric "Database/Transactions/Committed", '', row['xact_commit'].to_i
91
+ report_derived_metric "Database/Transactions/Rolled Back", '', row['xact_rollback'].to_i
92
+ report_derived_metric "Database/Tuples/Returned/From Sequential", '', row['tup_returned'].to_i
93
+ report_derived_metric "Database/Tuples/Returned/From Bitmap", '', row['tup_fetched'].to_i
94
+ report_derived_metric "Database/Tuples/Writes/Inserts", '', row['tup_inserted'].to_i
95
+ report_derived_metric "Database/Tuples/Writes/Updates", '', row['tup_updated'].to_i
96
+ report_derived_metric "Database/Tuples/Writes/Deletes", '', row['tup_deleted'].to_i
97
+ report_derived_metric "Database/Conflicts", '', row['conflicts'].to_i
104
98
  end
105
99
  end
100
+ @connection.exec(index_count_query) do |result|
101
+ report_metric "Database/Indexes/Count", 'indexes', result[0]['indexes'].to_i
102
+ end
103
+ @connection.exec(index_size_query) do |result|
104
+ report_metric "Databases/Indexes/Size", 'bytes', result[0]['size'].to_i
105
+ end
106
106
  end
107
107
 
108
108
  def report_bgwriter_metrics
@@ -113,71 +113,83 @@ module NewRelic::PostgresPlugin
113
113
  end
114
114
 
115
115
  def report_index_metrics
116
- @connection.exec(index_count_query) do |result|
117
- report_metric "Indexes/Number of Indexes", 'indexes', result[0]['indexes'].to_i
118
- end
119
- @connection.exec(index_hit_rate_query) do |result|
120
- report_metric "Indexes/Index Hit Rate", '%', result[0]['ratio'].to_f * 100.0
121
- report_metric "Indexes/Cache Hit Rate", '%', result[1]['ratio'].to_f * 100.0
122
- end
123
- @connection.exec(index_size_query) do |result|
124
- report_metric "Indexes/Size on Disk", 'bytes', result[0]['size'].to_i
125
- end
116
+ report_metric "Indexes/Miss Ratio", '%', calculate_miss_ratio(%Q{SELECT SUM(idx_blks_hit) AS hits, SUM(idx_blks_read) AS reads FROM pg_statio_user_indexes})
126
117
  end
127
118
 
128
- def backend_query
129
- %Q(
130
- SELECT ( SELECT count(*) FROM pg_stat_activity WHERE
131
- #{
132
- if nine_two?
133
- "state <> 'idle'"
134
- else
135
- "current_query <> '<IDLE>'"
136
- end
137
- }
138
- ) AS backends_active, ( SELECT count(*) FROM pg_stat_activity WHERE
139
- #{
140
- if nine_two?
141
- "state = 'idle'"
142
- else
143
- "current_query = '<IDLE>'"
144
- end
145
- }
146
- ) AS backends_idle FROM pg_stat_activity;
147
- )
119
+ def report_cache_metrics
120
+ report_metric "Cache/Miss Ratio", '%', calculate_miss_ratio(%Q{SELECT SUM(heap_blks_hit) AS hits, SUM(heap_blks_read) AS reads FROM pg_statio_user_tables})
148
121
  end
149
122
 
150
- def database_query
151
- "SELECT * FROM pg_stat_database;"
152
- end
123
+ private
153
124
 
154
- def bgwriter_query
155
- "SELECT * FROM pg_stat_bgwriter;"
156
- end
125
+ # This assumes the query returns a single row with two columns: hits and reads.
126
+ def calculate_miss_ratio(query)
127
+ sample = @connection.exec(query)[0]
128
+ sample.each { |k,v| sample[k] = v.to_i }
129
+ @previous_result_for_query ||= {}
130
+ miss_ratio = if check_samples(@previous_result_for_query[query], sample)
157
131
 
158
- def index_count_query
159
- "SELECT count(1) as indexes FROM pg_class WHERE relkind = 'i';"
160
- end
132
+ hits = sample["hits"] - @previous_result_for_query[query]["hits"]
133
+ reads = sample["reads"] - @previous_result_for_query[query]["reads"]
134
+
135
+ if (hits + reads) == 0
136
+ 0.0
137
+ else
138
+ reads.to_f / (hits + reads) * 100.0
139
+ end
140
+ else
141
+ 0.0
142
+ end
143
+
144
+ @previous_result_for_query[query] = sample
145
+ return miss_ratio
146
+ end
147
+
148
+ # Check if we don't have a time dimension yet or metrics have decreased in value.
149
+ def check_samples(last, current)
150
+ return false if last.nil? # First sample?
151
+ return false unless current.find { |k,v| last[k] > v }.nil? # Values have gone down?
152
+ return true
153
+ end
161
154
 
162
- def index_hit_rate_query
163
- %Q(
164
- SELECT
165
- 'index hit rate' AS name,
166
- (sum(idx_blks_hit)) / sum(idx_blks_hit + idx_blks_read) AS ratio
167
- FROM pg_statio_user_indexes
168
- WHERE idx_blks_hit > 0
169
- UNION ALL
170
- SELECT
171
- 'cache hit rate' AS name,
172
- sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) AS ratio
173
- FROM pg_statio_user_tables
174
- WHERE idx_blks_hit > 0;
175
- )
176
- end
155
+ def backend_query
156
+ %Q(
157
+ SELECT ( SELECT count(*) FROM pg_stat_activity WHERE
158
+ #{
159
+ if nine_two?
160
+ "state <> 'idle'"
161
+ else
162
+ "current_query <> '<IDLE>'"
163
+ end
164
+ }
165
+ ) AS backends_active, ( SELECT count(*) FROM pg_stat_activity WHERE
166
+ #{
167
+ if nine_two?
168
+ "state = 'idle'"
169
+ else
170
+ "current_query = '<IDLE>'"
171
+ end
172
+ }
173
+ ) AS backends_idle FROM pg_stat_activity;
174
+ )
175
+ end
177
176
 
178
- def index_size_query
179
- "SELECT sum(relpages::bigint*8192) AS size FROM pg_class WHERE reltype = 0;"
180
- end
177
+ def database_query
178
+ "SELECT * FROM pg_stat_database WHERE datname='#{dbname}';"
179
+ end
180
+
181
+ def bgwriter_query
182
+ "SELECT * FROM pg_stat_bgwriter;"
183
+ end
184
+
185
+ def index_count_query
186
+ "SELECT count(1) as indexes FROM pg_class WHERE relkind = 'i';"
187
+ end
188
+
189
+ def index_size_query
190
+ "SELECT sum(relpages::bigint*8192) AS size FROM pg_class WHERE reltype = 0;"
191
+ end
181
192
 
182
193
  end
194
+
183
195
  end
@@ -1,3 +1,3 @@
1
1
  module NewRelic::PostgresPlugin
2
- VERSION = '0.1.10'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
13
13
  ## If your rubyforge_project name is different, then edit it and comment out
14
14
  ## the sub! line in the Rakefile
15
15
  s.name = 'newrelic_postgres_plugin'
16
- s.version = '0.1.10'
17
- s.date = '2014-01-31'
16
+ s.version = '0.2.0'
17
+ s.date = '2014-08-05'
18
18
  s.rubyforge_project = 'newrelic_postgres_plugin'
19
19
 
20
20
  ## Make sure your summary is short. The description may be as long
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newrelic_postgres_plugin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Hodgson
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-01-31 00:00:00.000000000 Z
12
+ date: 2014-08-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: newrelic_plugin
@@ -86,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
86
  version: '0'
87
87
  requirements: []
88
88
  rubyforge_project: newrelic_postgres_plugin
89
- rubygems_version: 2.2.0
89
+ rubygems_version: 2.4.1
90
90
  signing_key:
91
91
  specification_version: 2
92
92
  summary: New Relic Postgres plugin