This file is indexed.

/usr/bin/plot-llstat is in lustre-utils 1.8.5+dfsg-3ubuntu1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/usr/bin/perl -w
# Report generation for llstat
# ===============================
#        The plot-llstat script is used to generate csv file and
# instructions files for gnuplot from the output of llstat script.
# Since llstat is generic in nature, plot-llstat is also generic
# script.
#
# Assume that:
# operations = { open, close, read_bytes, write_bytes, connect, create, .. etc.}
# parameters = { Rate, Total}
#
#        plot-llstat script creates dat(csv) file using number of operations
# specified by the user. Number of operations equals to number of columns in csv
# file. And values in those columns are equals to the corresponding value of
# the "$param_inx" parameter from the output file.
#        The plot-llstat also creates .scr file that contains instructions
# for gnuplot to plot the graph. After generating .dat and .scr files this
# script invokes gnuplot to display graph.

# Featrues:
# 1. This script is generic in nature, works with any operations names.
# 2. User have option to setect operations of their choice for graph generation.
# 3. This script automatically selects different y axes according to the ranges
#    of values of the parameter.
# 4. One can change parameter to be consider for graphing 
#    by changing value of $param_inx.

# Syntax:
# $ plot-llstat <results_filename> [parameter index (default=2, i.e. Rate)]
# [Note: 1. The output filt given to this script must have been generated 
# 	    with -g option to the llstat script.
#	 2. This script may need modifications whenever there will be 
#           modifications in output format of llstat script.]

# arg 0 is filename 
sub usages_msg(){
	print "$0 parses and graphs the output of llstat using gnuplot,\n";
	print "and generates .dat files for use in spreadsheets.\n";
	print "Usage: $0 <results_filename> [parameter_index]\n";
	print "         where parameter_index is one of:\n";
	print "            1 - Count per interval\n";
	print "            2 - Rate (count per second) (default)\n";
	print "            3 - Total count\n";
	print "ex: # llstat -i2 -g -c lustre-OST0000 > log\n";
	print "    # $0 log 3\n";
        exit 1;
}

my $count = 0; 		# count for number of rows in csv(.dat) file.
my $jumpcolumn = -1;	# Columns to be skiped to get op. name and the "$param_inx" param. 
my @columns;		# Array for Operations names.
my $columnvalues = "";  # Values of the "$param_inx" parameter for all operations.
my @line;		# To store recently read line from log file
my $param_inx = 2;	# Index of the parameter are you interested in graphing.
			# Default is 2 for Rate.
my $GraphTitle;
if ( !$ARGV[0] ) {
	usages_msg(); 	
}

if ( $ARGV[1] ) {
	$param_inx = $ARGV[1]; 	
}

$file = $ARGV[0];

# Open log file for reading
open ( PFILE, "$file") or die "Can't open results log file";
@alllines = <PFILE>;
close PFILE;
LABLE:while ( $count <= $#alllines ) {
	$line = $alllines[$count];
	#print "$line\n";
	chop($line);
	@line = split(/\s+/,$line); # splits line into tokens
	# This comparison may be changed if there will be changes log file.
	if( $line[0] eq "Timestamp" ) { 
	# decide operations position in the logfile depends on num of 
	# parameters(Rate, Total, etc.) present in this line.
		$jumpcolumn = $#line;
		$count = $count + 2; # skip the "---------" line from result file.
		last LABLE;
	}
	if ($line[1] eq "STATS" && $line[2] eq "on") {
                $GraphTitle = $line;
                @GraphTitle = split( /:/, $GraphTitle );
        }
	$count++;
}
if ($jumpcolumn < 0) {
	print "Invalid logfile format\n";
	exit 1;
}
$lastline = $alllines[-1];
@lastline = split(/\s+/,$lastline);
my $allcolumns = "";
$i = 1;
while ($i < $#lastline) {
	# display operations names for user selection.
	print "$lastline[$i] ";
	$allcolumns = "$allcolumns$lastline[$i] "; 
	# capture the "$param_inx" parameter in $columnvalues, 
	# used to define axes ranges depends on values.
	$columnvalues = "$columnvalues$lastline[$i + $param_inx] ";
	$i = $i + $jumpcolumn;
}
print "\nSelect columns(press return to select all): ";
$columns = <STDIN>;
# consider all operations if user hit return.
if ( $columns eq "\n" ) {
	$columns = $allcolumns;
}
chop ($columns);
@columns = split (/\s+/, $columns);
# Open .csv file for writting required columns from log file.
open ( DATAFILE, "> $file.dat" ) or die "Can't open csv file for writting";
print DATAFILE "0 ";
for ($i = 0; $i < $#lastline; $i++) {
	for ($j = 0; $j <= $#columns; $j++) {
		if ($columns[$j] eq $lastline[$i]) {
			print DATAFILE "$columns[$j]$lastline[$i + 4] ";
		}
		
	}
}
print DATAFILE "\n";
my $found = 0;
# depends on $jumpcolumn, capture operation names and value of 
# the "$param_inx" parameter for that perticular operation.
while ( $count <= $#alllines )  {
	$line = $alllines[$count];
	#print "$line\n";
	chop($line);
	@line = split(/\s+/,$line); # splits line into tokens
	# fill the csv(.dat) file with values of operations. 
	print DATAFILE "$line[0]";
	for ($j = 0; $j <= $#columns; $j++) {
		for ($i = 1; $i < $#line ; $i++) {
			if ($columns[$j] eq $line[$i]) {
				# capture the "$param_inx" parameter 
				print DATAFILE " $line[$i + $param_inx]";
				$found = 1;
			}
		}
		if (!$found) {
			print DATAFILE " 0";
		}
		$found = 0;
	}
	print DATAFILE "\n";
	$count = $count + 1;
}
close DATAFILE;

# Open .csv file for reading columns titles.
open ( DATAFILE, "$file.dat" ) or die "Can't open csv file for reading titles\n";
my $titles = <DATAFILE>;
close DATAFILE;
chop($titles);
@titles = split (/\s+/, $titles);
# Open .scr file for writting instructions for gnuplot.
open ( SCRFILE, "> $file.scr" ) or die "Can't open scr file for writting\n";
print SCRFILE "set title \"$GraphTitle[1]\"\n";
print SCRFILE "set xlabel \"time\"\n";
if ($param_inx == 1) {
    print SCRFILE "set ylabel \"units/interval\"\n";
} elsif ($param_inx == 3) {
    print SCRFILE "set ylabel \"units\"\n";
} else {
    print SCRFILE "set ylabel \"units/sec\"\n";
}
my $plot = "plot";
# generate instructions for gnuplot
for ($i = 2; $i <= ($#columns + 2); $i++) {
    print SCRFILE "$plot \"$file.dat\" using 1:$i axes x1y1 title \"$titles[$i - 1]\" with line\n";
    $plot = "replot";
}
print SCRFILE "pause -1\n";
close SCRFILE;
# invoke gnuplot to display graph.
system ("gnuplot $file.scr") == 0 or die "ERROR: while ploting graph.\nMake sure that gnuplot is working properly";