Check the hardrive performance of the particular process using a Perl script

I have written the following Perl script to monitor the hardrive performance of the particular process (say, for example, Chrome).

use strict;
use warnings;

#@usage example perl script.pl 5 5 if($#ARGV!=1); my$login = (getpwuid $>); die "must run as root" if$login ne 'root';

my $workbook = Spreadsheet::WriteExcel->new("Performance_report.xls"); my$disk=$workbook->add_worksheet('disk');$disk->write(0,0,"Time_interval",0);
$disk->write(0,1,"read/s",0);$disk->write(0,2,"write/s",0);

#stores the time interval
my $time_interval=$ARGV[0];
#stores the no of iteration
my $test_count=$ARGV[1];
my $iter=0; while($iter<$test_count) { my @processes; @processes=iotop -b -n 1 |grep chrome; my$read_per_second=0;

my $write_per_second=0; foreach(@processes) { my$read=0;
my $write=0; while ($_ =~ /([\d\.]+)\s+[B|K]\/s+\s+([\d\.]+)/sg)
{
$read_per_second+=$1;
$write_per_second+=$2;
}
}
$disk->write($iter+1,0,$time_interval*($iter+1));
$disk->write($iter+1,1,$read_per_second);$disk->write($iter+1,2,$write_per_second);
sleep($time_interval);$iter++;
}
$workbook->close() or die "Cannot close the worksheet";  I have used the iotop tool in this script to monitor the disk performance. sudo iotop -b -n 1 | grep chrome gives the following output: 3687 be/4 venkat 0.00 B/s 0.00 B/s 0.00 % 0.00 % chrome --type=zygote 4284 be/4 venkat 0.00 B/s 0.00 B/s 0.00 % 0.00 % chrome 3693 be/4 venkat 0.00 B/s 0.00 B/s 0.00 % 0.00 % chrome --type=zygote 3695 be/4 venkat 0.00 B/s 0.00 B/s 0.00 % 0.00 % chrome 3728 be/4 venkat 0.00 B/s 0.00 B/s 0.00 % 0.00 % chrome 5468 be/4 venkat 0.00 B/s 0.00 B/s 0.00 % 0.00 % chrome  I store the output to the array, process every value of the array, extract the second and third column value, recursively add the values of every thread of Chrome and store the final sum in the Excel sheet for every iteration. Is there any better way to do this using a Perl script? 1 Answer in general this script seems to be straight forward. But here are some suggestions for improvements: First check for needed command line arguments and die early with a usage message if they are missing/incomplete. Alternatively you could supply defaults for time interval and iterations like this #stores the time interval my$time_interval=$ARGV[0] || 10; #stores the no of iteration my$test_count=$ARGV[1] || 50;  You also might want to remove the hard coded process name (chrome) and use a third command line parameter #stores the process name my$processname=$ARGV[2] || 'chrome';  and @processes=iotop -b -n 1 |grep$processname;


The result of calls to the write method of Spreadsheet::WriteExcel should be checked for success (=0) and failures should be shown somewhere (either on the console and/or in some log file).

The processing of iotop output could be enhanced.

1. Variables $read and $write are not needed.

2. Each line needs to be matched only once (while -> if and no need for matching modifier g)

1. I defined the regex for the throughput part once in a variable ($throughputpattern) and used it twice afterwards in the match. This is a general principle (don't repeat yourself) for better maintainablility. 2. the regex now uses the x modifier which allows whitespace in the pattern for better spacing and readability (but then you need to express whitespace to be matched explicitly with \s). 3. I changed the accepted units of B and K to any capital letter. Who knows what throughput might be possible?  my$throughputpattern = qr{\b (\d+\.\d+) \s+ [A-Z]/s \s+}x;
if ($_ =~ /$throughputpattern $throughputpattern/x) {$read_per_second+=$1;$write_per_second+=\$2;