#!/usr/bin/perl -w use strict; use Getopt::Long; my $interface="lo"; my $dpmqryconf="/opt/lcg/bin/dpm-qryconf"; my $gmetric="/usr/bin/gmetric"; my $verbose=0; my $opt_scommand; my $opt_gmetric; my %opt; my @optdef=qw( scommand=s gmetric=s verbose ); $Getopt::Long::ignorecase=0; &GetOptions(\%opt, @optdef) or die "\n"; $opt{"dpmqryconf"} and $dpmqryconf=$opt{"dpmqryconf"}; $opt{"gmetric"} and $gmetric=$opt{"gmetric"}; $opt{"verbose"} and $verbose=1; # scaling of SI units to GB = 1e9 bytes my %scale_factor = ( k => 1e-6, M => 1e-3, G => 1., T => 1e3, P => 1e6 ); # # Wrapper around the system call to gmetric # Allows to view the results on STDOUT if verbose output was requested # # Arguments: # type string with value { float, double, string, (u)int(8|16|32) } # name string # unit string, may be empty # value string # sub publish() { my ($type, $name, $unit, $value) = @_; # substitute / by - because the slash cannot be used in the # name of the rrd file $name =~ tr!/!-!; if ($verbose) { if ($type eq 'float' or $type eq 'double') { printf "%-24s %24.3f %-s\n", $name, $value, $unit; } elsif ($type eq 'string') { printf "%-24s %24s %-s\n", $name, $value, $unit; $value = "\"$value\""; # in-place substitution of $value } else { # must be some kind of int or uint printf "%-24s %24d %-s\n", $name, $value, $unit; } } $unit = ($unit ? "-u \"$unit\"" : ""); # in-place substitution of $unit system("$gmetric -t $type -n \"$name\" -v $value $unit"); } sub get_scale() { my $unit = shift; my $factor = $scale_factor{$unit} or die "Invalid scaling factor $unit\n"; return($factor); } ############################################################################## # output of dpm-qryconf # my $cmd = "DPNS_CONRETRY=0 $dpmqryconf --si "; my @out = `$cmd`; # gather data per pool my $poolname; my %pool; foreach my $line ( @out ) { if ( $line =~ /^POOL ([^\s]+) / ) { $poolname = $1; $pool{$poolname}{capacity} = 0; $pool{$poolname}{free} = 0; $pool{$poolname}{used} = 0; } elsif ( $line =~ /^\s+CAPACITY (\d+\.\d+)([kMGTP]) FREE (\d+\.\d+)([kMGTP])/ ) { $pool{$poolname}{capacity} = $1 * &get_scale($2); } elsif ( $line =~ /CAPACITY (\d+\.\d+)([kMGTP]) FREE (\d+\.\d+)([kMGTP])/ ) { $pool{$poolname}{used} += $1 * &get_scale($2) - $3 * &get_scale($4); } } # calculate global totals and publish data my $total_capacity = 0; my $total_free = 0; my $total_used = 0; foreach my $pn ( sort keys %pool ) { $pool{$pn}{free} = $pool{$pn}{capacity} - $pool{$pn}{used}; # combine per-pool data in totals $total_capacity += $pool{$pn}{capacity}; $total_free += $pool{$pn}{free}; $total_used += $pool{$pn}{used}; # publish to Ganglia &publish('double', "pool-$pn-capacity", "GB", $pool{$pn}{capacity}); &publish('double', "pool-$pn-free", "GB", $pool{$pn}{free}); &publish('double', "pool-$pn-used", "GB", $pool{$pn}{used}); } # publish totals to Ganglia &publish('double', "DPM-capacity", "GB", $total_capacity); &publish('double', "DPM-free", "GB", $total_free); &publish('double', "DPM-used", "GB", $total_used);