Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env perl
- use strict;
- use Time::HiRes qw(gettimeofday tv_interval);
- use POSIX 'strftime';
- sub read_proc {
- my %stats = ();
- my @io_files = glob "/proc/**/io";
- foreach (@io_files) {
- /\/proc\/(\d+)\/io/ or next;
- my $pid = $1;
- my %s = ();
- open(FIN, $_) or die "$!";
- while (<FIN>) {
- /^(write|read)_bytes: (\d+)$/ or next;
- $s{$1} = int($2);
- }
- close(FIN);
- $stats{$1} = \%s;
- }
- return %stats;
- }
- sub assoc_proc_name {
- my $stats = $_[0];
- my $ps = `ps -ef`;
- foreach (split /\n/, $ps) {
- my @c = split(/\s+/, $_);
- next if $c[0] eq "UID";
- $$stats{$c[1]}{"proc"} = join(" ", @c[7..$#c]);
- }
- }
- sub diff_stats {
- my $stats_now = $_[0];
- my $stats_prev = $_[1];
- my @stats_diff = ();
- foreach (keys(%$stats_now)) {
- next if not exists($$stats_prev{$_});
- my %s = ();
- $s{"pid"} = $_;
- $s{"proc"} = $$stats_now{$_}{"proc"};
- $s{"write"} = $$stats_now{$_}{"write"} - $$stats_prev{$_}{"write"};
- $s{"read"} = $$stats_now{$_}{"read"} - $$stats_prev{$_}{"read"};
- push(@stats_diff, \%s);
- }
- return @stats_diff;
- }
- my $first_time = 1;
- my %stats_prev;
- my $time;
- while (1) {
- my %stats = &read_proc;
- &assoc_proc_name(\%stats);
- if (!$first_time) {
- my @stats_diff = &diff_stats(\%stats, \%stats_prev);
- my $elapsed = tv_interval($time);
- my $unit = 1000 * 1000;
- my $now = strftime("%Y/%m/%d %H:%M:%S", localtime);
- @stats_diff = sort {($a->{"write"} + $a->{"read"}) <=> ($b->{"write"} + $b->{"read"})} @stats_diff;
- print "=== [" . $now . "] ===\n";
- foreach (@stats_diff) {
- print $$_{"proc"} . ": (w) " . $$_{"write"} / ($elapsed * $unit) . "[MB/s], (r) " . $$_{"read"} / ($elapsed * $unit) . "[MB/s]\n";
- }
- }
- %stats_prev = %stats;
- $time = [gettimeofday];
- $first_time = 0;
- sleep 1;
- }
Add Comment
Please, Sign In to add comment