root / plugins / postgresql / pgbouncer_ @ 0b426019
Historique | Voir | Annoter | Télécharger (9,49 ko)
| 1 | 8a515d24 | Clemens Schwaighofer | #!/usr/bin/perl -w |
|---|---|---|---|
| 2 | |||
| 3 | # re-write of python version of pgbouncer stats |
||
| 4 | # data from stats, pools (cleint, server) |
||
| 5 | |||
| 6 | 647632f7 | Clemens Schwaighofer | use strict; |
| 7 | 8a515d24 | Clemens Schwaighofer | use Munin::Plugin; |
| 8 | use DBD::Pg; |
||
| 9 | |||
| 10 | # check that multigraph is avaailable |
||
| 11 | need_multigraph(); |
||
| 12 | # get the script name |
||
| 13 | my $plugin_name = $Munin::Plugin::me; |
||
| 14 | # set the DB connection vars |
||
| 15 | my $db_user = $ENV{'pgbouncer_user'} || 'postgres';
|
||
| 16 | my $db_port = $ENV{'pgbouncer_port'} || '6432';
|
||
| 17 | my $db_host = $ENV{'pgbouncer_host'} || 'localhost';
|
||
| 18 | my $db_pass = $ENV{'pgbouncer_pass'} || '';
|
||
| 19 | my $db_name = 'pgbouncer'; |
||
| 20 | 647632f7 | Clemens Schwaighofer | my @data = (); |
| 21 | 8a515d24 | Clemens Schwaighofer | # get the DB (pool) name we want to fetch |
| 22 | $plugin_name =~ /pgbouncer_(.*)$/; |
||
| 23 | 647632f7 | Clemens Schwaighofer | my $pool_name = $1; |
| 24 | 8a515d24 | Clemens Schwaighofer | # bail if no name |
| 25 | if (!$pool_name) |
||
| 26 | {
|
||
| 27 | print "Cannot get pool name\n"; |
||
| 28 | exit 1; |
||
| 29 | } |
||
| 30 | |||
| 31 | # command line arguments for autconf and config |
||
| 32 | if (defined($ARGV[0])) |
||
| 33 | {
|
||
| 34 | # autoconf, nothing to do |
||
| 35 | if ($ARGV[0] eq 'autoconf') |
||
| 36 | {
|
||
| 37 | 647632f7 | Clemens Schwaighofer | my $dbh = DBI->connect("DBI:Pg:dbname=$db_name;host=$db_host;port=$db_port", $db_user, $db_pass);
|
| 38 | 8a515d24 | Clemens Schwaighofer | if (!$dbh) |
| 39 | {
|
||
| 40 | print "no\n"; |
||
| 41 | exit 1; |
||
| 42 | } |
||
| 43 | else |
||
| 44 | {
|
||
| 45 | print "yes\n"; |
||
| 46 | exit 0; |
||
| 47 | } |
||
| 48 | $dbh->disconnect(); |
||
| 49 | } |
||
| 50 | |||
| 51 | if ($ARGV[0] eq 'config') |
||
| 52 | {
|
||
| 53 | # create the basic RRD |
||
| 54 | # stats: average connections |
||
| 55 | print "multigraph ".$plugin_name."_stats_avg_req\n"; |
||
| 56 | print "graph_title PgBouncer $pool_name average connections\n"; |
||
| 57 | print "graph_args --base 1000\n"; # numbers not bytes |
||
| 58 | print "graph_vlabel Average connections\n"; |
||
| 59 | print "graph_scale no\n"; # so we do not print "micro, milli, kilo, etc" |
||
| 60 | print "graph_category pgbouncer\n"; |
||
| 61 | print $pool_name."_avg_req.type GAUGE\n"; |
||
| 62 | print $pool_name."_avg_req.label Avg Req\n"; |
||
| 63 | print $pool_name."_avg_req.min 0\n"; |
||
| 64 | print $pool_name."_avg_req.draw LINE2\n"; |
||
| 65 | # stats: average time for query |
||
| 66 | print "multigraph ".$plugin_name."_stats_avg_query\n"; |
||
| 67 | print "graph_title PgBouncer $pool_name average query time\n"; |
||
| 68 | print "graph_args --base 1000\n"; # numbers not bytes |
||
| 69 | print "graph_vlabel Average time per query (microseconds)\n"; |
||
| 70 | print "graph_category pgbouncer\n"; |
||
| 71 | print $pool_name."_avg_query.type GAUGE\n"; |
||
| 72 | print $pool_name."_avg_query.label Avg Time\n"; |
||
| 73 | print $pool_name."_avg_query.min 0\n"; |
||
| 74 | print $pool_name."_avg_query.draw LINE2\n"; |
||
| 75 | # stats: in/out bytes |
||
| 76 | print "multigraph ".$plugin_name."_stats_bytesinout\n"; |
||
| 77 | print "graph_title PgBouncer $pool_name average bytes received/sent\n"; |
||
| 78 | print "graph_args --base 1024\n"; # numbers in bytes |
||
| 79 | print "graph_vlabel Average bytes received (-)/sent (+)\n"; |
||
| 80 | print "graph_category pgbouncer\n"; |
||
| 81 | # bytes received |
||
| 82 | print $pool_name."_avg_recv.type GAUGE\n"; |
||
| 83 | print $pool_name."_avg_recv.label Avg received\n"; |
||
| 84 | print $pool_name."_avg_recv.min 0\n"; |
||
| 85 | print $pool_name."_avg_recv.draw LINE1\n"; |
||
| 86 | print $pool_name."_avg_recv.graph no\n"; |
||
| 87 | # bytes sent |
||
| 88 | print $pool_name."_avg_sent.type GAUGE\n"; |
||
| 89 | print $pool_name."_avg_sent.label Avg rcvd/sent\n"; |
||
| 90 | print $pool_name."_avg_sent.min 0\n"; |
||
| 91 | print $pool_name."_avg_sent.draw LINE1\n"; |
||
| 92 | print $pool_name."_avg_sent.negative ".$pool_name."_avg_recv\n"; |
||
| 93 | # pools: server (sv_) |
||
| 94 | print "multigraph ".$plugin_name."_pools_server\n"; |
||
| 95 | print "graph_title PgBouncer $pool_name servers\n"; |
||
| 96 | print "graph_category pgbouncer\n"; |
||
| 97 | print "graph_args --base 1000\n"; # numbers not bytes |
||
| 98 | print "graph_vlabel Server connections\n"; |
||
| 99 | print "graph_scale no\n"; |
||
| 100 | # active connections |
||
| 101 | print $pool_name."_server_active.label active\n"; |
||
| 102 | print $pool_name."_server_active.min 0\n"; |
||
| 103 | print $pool_name."_server_active.type GAUGE\n"; |
||
| 104 | print $pool_name."_server_active.draw AREA\n"; |
||
| 105 | # idle connections |
||
| 106 | print $pool_name."_server_idle.label idle\n"; |
||
| 107 | print $pool_name."_server_idle.min 0\n"; |
||
| 108 | print $pool_name."_server_idle.type GAUGE\n"; |
||
| 109 | print $pool_name."_server_idle.draw STACK\n"; |
||
| 110 | # used connections |
||
| 111 | print $pool_name."_server_used.label used\n"; |
||
| 112 | print $pool_name."_server_used.min 0\n"; |
||
| 113 | print $pool_name."_server_used.type GAUGE\n"; |
||
| 114 | print $pool_name."_server_used.draw STACK\n"; |
||
| 115 | # tested connections |
||
| 116 | print $pool_name."_server_tested.label tested\n"; |
||
| 117 | print $pool_name."_server_tested.min 0\n"; |
||
| 118 | print $pool_name."_server_tested.type GAUGE\n"; |
||
| 119 | print $pool_name."_server_tested.draw STACK\n"; |
||
| 120 | # logged in connections |
||
| 121 | print $pool_name."_server_login.label login\n"; |
||
| 122 | print $pool_name."_server_login.min 0\n"; |
||
| 123 | print $pool_name."_server_login.type GAUGE\n"; |
||
| 124 | print $pool_name."_server_login.draw STACK\n"; |
||
| 125 | # pools: client (cl_) |
||
| 126 | print "multigraph ".$plugin_name."_pools_client\n"; |
||
| 127 | print "graph_title PgBouncer $pool_name clients\n"; |
||
| 128 | print "graph_category pgbouncer\n"; |
||
| 129 | print "graph_args --base 1000\n"; # numbers not bytes |
||
| 130 | print "graph_vlabel Client connections\n"; |
||
| 131 | print "graph_scale no\n"; |
||
| 132 | # active client connections |
||
| 133 | print $pool_name."_client_active.label active\n"; |
||
| 134 | print $pool_name."_client_active.min 0\n"; |
||
| 135 | print $pool_name."_client_active.type GAUGE\n"; |
||
| 136 | print $pool_name."_client_active.draw AREA\n"; |
||
| 137 | # waiting client connections |
||
| 138 | print $pool_name."_client_waiting.label waiting\n"; |
||
| 139 | print $pool_name."_client_waiting.min 0\n"; |
||
| 140 | print $pool_name."_client_waiting.type GAUGE\n"; |
||
| 141 | print $pool_name."_client_waiting.draw STACK\n"; |
||
| 142 | # pools: maxwait (longest waiting connection, should be 0) |
||
| 143 | print "multigraph ".$plugin_name."_pools_maxwait\n"; |
||
| 144 | print "graph_title PgBouncer $pool_name maximum waiting time\n"; |
||
| 145 | print "graph_args --base 1000\n"; # numbers not bytes |
||
| 146 | print "graph_vlabel Maximum wait time (seconds)\n"; |
||
| 147 | print "graph_category pgbouncer\n"; |
||
| 148 | print $pool_name."_maxwait.type GAUGE\n"; |
||
| 149 | print $pool_name."_maxwait.label Wait Time\n"; |
||
| 150 | print $pool_name."_maxwait.min 0\n"; |
||
| 151 | print $pool_name."_maxwait.draw LINE2\n"; |
||
| 152 | print $pool_name."_maxwait.warning 1\n"; # warn if not 0 |
||
| 153 | print $pool_name."_maxwait.critical 10\n"; # go critical if 10 seconds waiting |
||
| 154 | # END graph |
||
| 155 | exit 0; |
||
| 156 | } |
||
| 157 | } |
||
| 158 | |||
| 159 | # connect to data |
||
| 160 | 6facd3c3 | Clemens Schwaighofer | my $dbh = DBI->connect("DBI:Pg:dbname=$db_name;host=$db_host;port=$db_port", $db_user, $db_pass)
|
| 161 | or die ("Cannot connect to database");
|
||
| 162 | 8a515d24 | Clemens Schwaighofer | # go trough each set and get the data |
| 163 | 647632f7 | Clemens Schwaighofer | foreach my $get ('pools', 'stats')
|
| 164 | 8a515d24 | Clemens Schwaighofer | {
|
| 165 | # prep and execute the show query |
||
| 166 | 6facd3c3 | Clemens Schwaighofer | my $pre = $dbh->prepare("SHOW $get")
|
| 167 | or die ("Cannot prepare query");
|
||
| 168 | $pre->execute() |
||
| 169 | d44f2ac6 | kolyagora | or die ("Cannot execute statement");
|
| 170 | 8a515d24 | Clemens Schwaighofer | while (@data = $pre->fetchrow) |
| 171 | {
|
||
| 172 | # first defines the pool |
||
| 173 | if ($data[0] eq $pool_name) |
||
| 174 | {
|
||
| 175 | # print values for the stats: average reqeust, average query time, bytes in/out |
||
| 176 | if ($get eq 'stats') |
||
| 177 | {
|
||
| 178 | print "multigraph ".$plugin_name."_".$get."_avg_req\n"; |
||
| 179 | print $pool_name."_avg_req.value ".$data[5]."\n"; |
||
| 180 | print "multigraph ".$plugin_name."_".$get."_avg_query\n"; |
||
| 181 | print $pool_name."_avg_query.value ".$data[8]."\n"; |
||
| 182 | print "multigraph ".$plugin_name."_".$get."_bytesinout\n"; |
||
| 183 | print $pool_name."_avg_recv.value ".$data[6]."\n"; |
||
| 184 | print $pool_name."_avg_sent.value ".$data[7]."\n"; |
||
| 185 | } |
||
| 186 | # print data for the pools: server, client |
||
| 187 | if ($get eq 'pools') |
||
| 188 | {
|
||
| 189 | print "multigraph ".$plugin_name."_".$get."_server\n"; |
||
| 190 | print $pool_name."_server_active.value ".$data[4]."\n"; |
||
| 191 | print $pool_name."_server_idle.value ".$data[5]."\n"; |
||
| 192 | print $pool_name."_server_used.value ".$data[6]."\n"; |
||
| 193 | print $pool_name."_server_tested.value ".$data[7]."\n"; |
||
| 194 | print $pool_name."_server_login.value ".$data[8]."\n"; |
||
| 195 | print "multigraph ".$plugin_name."_".$get."_client\n"; |
||
| 196 | print $pool_name."_client_active.value ".$data[2]."\n"; |
||
| 197 | print $pool_name."_client_waiting.value ".$data[3]."\n"; |
||
| 198 | print "multigraph ".$plugin_name."_".$get."_maxwait\n"; |
||
| 199 | print $pool_name."_maxwait.value ".$data[9]."\n"; |
||
| 200 | } |
||
| 201 | } |
||
| 202 | } |
||
| 203 | } |
||
| 204 | # close connection |
||
| 205 | $dbh->disconnect(); |
||
| 206 | |||
| 207 | exit 0; |
||
| 208 | |||
| 209 | __END__ |
||
| 210 | |||
| 211 | =head1 NAME |
||
| 212 | |||
| 213 | pgbouncer_ is a plugin to get the pool and stat values for a single pgbouncer pool name |
||
| 214 | |||
| 215 | =head1 APPLICATION |
||
| 216 | |||
| 217 | perl and DBD::Pg is required, and pgbounce must been installed with a correct setup access for a stat account |
||
| 218 | |||
| 219 | =head1 CONFIGURATION |
||
| 220 | |||
| 221 | the plugin that will be run needs to have the pool name after the plguin base name. |
||
| 222 | |||
| 223 | =head2 plugin configuration |
||
| 224 | |||
| 225 | eg: pgbouncer_foo will run for the pool named foo. |
||
| 226 | |||
| 227 | see SHOW POOLS database list for the pool name |
||
| 228 | |||
| 229 | =head2 munin plugin config file |
||
| 230 | |||
| 231 | in the plugin config file under the [pgbouncer] name the access information ca be set. |
||
| 232 | |||
| 233 | eg: |
||
| 234 | [pgbouncer*] |
||
| 235 | env.pgbouncer_pass barfoo |
||
| 236 | |||
| 237 | more extended would be: |
||
| 238 | [pgbouncer*] |
||
| 239 | env.pgbouncer_pass barfoo |
||
| 240 | env.pgbouncer_user bar |
||
| 241 | env.pgbouncer_port 6542 |
||
| 242 | env.pgbouncer_host localhost |
||
| 243 | |||
| 244 | The database name is always pgbouncer |
||
| 245 | |||
| 246 | =head1 OUTPUT |
||
| 247 | |||
| 248 | The plugin will output 5 graphs in the group pgbouncer |
||
| 249 | |||
| 250 | =head2 Average bytes received/sent |
||
| 251 | |||
| 252 | This graph will show the average bytes sent and received by the pgbouncer for this pool |
||
| 253 | |||
| 254 | =head2 Avaerage connections |
||
| 255 | |||
| 256 | This graph will show the average amount of connections to the pgbouncer for this pool |
||
| 257 | |||
| 258 | =head2 Average query time |
||
| 259 | |||
| 260 | This graph shows the average query time as processed by the pgbouncer for this pool in microseconds. The data will be shorted by standard SI. eg, m = milli, k = kilo. |
||
| 261 | |||
| 262 | So 4.61K is 4610 milliseconds |
||
| 263 | |||
| 264 | =head2 Client connections |
||
| 265 | |||
| 266 | This graph shows the active and waiting client connections to pgbouncer for this pool |
||
| 267 | |||
| 268 | =head2 Server connections |
||
| 269 | |||
| 270 | This graph shows the server connections to pgbouncer for this pool. The following data sets are shown: active, idle, used, tested, login |
||
| 271 | |||
| 272 | =head2 Max wait |
||
| 273 | |||
| 274 | how long the oldest cllient the queue has waited, should be always 0 |
||
| 275 | |||
| 276 | =head1 ACKNOWLEDGEMENTS |
||
| 277 | |||
| 278 | Original idea derived from a simple python script by Dimitri Fontaine |
||
| 279 | |||
| 280 | =head1 SEE ALSO |
||
| 281 | |||
| 282 | See further info on stats and pools on the pgbouncer homepage: |
||
| 283 | http://pgbouncer.projects.postgresql.org/doc/usage.html#_show_commands |
||
| 284 | |||
| 285 | =head1 VERSION |
||
| 286 | |||
| 287 | 1.0 |
||
| 288 | |||
| 289 | =head1 AUTHOR |
||
| 290 | |||
| 291 | Clemens Schwaighofer <gullevek@gullevek.org> |
||
| 292 | |||
| 293 | =head1 LICENSE |
||
| 294 | |||
| 295 | GPLv2 |
||
| 296 | |||
| 297 | |||
| 298 | =cut |
