Initial checkin of xvm-munin-config package
[invirt/packages/xvm-munin-config.git] / master / usr / share / xvm-munin-master-config / plugins / postgres_space_
1 #!/usr/bin/perl -w
2 # -*- perl -*-
3
4 # Written by Bjrn Ruberg (bjorn@linpro.no) 2006
5 # Rewritten by Moses Moore 2006-04-08  moc.iazom@sesom
6 # Licenced under GPL
7
8 # Magic markers
9 #%# family=auto
10 #%# capabilities=autoconf suggest
11
12 use strict;
13 use DBI;
14 use vars qw ( $debug $suggest $configure $dbh );
15
16 # Package maintainers should provide an environment
17 # file for the /etc/munin/plugin-conf.d/ directory
18 # to override these values if necessary.
19 # NOTE: The plugin (also when auto configured) should
20 # be run by the postgresql user account.
21
22 # Need these variables at an early stage to enable
23 # autoconf and suggest
24 my $dbhost = $ENV{'dbhost'} || ''; # Connect to localhost by default
25 my $dbport = $ENV{'dbport'} || '';
26 my $dbuser = $ENV{'dbuser'} || 'postgres';
27 my $dbpass = $ENV{'dbpass'} || '';
28
29 if (exists $ARGV[0]) {
30     if ($ARGV[0] eq 'autoconf') {
31         # Check for DBD::Pg
32         if (! eval "require DBD::Pg;") {
33             print "no (DBD::Pg not found)";
34             exit 1;
35         }
36         # Then we try to detect Postgres presence by connecting to
37         # 'template1'.
38         my $dsn = "dbi:Pg:dbname=template1";
39         $dsn .= ";host=$dbhost" if $dbhost;
40         $dsn .= ";port=$dbport" if $dbport;
41         my $tempdbh = DBI->connect ($dsn, $dbuser, $dbpass);
42         if ($tempdbh) {
43             print "yes\n";
44             exit 0;
45         } else {
46             print "no (Can't connect to given host, please check environment settings)\n";
47             exit 1;
48         }
49     } elsif ($ARGV[0] and $ARGV[0] eq 'debug') {
50         # Set config flag
51         $debug = 1;
52     } elsif ($ARGV[0] and $ARGV[0] eq 'config') {
53         # Set config flag
54         $configure = 1;
55     } elsif ($ARGV[0] eq 'suggest') {
56         # doesn't always work
57         my @datasources = DBI->data_sources ('Pg');
58         foreach my $dsn (grep !/\=template\d$/, @datasources) {
59             (my $db = $dsn) =~ s/^.*=//;
60             print "$db\n";
61         }
62         exit 0;
63     }
64 }
65
66 # Must do this here, after checking for autoconf/suggest/etc, because the
67 # plugin must be able to run before it is linked to the databases.
68 my (undef, undef, $dbname) = split (/_/, $0, 3);
69 die "No dbname configured (did you make the proper symlink?)" unless $dbname;
70
71 my @datasources = DBI->data_sources ('Pg')
72     or die ("Can't read any possible data sources: $?");
73
74 my $dsn = "DBI:Pg:dbname=$dbname";
75 $dsn .= ";host=$dbhost" if $dbhost;
76 $dsn .= ";port=$dbport" if $dbport;
77 print "#$dsn\n" if $debug;
78 my $dbh = DBI->connect ($dsn, $dbuser, $dbpass, {RaiseError =>1});
79 unless($dbh) {
80     die("Database $dbname\@$dbhost (". $DBI::errstr .")\n");
81 }
82
83 if ($configure) {
84     print <<_EOM;
85 graph_title Postgres database $dbname
86 graph_args -l 0 --base 1024
87 graph_vlabel bytes
88 graph_category Postgresql
89 graph_info Size
90 size.label Database size (bytes)
91 size.info Database size
92 size.type GAUGE
93 size.draw AREA
94 indexsize.label Index size (bytes)
95 indexsize.info Index size
96 indexsize.type GAUGE
97 indexsize.draw STACK
98 metasize.label Meta database size (bytes)
99 metasize.info Meta database size
100 metasize.type GAUGE
101 metasize.draw STACK
102 metaindexsize.label Meta index size (bytes)
103 metaindexsize.info Meta index size
104 metaindexsize.type GAUGE
105 metaindexsize.draw STACK
106 _EOM
107 } else {
108     my $database_pages = 0;
109     my $database_indexes = 0;
110     my $metadatabase_pages = 0;
111     my $metadatabase_indexes = 0;
112     my @names = $dbh->tables;
113     
114     # Find relfilenode and relpages from the given table
115     my $q_ind = "SELECT relkind, relfilenode, relpages FROM pg_class
116                      WHERE relname = ?
117                      UNION
118                      SELECT relkind, relfilenode, relpages FROM pg_class
119                      WHERE relfilenode IN (SELECT indexrelid FROM pg_index 
120                      WHERE indrelid IN (SELECT relfilenode FROM pg_class
121                      WHERE relname = ?))";
122     my $sth = $dbh->prepare ($q_ind) or die $dbh->errstr;
123     
124     # Iterate over the tables in the database
125     foreach my $table (@names) {
126         my $meta = 1;
127         print "#TABLE: $table\n" if $debug;
128         my $table_pages = 0;
129         my $table_indexes = 0;
130         my $metatable_pages = 0;
131         my $metatable_indexes = 0;
132         # "public" tables are the user data
133         $meta = 0 if $table =~ /^public\./;
134         $table =~ s/^.*\.//;
135         
136         # Call the query with $table twice for each side of the UNION
137         $sth->execute ($table, $table) or die $dbh->errstr;
138         while (my ($relkind, $relfilenode, $relpages) = $sth->fetchrow_array) {
139             if ($relkind eq 'r') {
140                 $table_pages     += $relpages if $meta == 0;
141                 $metatable_pages += $relpages if $meta == 1;
142             } elsif ($relkind eq 'i') {
143                 $table_indexes     += $relpages if $meta == 0;
144                 $metatable_indexes += $relpages if $meta == 1;
145             }
146             # Define the query
147             my $q2 = "SELECT SUM(relpages) 
148                       FROM pg_class 
149                       WHERE relname IN (?, ?)";
150             my $sth2 = $dbh->prepare ($q2);
151             $sth2->execute ("pg_toast_${relfilenode}",
152                             "pg_toast_${relfilenode}_index");
153             my $relpages = $sth2->fetchrow_array;
154             if ($relpages) {
155                 if ($relkind eq 'r') {
156                     $table_pages     += $relpages if $meta == 0;
157                     $metatable_pages += $relpages if $meta == 1;
158                 } elsif ($relkind eq 'i') {
159                     $table_indexes     += $relpages if $meta == 0;
160                     $metatable_indexes += $relpages if $meta == 1;
161                 }
162             }
163             print "#\tR:$relfilenode\tP:$table_pages\tI:$table_indexes\n" if $debug;
164         }
165         $database_pages       += $table_pages;
166         $database_indexes     += $table_indexes;
167         $metadatabase_pages   += $metatable_pages;
168         $metadatabase_indexes += $metatable_indexes;
169     }    
170     $sth->finish;
171     $dbh->disconnect;
172     print "size\.value " . $database_pages * 8192 . "\n";
173     print "indexsize\.value " . $database_indexes * 8192 . "\n";
174     print "metasize\.value " . $metadatabase_pages * 8192 . "\n";
175     print "metaindexsize\.value " . $metadatabase_indexes * 8192 . "\n";
176 }