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



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

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



158
159
160
# File 'lib/newrelic_postgres_plugin/agent.rb', line 158

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



154
155
156
# File 'lib/newrelic_postgres_plugin/agent.rb', line 154

def database_query
  "SELECT * FROM pg_stat_database;"
end

#index_count_queryObject



162
163
164
# File 'lib/newrelic_postgres_plugin/agent.rb', line 162

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

#index_hit_rate_queryObject



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

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



180
181
182
# File 'lib/newrelic_postgres_plugin/agent.rb', line 180

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
# 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
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



84
85
86
87
88
89
# File 'lib/newrelic_postgres_plugin/agent.rb', line 84

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



112
113
114
115
116
117
# File 'lib/newrelic_postgres_plugin/agent.rb', line 112

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



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

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



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

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



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

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