#!/usr/bin/perl -w
###############################################################################
# Webmin Sysstats - mem.pl
#
# Webmin Sysstats Module
# Copyright (C) 2002 by Eric Gerbier
# Bug reports to: gerbier@users.sourceforge.net
# $Id$
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
###############################################################################
# generic linux code
use strict;
use warnings;
no warnings 'redefine';
use RRDs;
use English qw(-no_match_vars);
use FindBin;
# to be used alone or from sysstat.pl without warning
# because require verify the path
if ( !exists $ENV{WEBMINSTAT_TEMP} ) {
use lib "$FindBin::Bin/../..";
## no critic (RequireBarewordIncludes)
require 'sysstats-aquisition-lib.pl';
## use critic
}
my $module_name;
my $info = '/proc/meminfo';
my %config;
read_file_cached( 'config', \%config );
$module_name = $config{'name'};
debug( "run $module_name version " . $config{'version'} );
my %codes = action_load( \%config );
my ( $mem_total, $mem_used, $swap_total, $swap_used ) = ( 'U', 'U', 'U', 'U' );
# fix for 2.6 kernel : MemShared does not exist any more, so set it to 0
# to avoid some undefined values
my ( $mem_shared, $mem_buffers, $mem_cached ) = ( 0, 0, 0 );
my ( $swap_free, $mem_free );
my $r_tab = read_full_file($info);
foreach ( @{$r_tab} ) {
# old code : do not work on 2.6 kernels
# if (m/^Mem:/) {
# my @tab = split;
# $mtotal = $tab[1];
# $mused = $tab[2] - $tab[5] - $tab[6];
# $mshared = $tab[4];
# $mbuffers = $tab[5];
# $mcached = $tab[6];
# }
# elsif (m/^Swap:/) {
# my @tab = split;
# $stotal = $tab[1];
# $sused = $tab[2];
# }
# new code , compatible with 2.6 kernel
## no critic (ProhibitCascadingIfElse)
if (m/^MemTotal:\s*(\d+)/) {
$mem_total = $1;
}
elsif (m/^MemFree:\s*(\d+)/) {
$mem_free = $1;
}
elsif (m/^Buffers:\s*(\d+)/) {
$mem_buffers = $1;
}
elsif (m/^Cached:\s*(\d+)/) {
$mem_cached = $1;
}
elsif (m/^MemShared:\s*(\d+)/) {
$mem_shared = $1;
}
elsif (m/^SwapTotal:\s*(\d+)/) {
$swap_total = $1;
}
elsif (m/^SwapFree:\s*(\d+)/) {
$swap_free = $1;
}
}
$swap_used = $swap_total - $swap_free;
$mem_used = $mem_total - $mem_free - $mem_buffers - $mem_cached;
#debug(
#"$module_name : memtotal=$mem_total memused=$mem_used swaptotal=$swap_total swapused=$swap_used"
#);
# with webminstat 2.0
# all computing is done in aquisition
my $mmed = pourcent( $mem_used, $mem_total );
my $smed = ($swap_total) ? pourcent( $swap_used, $swap_total ) : 'U';
# names are set according list_params and graph display
debug( "$module_name : programs=" . int($mmed) . '% swap=' . $smed . PCENT() );
action_param( 'programs', $mmed, \%codes );
action_param( 'swap', $smed, \%codes );
#RRDs::update( 'mem.rrd', "N:$mem_total:$mem_used:$swap_total:$swap_used" );
# mem_total set to 100 to make rrd computing work in graph
my $rrdbase = 'mem.rrd';
RRDs::update( $rrdbase, "N:100:$mmed:100:$smed" );
my $ERR = RRDs::error();
warning("ERROR while updating $rrdbase database : $ERR") if $ERR;
#debug(
#"$module_name memshared=$mem_shared membuffer=$mem_buffers memcached=$mem_cached"
#);
my $mbuf = pourcent( $mem_buffers, $mem_total );
my $mca = pourcent( $mem_cached, $mem_total );
my $free = 100 - $mmed - $mbuf - $mca;
debug( "$module_name buffers="
. int($mbuf)
. '% cached='
. int($mca)
. '% free='
. int($free)
. PCENT() );
action_param( 'buffers', $mbuf, \%codes );
action_param( 'cached', $mca, \%codes );
action_param( 'free', $free, \%codes );
$rrdbase = 'mem2.rrd';
RRDs::update( $rrdbase, "N:$mem_shared:$mbuf:$mca" );
$ERR = RRDs::error();
warning("ERROR while updating $rrdbase database : $ERR") if $ERR;