#!/usr/bin/perl use warnings; use strict; use Statistics::Descriptive; my $webuser = 'www-data'; my $command = 'apache2'; my @top = `top -bn1`; my %header; my $mem = Statistics::Descriptive::Full->new(); my $othermem = Statistics::Descriptive::Full->new(); my $totalmem; foreach (@top) { s/^\s+|\s+$//sg; my @line = split(/\s+/, $_); if(/mem:\s+(\S+)\s+total/i) { $totalmem = convtok($1); } if(defined $line[3] && exists $header{res} && $line[0] =~ /^\d+$/) { next unless (defined $line[$header{user}] && defined $line[$header{res}] && defined $line[$header{shr}] && defined $line[$header{command}]); if(($line[$header{user}] eq $webuser) && ($line[$header{command}] eq $command)) { $mem->add_data(convtok($line[$header{res}]) - convtok($line[$header{shr}])); } else { $othermem->add_data(convtok($line[$header{res}]) - convtok($line[$header{shr}])); } } elsif (!exists $header{res}) { my %tempheader; for (0 .. $#line) { $tempheader{lc($line[$_])} = $_; } if(defined $tempheader{user} && defined $tempheader{res} && defined $tempheader{shr} && defined $tempheader{command}) { %header = %tempheader; } } } printf "Total memory available: %.2fG\n", ($totalmem / 1024 / 1024); printf "Total used by $command (%d instances): %.2fG\n", $mem->count(), ($mem->sum() / 1024 / 1024); printf "Total used by other processes: %.2fG\n\n", ($othermem->sum() / 1024 / 1024); $totalmem -= $othermem->sum(); printf "Average memory used per $command process: %.2fM\n", ($mem->mean() / 1024); printf "Recommended number of processes based on Average: %d\n", ($totalmem / $mem->mean()); printf "Needed memory for 500 processes based on Average: %.2fG\n\n", ($mem->mean() / 1024 / 1024 * 500); printf "Max memory used for $command process: %.2fM\n", ($mem->max() / 1024); printf "Recommended number of processes based on Max: %d\n", ($totalmem / $mem->max()); printf "Needed memory for 500 processes based on Max: %.2fG\n\n", ($mem->max() / 1024 / 1024 * 500); printf "Mean plus two Standard Deviations (bulk of usage under max): %.2fM\n", (($mem->mean() + $mem->standard_deviation() * 2) / 1024); printf "Recommended number of processes based on Mean + 2*Stdev: %d\n", ($totalmem / ($mem->mean() + $mem->standard_deviation() * 2)); printf "Needed memory for 500 processes based on Mean + 2*Stdev: %.2fG\n", (($mem->mean() + $mem->standard_deviation() * 2) / 1024 / 1024 * 500); sub convtok { my $num = shift; if($num =~ /^\s*([0-9.]+)k\s*$/i) { $num = $1; } elsif ($num =~ /^\s*([0-9.]+)m\s*$/i) { $num = $1 * 1024; } elsif ($num =~ /^\s*([0-9.]+)g\s*$/i) { $num = $1 * 1024 * 1024; } return $num; }