Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / other / buddyinfo @ 2d334ef3

Historique | Voir | Annoter | Télécharger (3,47 ko)

1
#! /usr/bin/perl -w
2

    
3
=head1 NAME
4

    
5
buddyinfo - Plugin to monitor memory fragmentation on Linux systems.
6

    
7
=head1 APPLICABLE SYSTEMS
8

    
9
Linux 2.6
10

    
11
=head1 CONFIGURATION
12

    
13
None needed.
14

    
15
=head1 INTERPRETATION
16

    
17
Linux manages virtual memory on a page granularity. There are some operations
18
however that require physically contiguous pages to be allocated by the kernel.
19
Such allocations may fail if the memory gets fragmented and even though there
20
are enough pages free, but they are not contiguous.
21

    
22
This plugin monitors the amount of contiguous areas, called higher order pages.
23
The order means the exponent of two of the size of the area, so order 2 means
24
2^2 = 4 pages.
25

    
26
=head1 SEE ALSO
27

    
28
See C<Documentation/filesystems/proc.txt> in the Linux source tree for the
29
description of the buddyinfo file.
30

    
31
=head1 MAGIC MARKERS
32

    
33
 #%# family=manual
34
 #%# capabilities=autoconf
35

    
36
=head1 AUTHOR
37

    
38
Gábor Gombás <gombasg@sztaki.hu>
39

    
40
=head1 LICENSE
41

    
42
GPLv2 or later
43

    
44
=cut
45

    
46
use strict;
47
use Munin::Plugin;
48
use POSIX;
49
use Carp;
50

    
51
need_multigraph();
52

    
53
if ($ARGV[0] and $ARGV[0] eq 'autoconf') {
54
	if (-f "/proc/buddyinfo") {
55
		print "yes\n";
56
	}
57
	else {
58
		print "no (/proc/buddyinfo is missing)\n";
59
	}
60
	exit 0;
61
}
62

    
63
# The most common page size is 4k, but it is not universal
64
my $pagesize = POSIX::sysconf(&POSIX::_SC_PAGESIZE) / 1024;
65

    
66
my $zones = {};
67

    
68
open(FH, '< /proc/buddyinfo')
69
	or croak "Failed to open '/proc/buddyinfo': $!";
70
while (my $line = <FH>) {
71
	chomp $line;
72

    
73
	$line =~ m/Node (\d+), zone\s+(\S+)\s+(\S.*)$/;
74
	my $name = "Node $1, zone $2";
75
	my @cnt = split(/ +/, $3);
76
	$zones->{$name} = \@cnt;
77
}
78
close FH;
79

    
80
my $totals = [];
81
foreach my $zone (keys %$zones) {
82
	for my $i (0 .. $#{$zones->{$zone}}) {
83
		$totals->[$i] += $zones->{$zone}->[$i]
84
	}
85
}
86

    
87
sub do_config {
88
	print "multigraph buddyinfo\n";
89
	print "graph_title Memory fragmentation\n";
90
	print "graph_args --base 1024 --lower-limit 0\n";
91
	print "graph_vlabel pages free\n";
92
	print "graph_category system\n";
93
	print "graph_info This graph shows the number of free pages of different size\n";
94
	print "graph_order " . join(' ', map { "order$_" } (0 .. $#{$totals})) . "\n";
95
	for my $i (0 .. $#{$totals}) {
96
		print "order$i.label Order $i\n";
97
		print "order$i.info Number of order $i (" . ($pagesize * 2 ** $i) . " KiB) pages\n";
98
		print "order$i.type GAUGE\n";
99
		print "order$i.draw LINE2\n";
100
		print "order$i.min 0\n";
101
	}
102
	for my $zone (sort keys %$zones) {
103
		my $zoneid = $zone;
104
		$zoneid = clean_fieldname($zone);
105

    
106
		print "multigraph buddyinfo.$zoneid\n";
107
		print "graph_title Memory fragmentation in $zone\n";
108
		print "graph_args --base 1024 --lower-limit 0\n";
109
		print "graph_vlabel pages free\n";
110
		print "graph_category system\n";
111
		print "graph_info This graph shows the number of free pages in $zone\n";
112
		print "graph_order " .
113
			join(' ', map { "order$_" } (0 .. $#{$zones->{$zone}})) . "\n";
114
		for my $i (0 .. $#{$zones->{$zone}}) {
115
			print "order$i.label Order $i\n";
116
			print "order$i.info Number of order $i (" .
117
				($pagesize * 2 ** $i) . " KiB) pages\n";
118
			print "order$i.type GAUGE\n";
119
			print "order$i.draw LINE2\n";
120
			print "order$i.min 0\n";
121
		}
122
	}
123
}
124

    
125
sub do_fetch {
126
	print "multigraph buddyinfo\n";
127
	for my $i (0 .. $#{$totals}) {
128
		print "order$i.value " . $totals->[$i] . "\n";
129
	}
130
	for my $zone (sort keys %$zones) {
131
		my $zoneid = $zone;
132
		$zoneid =~ tr/ ,/__/;
133

    
134
		print "multigraph buddyinfo.$zoneid\n";
135
		for my $i (0 .. $#{$zones->{$zone}}) {
136
			print "order$i.value " . $zones->{$zone}->[$i] . "\n";
137
		}
138
	}
139
}
140

    
141
if ($ARGV[0] and $ARGV[0] eq 'config') {
142
	do_config();
143
	exit 0;
144
}
145

    
146
do_fetch();