|
Server : Apache/2.2.2 (Fedora) System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686 User : apache ( 48) PHP Version : 5.2.9 Disable Function : NONE Directory : /usr/local/src/munin-1.2.6/node/node.d.linux/ |
Upload File : |
#!@@PERL@@ -w
#
# Plugin to monitor memory usage.
#
# Origional Author: Jimmy Olsen
# Contributors:
# Mike Fedyk: Slab, SwapCached, PageTables, VmallocUsed, Mapped, Active, Inactive, 2.4 Rmap & 2.6
#
# Parameters:
#
# config (required)
# autoconf (optional - only used by munin-config)
#
# Magic markers (optional - only used by munin-config and some
# installation scripts):
#%# family=auto
#%# capabilities=autoconf
if ($ARGV[0] and $ARGV[0] eq "autoconf")
{
if (-r "/proc/meminfo")
{
print "yes\n";
exit 0;
}
else
{
print "/proc/meminfo not found\n";
exit 1;
}
}
my %mems;
&fetch_meminfo;
if ($ARGV[0] and $ARGV[0] eq "config")
{
print "graph_args --base 1024 -l 0 --vertical-label Bytes --upper-limit ", $mems{'MemTotal'}, "\n";
print "graph_title Memory usage\n";
print "graph_category system\n";
print "graph_info This graph shows what the machine uses its memory for.\n";
print "graph_order ",
"apps ";
if (exists $mems{'PageTables'})
{
print "page_tables ";
}
if (exists $mems{'SwapCached'})
{
print "swap_cache ";
}
if (exists $mems{'VmallocUsed'})
{
print "vmalloc_used ";
}
if (exists $mems{'Slab'})
{
print "slab ";
}
print "cached ",
"buffers ",
"free ",
"swap ",
"\n";
print "apps.label apps\n";
print "apps.draw AREA\n";
print "apps.info Memory used by user-space applications.\n";
print "buffers.label buffers\n";
print "buffers.draw STACK\n";
print "buffers.info Block device (e.g. harddisk) cache. Also where \"dirty\" blocks are stored until written.\n";
print "swap.label swap\n";
print "swap.draw STACK\n";
print "swap.info Swap space used.\n";
print "cached.label cache\n";
print "cached.draw STACK\n";
print "cached.info Parked file data (file content) cache.\n";
print "free.label unused\n";
print "free.draw STACK\n";
print "free.info Wasted memory. Memory that is not used for anything at all.\n";
if (exists $mems{'Slab'})
{
print "slab.label slab_cache\n";
print "slab.draw STACK\n";
print "slab.info Memory used by the kernel (major users are caches like inode, dentry, etc).\n";
}
if (exists $mems{'SwapCached'})
{
print "swap_cache.label swap_cache\n";
print "swap_cache.draw STACK\n";
print "swap_cache.info A piece of memory that keeps track of pages that have been fetched from swap but not yet been modified.\n";
}
if (exists $mems{'PageTables'})
{
print "page_tables.label page_tables\n";
print "page_tables.draw STACK\n";
print "page_tables.info Memory used to map between virtual and physical memory addresses.\n"
}
if (exists $mems{'VmallocUsed'})
{
print "vmalloc_used.label vmalloc_used\n";
print "vmalloc_used.draw STACK\n";
print "vmalloc_used.info Virtual memory used by the kernel (used when the memory does not have to be physically contiguous).\n";
}
if (exists $mems{'Committed_AS'})
{
print "committed.label committed\n";
print "committed.draw LINE2\n";
# Linux machines frequently overcommit - this is not a
# error condition or even worrying. But sometimes
# overcommit shows memory leaks so we want to graph
# it.
# print "committed.warning ", $mems{'SwapTotal'} + $mems{'MemTotal'}, "\n";
print "committed.info The amount of memory allocated by the kernel to programs. Overcommitting is normal, but may indicate memory leaks.\n";
}
if (exists $mems{'Mapped'})
{
print "mapped.label mapped\n";
print "mapped.draw LINE2\n";
print "mapped.info All mmap()ed pages.\n";
}
if (exists $mems{'Active'})
{
print "active.label active\n";
print "active.draw LINE2\n";
print "active.info Memory recently used. Not reclaimed unless absolutely necessary.\n";
}
if (exists $mems{'ActiveAnon'})
{
print "active_anon.label active_anon\n";
print "active_anon.draw LINE1\n";
}
if (exists $mems{'ActiveCache'})
{
print "active_cache.label active_cache\n";
print "active_cache.draw LINE1\n";
}
if (exists $mems{'Inactive'})
{
print "inactive.label inactive\n";
print "inactive.draw LINE2\n";
print "inactive.info Memory not currently used.\n";
}
if (exists $mems{'Inact_dirty'})
{
print "inact_dirty.label inactive_dirty\n";
print "inact_dirty.draw LINE1\n";
print "inact_dirty.info Memory not currently used, but in need of being written to disk.\n";
}
if (exists $mems{'Inact_laundry'})
{
print "inact_laundry.label inactive_laundry\n";
print "inact_laundry.draw LINE1\n";
}
if (exists $mems{'Inact_clean'})
{
print "inact_clean.label inactive_clean\n";
print "inact_clean.draw LINE1\n";
print "inact_clean.info Memory not currently used.\n";
}
exit 0;
}
# Any optional value needs to be initialized to zero if it's used in a calculation below
# and is has not been set by &fetch_meminfo
if (exists $mems{'Slab'})
{
print "slab.value ", $mems{'Slab'}, "\n";
}
else
{
$mems{'Slab'} = 0;
}
if (exists $mems{'SwapCached'})
{
print "swap_cache.value ", $mems{'SwapCached'}, "\n";
}
else
{
$mems{'SwapCached'} = 0;
}
if (exists $mems{'PageTables'})
{
print "page_tables.value ", $mems{'PageTables'}, "\n";
}
else
{
$mems{'PageTables'} = 0;
}
if (exists $mems{'VmallocUsed'})
{
print "vmalloc_used.value ", $mems{'VmallocUsed'}, "\n";
}
else
{
$mems{'VmallocUsed'} = 0;
}
print "apps.value ", $mems{'MemTotal'}
-$mems{'MemFree'}
-$mems{'Buffers'}
-$mems{'Cached'}
-$mems{'SwapCached'}
-$mems{'Slab'}
-$mems{'PageTables'}
-$mems{'VmallocUsed'}
,"\n";
print "free.value ", $mems{'MemFree'}, "\n";
print "buffers.value ", $mems{'Buffers'}, "\n";
print "cached.value ", $mems{'Cached'}, "\n";
print "swap.value ", $mems{'SwapTotal'} - $mems{'SwapFree'}, "\n";
if (exists $mems{'Committed_AS'})
{
print "committed.value ", $mems{'Committed_AS'}, "\n";
}
if (exists $mems{'Mapped'})
{
print "mapped.value ", $mems{'Mapped'}, "\n";
}
if (exists $mems{'Active'})
{
print "active.value ", $mems{'Active'}, "\n";
}
if (exists $mems{'ActiveAnon'})
{
print "active_anon.value ", $mems{'ActiveAnon'}, "\n";
}
if (exists $mems{'ActiveCache'})
{
print "active_cache.value ", $mems{'ActiveCache'}, "\n";
}
if (exists $mems{'Inactive'})
{
print "inactive.value ", $mems{'Inactive'}, "\n";
}
if (exists $mems{'Inact_dirty'})
{
print "inact_dirty.value ", $mems{'Inact_dirty'}, "\n";
}
if (exists $mems{'Inact_laundry'})
{
print "inact_laundry.value ", $mems{'Inact_laundry'}, "\n";
}
if (exists $mems{'Inact_clean'})
{
print "inact_clean.value ", $mems{'Inact_clean'}, "\n";
}
sub fetch_meminfo
{
open (IN, "/proc/meminfo") || die "Could not open /proc/meminfo for reading: $!";
while (<IN>)
{
if (/^(\w+):\s*(\d+)\s+kb/i)
{
$mems{"$1"} = $2 * 1024;
}
}
close (IN);
# Only 2.6 and above has slab reported in meminfo, so read slabinfo if it isn't in meminfo
if (!$mems{Slab})
{
&fetch_slabinfo;
}
# Support 2.4 Rmap VM based kernels
if (!$mems{'Inactive'} && $mems{'Inact_dirty'} && $mems{'Inact_laundry'} && $mems{'Inact_clean'})
{
$mems{'Inactive'} = $mems{'Inact_dirty'} + $mems{'Inact_laundry'} + $mems{'Inact_clean'}
}
}
sub fetch_slabinfo
{
# In 2.0 there is no slabinfo file, so return if the file doesn't open
open (IN, "/proc/slabinfo") || return;
my @slabinfo;
my $tot_slab_pages = 0;
my $slab_version = <IN>;
if ($slab_version =~ /^slabinfo - version: 1.1/)
{
while (<IN>)
{
if (!/^slabinfo/)
{
@slabinfo = split;
$tot_slab_pages += $slabinfo[5];
}
}
}
close (IN);
if ($tot_slab_pages gt 0)
{
$mems{'Slab'} = $tot_slab_pages * 4096;
}
}
# vim:syntax=perl:ts=8