1 |
#!/usr/bin/perl -w |
2 |
use strict; |
3 |
use Getopt::Long; |
4 |
|
5 |
my $interface="lo"; |
6 |
my $dpmqryconf="/opt/lcg/bin/dpm-qryconf"; |
7 |
my $gmetric="/usr/bin/gmetric"; |
8 |
my $verbose=0; |
9 |
|
10 |
my $opt_scommand; |
11 |
my $opt_gmetric; |
12 |
my %opt; |
13 |
my @optdef=qw( scommand=s gmetric=s verbose ); |
14 |
|
15 |
$Getopt::Long::ignorecase=0; |
16 |
&GetOptions(\%opt, @optdef) or die "\n"; |
17 |
$opt{"dpmqryconf"} and $dpmqryconf=$opt{"dpmqryconf"}; |
18 |
$opt{"gmetric"} and $gmetric=$opt{"gmetric"}; |
19 |
$opt{"verbose"} and $verbose=1; |
20 |
|
21 |
# scaling of SI units to GB = 1e9 bytes |
22 |
my %scale_factor = ( k => 1e-6, M => 1e-3, G => 1., T => 1e3, P => 1e6 ); |
23 |
|
24 |
# |
25 |
# Wrapper around the system call to gmetric |
26 |
# Allows to view the results on STDOUT if verbose output was requested |
27 |
# |
28 |
# Arguments: |
29 |
# type string with value { float, double, string, (u)int(8|16|32) } |
30 |
# name string |
31 |
# unit string, may be empty |
32 |
# value string |
33 |
# |
34 |
sub publish() { |
35 |
my ($type, $name, $unit, $value) = @_; |
36 |
|
37 |
# substitute / by - because the slash cannot be used in the |
38 |
# name of the rrd file |
39 |
$name =~ tr!/!-!; |
40 |
|
41 |
if ($verbose) { |
42 |
if ($type eq 'float' or $type eq 'double') { |
43 |
printf "%-24s %24.3f %-s\n", $name, $value, $unit; |
44 |
} |
45 |
elsif ($type eq 'string') { |
46 |
printf "%-24s %24s %-s\n", $name, $value, $unit; |
47 |
$value = "\"$value\""; # in-place substitution of $value |
48 |
} |
49 |
else { # must be some kind of int or uint |
50 |
printf "%-24s %24d %-s\n", $name, $value, $unit; |
51 |
} |
52 |
} |
53 |
|
54 |
$unit = ($unit ? "-u \"$unit\"" : ""); # in-place substitution of $unit |
55 |
system("$gmetric -t $type -n \"$name\" -v $value $unit"); |
56 |
} |
57 |
|
58 |
|
59 |
sub get_scale() { |
60 |
my $unit = shift; |
61 |
my $factor = $scale_factor{$unit} or |
62 |
die "Invalid scaling factor $unit\n"; |
63 |
return($factor); |
64 |
} |
65 |
|
66 |
############################################################################## |
67 |
# output of dpm-qryconf |
68 |
# |
69 |
|
70 |
my $cmd = "DPNS_CONRETRY=0 $dpmqryconf --si "; |
71 |
my @out = `$cmd`; |
72 |
|
73 |
|
74 |
# gather data per pool |
75 |
my $poolname; |
76 |
my %pool; |
77 |
foreach my $line ( @out ) { |
78 |
if ( $line =~ /^POOL (\w+) / ) { |
79 |
$poolname = $1; |
80 |
$pool{$poolname}{capacity} = 0; |
81 |
$pool{$poolname}{free} = 0; |
82 |
$pool{$poolname}{used} = 0; |
83 |
} |
84 |
elsif ( $line =~ /^\s+CAPACITY (\d+\.\d+)([kMGTP]) FREE (\d+\.\d+)([kMGTP])/ ) { |
85 |
$pool{$poolname}{capacity} = $1 * &get_scale($2); |
86 |
} |
87 |
elsif ( $line =~ /CAPACITY (\d+\.\d+)([kMGTP]) FREE (\d+\.\d+)([kMGTP])/ ) { |
88 |
$pool{$poolname}{used} += $1 * &get_scale($2) - $3 * &get_scale($4); |
89 |
} |
90 |
} |
91 |
|
92 |
|
93 |
# calculate global totals and publish data |
94 |
my $total_capacity = 0; |
95 |
my $total_free = 0; |
96 |
my $total_used = 0; |
97 |
foreach my $pn ( sort keys %pool ) { |
98 |
$pool{$pn}{free} = $pool{$pn}{capacity} - $pool{$pn}{used}; |
99 |
|
100 |
# combine per-pool data in totals |
101 |
$total_capacity += $pool{$pn}{capacity}; |
102 |
$total_free += $pool{$pn}{free}; |
103 |
$total_used += $pool{$pn}{used}; |
104 |
|
105 |
# publish to Ganglia |
106 |
&publish('double', "pool-$pn-capacity", "GB", $pool{$pn}{capacity}); |
107 |
&publish('double', "pool-$pn-free", "GB", $pool{$pn}{free}); |
108 |
&publish('double', "pool-$pn-used", "GB", $pool{$pn}{used}); |
109 |
} |
110 |
|
111 |
# publish totals to Ganglia |
112 |
&publish('double', "DPM-capacity", "GB", $total_capacity); |
113 |
&publish('double', "DPM-free", "GB", $total_free); |
114 |
&publish('double', "DPM-used", "GB", $total_used); |