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

use strict;
use warnings;
use Spreadsheet::WriteExcel;

#@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');

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

   my $write_per_second=0;
      my $read=0;
      my $write=0;
      while ($_ =~ /([\d\.]+)\s+[B|K]\/s+\s+([\d\.]+)/sg)
$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 1


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';


@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)

The regexs could be made more robust and written more readable.

  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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.