Projet

Général

Profil

Révision 2d334ef3

ID2d334ef3a43edb6d0e637fdd40b9d93c6429ab59
Parent dee7dda2
Enfant 9a168e78

Ajouté par Gabor Gombas il y a presque 14 ans

Initial version

Voir les différences:

plugins/other/buddyinfo
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();

Formats disponibles : Unified diff