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