Class: NewRelic::PostgresPlugin::Agent

Inherits:
NewRelic::Plugin::Agent::Base
  • Object
show all
Defined in:
lib/newrelic_postgres_plugin/agent.rb

Instance Method Summary collapse

Constructor Details

#initialize(name, agent_info, options = {}) ⇒ Agent

Returns a new instance of Agent.



27
28
29
30
# File 'lib/newrelic_postgres_plugin/agent.rb', line 27

def initialize name, agent_info, options={}
  @previous_metrics = {}
  super
end

Instance Method Details

#backend_queryObject



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/newrelic_postgres_plugin/agent.rb', line 134

def backend_query
  %Q(
    SELECT ( SELECT count(*) FROM pg_stat_activity WHERE
      #{
        if nine_two?
          "state <> 'idle'"
        else
          "current_query <> '<IDLE>'"
        end
      }
    ) AS backends_active, ( SELECT count(*) FROM pg_stat_activity WHERE
      #{
        if nine_two?
          "state = 'idle'"
        else
          "current_query = '<IDLE>'"
        end
      }
    ) AS backends_idle FROM pg_stat_activity;
  )
end

#bgwriter_queryObject



160
161
162
# File 'lib/newrelic_postgres_plugin/agent.rb', line 160

def bgwriter_query
  "SELECT * FROM pg_stat_bgwriter;"
end

#connectObject

Get a connection to postgres



48
49
50
# File 'lib/newrelic_postgres_plugin/agent.rb', line 48

def connect
  PG::Connection.new(:host => host, :port => port, :user => user, :password => password, :sslmode => sslmode, :dbname => dbname)
end

#database_queryObject



156
157
158
# File 'lib/newrelic_postgres_plugin/agent.rb', line 156

def database_query
  "SELECT * FROM pg_stat_database;"
end

#index_count_queryObject



164
165
166
# File 'lib/newrelic_postgres_plugin/agent.rb', line 164

def index_count_query
  "SELECT count(1) as indexes FROM pg_class WHERE relkind = 'i';"
end

#index_hit_rate_queryObject



168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/newrelic_postgres_plugin/agent.rb', line 168

def index_hit_rate_query
  %Q(
    SELECT
      'index hit rate' AS name,
      (sum(idx_blks_hit)) / sum(idx_blks_hit + idx_blks_read) AS ratio
    FROM pg_statio_user_indexes
    UNION ALL
    SELECT
     'cache hit rate' AS name,
      sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) AS ratio
    FROM pg_statio_user_tables;
  )
end

#index_size_queryObject



182
183
184
# File 'lib/newrelic_postgres_plugin/agent.rb', line 182

def index_size_query
  "SELECT sum(relpages*8192) AS size FROM pg_class WHERE reltype = 0;"
end

#nine_two?Boolean

Returns true if we’re talking to Postgres version >= 9.2

Returns:

  • (Boolean)


55
56
57
# File 'lib/newrelic_postgres_plugin/agent.rb', line 55

def nine_two?
  @connection.server_version >= 90200
end

#poll_cycleObject

This is called on every polling cycle



63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/newrelic_postgres_plugin/agent.rb', line 63

def poll_cycle
  @connection = self.connect

  report_backend_metrics
  report_bgwriter_metrics
  report_database_metrics
  report_index_metrics
  
  @connection.finish
rescue => e
  $stderr.puts "#{e}: #{e.backtrace.join("\n  ")}"
end

#portObject

You do not have to specify the postgres port in the yaml if you don’t want to.



41
42
43
# File 'lib/newrelic_postgres_plugin/agent.rb', line 41

def port
  @port || 5432
end

#report_backend_metricsObject



86
87
88
89
90
91
# File 'lib/newrelic_postgres_plugin/agent.rb', line 86

def report_backend_metrics
  @connection.exec(backend_query) do |result|
    report_metric "Backends/Active", 'connections', result[0]['backends_active']
    report_metric "Backends/Idle",   'connections', result[0]['backends_idle']
  end
end

#report_bgwriter_metricsObject



114
115
116
117
118
119
# File 'lib/newrelic_postgres_plugin/agent.rb', line 114

def report_bgwriter_metrics
  @connection.exec(bgwriter_query) do |result|
    report_derived_metric "Background Writer/Checkpoints/Scheduled", 'checkpoints', result[0]['checkpoints_timed'].to_i
    report_derived_metric "Background Writer/Checkpoints/Requested", 'checkpoints', result[0]['checkpoints_requests'].to_i
  end
end

#report_database_metricsObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/newrelic_postgres_plugin/agent.rb', line 93

def report_database_metrics
  @connection.exec(database_query) do |result|
    result.each do |row|
      database_name = row['datname']
      if database_name == dbname
        report_metric         "Database/Backends",                        '', row['numbackends'].to_i
        report_derived_metric "Database/Transactions/Committed",          '', row['xact_commit'].to_i
        report_derived_metric "Database/Transactions/Rolled Back",        '', row['xact_rollback'].to_i
        report_derived_metric "Database/Tuples/Read from Disk",           '', row['blks_read'].to_i
        report_derived_metric "Database/Tuples/Read Cache Hit",           '', row['blks_hit'].to_i
        report_derived_metric "Database/Tuples/Returned/From Sequential", '', row['tup_returned'].to_i
        report_derived_metric "Database/Tuples/Returned/From Bitmap",     '', row['tup_fetched'].to_i
        report_derived_metric "Database/Tuples/Writes/Inserts",           '', row['tup_inserted'].to_i
        report_derived_metric "Database/Tuples/Writes/Updates",           '', row['tup_updated'].to_i
        report_derived_metric "Database/Tuples/Writes/Deletes",           '', row['tup_deleted'].to_i
        report_derived_metric "Database/Conflicts",                       '', row['conflicts'].to_i
      end
    end
  end
end

#report_derived_metric(name, units, value) ⇒ Object



76
77
78
79
80
81
82
83
# File 'lib/newrelic_postgres_plugin/agent.rb', line 76

def report_derived_metric(name, units, value)
  if previous_value = @previous_metrics[name]
    report_metric name, units, (value - previous_value)
  else
    report_metric name, units, 0
  end
  @previous_metrics[name] = value
end

#report_index_metricsObject



121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/newrelic_postgres_plugin/agent.rb', line 121

def report_index_metrics
  @connection.exec(index_count_query) do |result|
    report_metric "Indexes/Number of Indexes", 'indexes', result[0]['indexes'].to_i
  end
  @connection.exec(index_hit_rate_query) do |result|
    report_metric "Indexes/Index Hit Rate", '%', result[0]['ratio'].to_f * 100.0
    report_metric "Indexes/Cache Hit Rate", '%', result[1]['ratio'].to_f * 100.0
  end
  @connection.exec(index_size_query) do |result|
    report_metric "Indexes/Size on Disk", 'bytes', result[0]['size'].to_f
  end
end

#setup_metricsObject

Required, but not used



35
36
# File 'lib/newrelic_postgres_plugin/agent.rb', line 35

def setup_metrics
end