1#!/usr/local/bin/perl -w
2
3=head1 NAME
4
5lvm_usage - Plugin to monitor usage of LVM volume groups
6
7=head1 CONFIGURATION
8
9Must be run as root:
10
11  [lvm_usage]
12    user root
13
14=head1 MAGIC MARKERS
15
16 #%# family=auto
17 #%# capabilities=autoconf
18
19=head1 AUTHOR
20
21Gábor Gombás <gombasg@sztaki.hu>
22
23=head1 LICENSE
24
25GPLv2 or later
26
27=cut
28
29use strict;
30use Munin::Plugin;
31use Carp;
32
33need_multigraph();
34
35if ($ARGV[0] and $ARGV[0] eq 'autoconf') {
36	if (-c "/dev/mapper/control") {
37		print "yes\n";
38	}
39	else {
40		print "no (/dev/mapper/control is missing)\n";
41	}
42	exit 0;
43}
44
45my %vgs;
46
47open(VGS, "vgs --units b --nosuffix --noheadings -o vg_name,vg_size,vg_free |")
48	or croak("Failed to run 'lvs': " . $!);
49while (my $line = <VGS>) {
50	chomp $line;
51	$line =~ s/^\s+//;
52	my ($vg_name, $vg_size, $vg_free) = split(/\s+/, $line);
53	$vgs{$vg_name}->{size} = $vg_size unless $vgs{$vg_name}->{size};
54	$vgs{$vg_name}->{free} = $vg_free unless $vgs{$vg_name}->{free};
55	$vgs{$vg_name}->{lvs} = {};
56}
57close VGS;
58
59open(LVS, "lvs --units b --nosuffix --noheadings -o vg_name,lv_name,lv_size |")
60	or croak("Failed to run 'lvs': " . $!);
61while (my $line = <LVS>) {
62	chomp $line;
63	$line =~ s/^\s+//;
64	my ($vg_name, $lv_name, $lv_size) = split(/\s+/, $line);
65	$vgs{$vg_name}->{lvs}->{$lv_name} = $lv_size;
66}
67close LVS;
68
69if ($ARGV[0] and $ARGV[0] eq 'config') {
70	print "multigraph lvm_usage\n";
71	print "graph_title LVM volume group usage\n";
72	print "graph_args --base 1024 --lower-limit 0 --upper-limit 100\n";
73	print "graph_vlabel %\n";
74        print "graph_category disk\n";
75	print "graph_order " . join(' ', map { clean_fieldname($_) } (sort keys %vgs)) . "\n";
76	for my $vg (sort keys %vgs) {
77		my $id = clean_fieldname($vg);
78		print "$id.label $vg\n";
79		print "$id.type GAUGE\n";
80		print "$id.draw LINE2\n";
81	}
82
83	for my $vg (sort keys %vgs) {
84		my $id = clean_fieldname($vg);
85
86		print "multigraph lvm_usage.$id\n";
87		print "graph_title Volume group usage ($vg)\n";
88		print "graph_args --base 1024 --lower-limit 0\n";
89		print "graph_vlabel bytes\n";
90        	print "graph_category disk\n";
91		print "__free.label Free space\n";
92		print "__free.draw AREA\n";
93
94		foreach my $lv (sort keys %{$vgs{$vg}->{lvs}}) {
95			my $id = clean_fieldname($lv);
96			print "$id.label $lv\n";
97			print "$id.draw STACK\n";
98		}
99	}
100
101	exit 0;
102}
103
104print "multigraph lvm_usage\n";
105for my $vg (sort keys %vgs) {
106	my $id = clean_fieldname($vg);
107	my $used = $vgs{$vg}->{'size'} - $vgs{$vg}->{'free'};
108	print "$id.value " . int($used * 100 / $vgs{$vg}->{'size'}) . "\n";
109}
110
111for my $vg (sort keys %vgs) {
112	my $id = clean_fieldname($vg);
113	print "multigraph lvm_usage.$id\n";
114	print "__free.value " . $vgs{$vg}->{free} . "\n";
115
116	foreach my $lv (sort keys %{$vgs{$vg}->{lvs}}) {
117		my $id = clean_fieldname($lv);
118		print "$id.value " . $vgs{$vg}->{lvs}->{$lv} . "\n";
119	}
120}
121