You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
4.6 KiB
119 lines
4.6 KiB
#!/usr/bin/perl |
|
# |
|
# This reports the total memory used by all processes with to passed-in program name. |
|
# |
|
# The size in bytes is returned. If '0' is reported, check the exit code to see why. |
|
# |
|
# This software was created by Alteeve's Niche! Inc. and has been released under the terms of the GNU GPL |
|
# version 2. |
|
# |
|
# https://alteeve.com |
|
# |
|
# Exit Codes: |
|
# 0 - Success |
|
# 1 - No program name passed-in. |
|
# 2 - No PIDs found for the passed-in program name. |
|
# 3 - No PID returned by pgrep |
|
# |
|
|
|
use strict; |
|
use warnings; |
|
use Anvil::Tools; |
|
|
|
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; |
|
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; |
|
if (($running_directory =~ /^\./) && ($ENV{PWD})) |
|
{ |
|
$running_directory =~ s/^\./$ENV{PWD}/; |
|
} |
|
|
|
# Turn off buffering so that the pinwheel will display while waiting for the SSH call(s) to complete. |
|
$| = 1; |
|
|
|
my $anvil = Anvil::Tools->new(); |
|
|
|
$anvil->data->{switches}{program} = ""; |
|
$anvil->Get->switches; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
'switches::program' => $anvil->data->{switches}{program}, |
|
}}); |
|
|
|
$anvil->data->{memory}{total} = 0; |
|
|
|
# If we weren't given a program, exit |
|
if (not $anvil->data->{switches}{program}) |
|
{ |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0065"}); |
|
print "#!error!#\n"; |
|
$anvil->nice_exit({exit_code => 1}); |
|
} |
|
|
|
# Find the PID(s) of the program. |
|
$anvil->data->{sys}{pids} = $anvil->System->pids({ignore_me => 1, program_name => $anvil->data->{switches}{program}}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'sys::pids' => $anvil->data->{sys}{pids} }}); |
|
|
|
my $pids_found = @{$anvil->data->{sys}{pids}}; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { pids_found => $pids_found }}); |
|
|
|
if (not $pids_found) |
|
{ |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, key => "error_0066", variables => { prorgram => $anvil->data->{switches}{program} }}); |
|
print $anvil->data->{switches}{program}." = ".$anvil->data->{memory}{total}."\n"; |
|
$anvil->nice_exit({exit_code => 2}); |
|
} |
|
|
|
# Read in the smaps for each pid |
|
foreach my $pid (sort {$a cmp $b} @{$anvil->data->{sys}{pids}}) |
|
{ |
|
my $smaps_path = "/proc/".$pid."/smaps"; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { smaps_path => $smaps_path }}); |
|
|
|
# This will store the amount of RAM used by this specific PID. |
|
$anvil->data->{memory}{pid}{$pid} = 0; |
|
|
|
if (not -e $smaps_path) |
|
{ |
|
# It is possible that the program just closed. |
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 1, key => "log_0433", variables => { pid => $pid }}); |
|
next; |
|
} |
|
|
|
# Read in the file. |
|
my $body = $anvil->Storage->read_file({file => $smaps_path}); |
|
foreach my $line (split/\n/, $body) |
|
{ |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }}); |
|
if ($line =~ /^Private_Dirty:\s+(\d+) (.*B)$/) |
|
{ |
|
my $size = $1; |
|
my $type = $2; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
type => $type, |
|
size => $size, |
|
}}); |
|
next if not $size; |
|
next if $size =~ /\D/; |
|
|
|
# This uses 'kB' for 'KiB' >_> |
|
$type = lc($type); |
|
$type =~ s/b$/ib/ if $type !~ /ib$/; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { type => $type }}); |
|
|
|
my $size_in_bytes = $anvil->Convert->human_readable_to_bytes({size => $size, type => $type, base2 => 1}); |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
size_in_bytes => $anvil->Convert->add_commas({number => $size_in_bytes})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $size_in_bytes}).")", |
|
}}); |
|
|
|
$anvil->data->{memory}{pid}{$pid} += $size_in_bytes; |
|
$anvil->data->{memory}{total} += $size_in_bytes; |
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
|
"memory::pid::${pid}" => $anvil->Convert->add_commas({number => $anvil->data->{memory}{pid}{$pid}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{memory}{pid}{$pid}}).")", |
|
'memory::total' => $anvil->Convert->add_commas({number => $anvil->data->{memory}{total}})." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{memory}{total}}).")", |
|
}}); |
|
} |
|
} |
|
} |
|
|
|
# Report and exit. |
|
print $anvil->data->{switches}{program}." = ".$anvil->data->{memory}{total}." # ".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{memory}{total}})."\n"; |
|
$anvil->nice_exit({exit_code => 0});
|
|
|