Edit File by line
/home/barbar84/www/wp-conte.../plugins/sujqvwi/ShExBy/shex_roo.../bin
File: fiologparser.py
#! /usr/libexec/platform-python
[0] Fix | Delete
# Note: this script is python2 and python 3 compatible.
[1] Fix | Delete
#
[2] Fix | Delete
# fiologparser.py
[3] Fix | Delete
#
[4] Fix | Delete
# This tool lets you parse multiple fio log files and look at interaval
[5] Fix | Delete
# statistics even when samples are non-uniform. For instance:
[6] Fix | Delete
#
[7] Fix | Delete
# fiologparser.py -s *bw*
[8] Fix | Delete
#
[9] Fix | Delete
# to see per-interval sums for all bandwidth logs or:
[10] Fix | Delete
#
[11] Fix | Delete
# fiologparser.py -a *clat*
[12] Fix | Delete
#
[13] Fix | Delete
# to see per-interval average completion latency.
[14] Fix | Delete
[15] Fix | Delete
from __future__ import absolute_import
[16] Fix | Delete
from __future__ import print_function
[17] Fix | Delete
import argparse
[18] Fix | Delete
import math
[19] Fix | Delete
[20] Fix | Delete
def parse_args():
[21] Fix | Delete
parser = argparse.ArgumentParser()
[22] Fix | Delete
parser.add_argument('-i', '--interval', required=False, type=int, default=1000, help='interval of time in seconds.')
[23] Fix | Delete
parser.add_argument('-d', '--divisor', required=False, type=int, default=1, help='divide the results by this value.')
[24] Fix | Delete
parser.add_argument('-f', '--full', dest='full', action='store_true', default=False, help='print full output.')
[25] Fix | Delete
parser.add_argument('-A', '--all', dest='allstats', action='store_true', default=False,
[26] Fix | Delete
help='print all stats for each interval.')
[27] Fix | Delete
parser.add_argument('-a', '--average', dest='average', action='store_true', default=False, help='print the average for each interval.')
[28] Fix | Delete
parser.add_argument('-s', '--sum', dest='sum', action='store_true', default=False, help='print the sum for each interval.')
[29] Fix | Delete
parser.add_argument("FILE", help="collectl log output files to parse", nargs="+")
[30] Fix | Delete
args = parser.parse_args()
[31] Fix | Delete
[32] Fix | Delete
return args
[33] Fix | Delete
[34] Fix | Delete
def get_ftime(series):
[35] Fix | Delete
ftime = 0
[36] Fix | Delete
for ts in series:
[37] Fix | Delete
if ftime == 0 or ts.last.end < ftime:
[38] Fix | Delete
ftime = ts.last.end
[39] Fix | Delete
return ftime
[40] Fix | Delete
[41] Fix | Delete
def print_full(ctx, series):
[42] Fix | Delete
ftime = get_ftime(series)
[43] Fix | Delete
start = 0
[44] Fix | Delete
end = ctx.interval
[45] Fix | Delete
[46] Fix | Delete
while (start < ftime):
[47] Fix | Delete
end = ftime if ftime < end else end
[48] Fix | Delete
results = [ts.get_value(start, end) for ts in series]
[49] Fix | Delete
print("%s, %s" % (end, ', '.join(["%0.3f" % i for i in results])))
[50] Fix | Delete
start += ctx.interval
[51] Fix | Delete
end += ctx.interval
[52] Fix | Delete
[53] Fix | Delete
def print_sums(ctx, series):
[54] Fix | Delete
ftime = get_ftime(series)
[55] Fix | Delete
start = 0
[56] Fix | Delete
end = ctx.interval
[57] Fix | Delete
[58] Fix | Delete
while (start < ftime):
[59] Fix | Delete
end = ftime if ftime < end else end
[60] Fix | Delete
results = [ts.get_value(start, end) for ts in series]
[61] Fix | Delete
print("%s, %0.3f" % (end, sum(results)))
[62] Fix | Delete
start += ctx.interval
[63] Fix | Delete
end += ctx.interval
[64] Fix | Delete
[65] Fix | Delete
def print_averages(ctx, series):
[66] Fix | Delete
ftime = get_ftime(series)
[67] Fix | Delete
start = 0
[68] Fix | Delete
end = ctx.interval
[69] Fix | Delete
[70] Fix | Delete
while (start < ftime):
[71] Fix | Delete
end = ftime if ftime < end else end
[72] Fix | Delete
results = [ts.get_value(start, end) for ts in series]
[73] Fix | Delete
print("%s, %0.3f" % (end, float(sum(results))/len(results)))
[74] Fix | Delete
start += ctx.interval
[75] Fix | Delete
end += ctx.interval
[76] Fix | Delete
[77] Fix | Delete
# FIXME: this routine is computationally inefficient
[78] Fix | Delete
# and has O(N^2) behavior
[79] Fix | Delete
# it would be better to make one pass through samples
[80] Fix | Delete
# to segment them into a series of time intervals, and
[81] Fix | Delete
# then compute stats on each time interval instead.
[82] Fix | Delete
# to debug this routine, use
[83] Fix | Delete
# # sort -n -t ',' -k 2 small.log
[84] Fix | Delete
# on your input.
[85] Fix | Delete
[86] Fix | Delete
def my_extend( vlist, val ):
[87] Fix | Delete
vlist.extend(val)
[88] Fix | Delete
return vlist
[89] Fix | Delete
[90] Fix | Delete
array_collapser = lambda vlist, val: my_extend(vlist, val)
[91] Fix | Delete
[92] Fix | Delete
def print_all_stats(ctx, series):
[93] Fix | Delete
ftime = get_ftime(series)
[94] Fix | Delete
start = 0
[95] Fix | Delete
end = ctx.interval
[96] Fix | Delete
print('start-time, samples, min, avg, median, 90%, 95%, 99%, max')
[97] Fix | Delete
while (start < ftime): # for each time interval
[98] Fix | Delete
end = ftime if ftime < end else end
[99] Fix | Delete
sample_arrays = [ s.get_samples(start, end) for s in series ]
[100] Fix | Delete
samplevalue_arrays = []
[101] Fix | Delete
for sample_array in sample_arrays:
[102] Fix | Delete
samplevalue_arrays.append(
[103] Fix | Delete
[ sample.value for sample in sample_array ] )
[104] Fix | Delete
# collapse list of lists of sample values into list of sample values
[105] Fix | Delete
samplevalues = reduce( array_collapser, samplevalue_arrays, [] )
[106] Fix | Delete
# compute all stats and print them
[107] Fix | Delete
mymin = min(samplevalues)
[108] Fix | Delete
myavg = sum(samplevalues) / float(len(samplevalues))
[109] Fix | Delete
mymedian = median(samplevalues)
[110] Fix | Delete
my90th = percentile(samplevalues, 0.90)
[111] Fix | Delete
my95th = percentile(samplevalues, 0.95)
[112] Fix | Delete
my99th = percentile(samplevalues, 0.99)
[113] Fix | Delete
mymax = max(samplevalues)
[114] Fix | Delete
print( '%f, %d, %f, %f, %f, %f, %f, %f, %f' % (
[115] Fix | Delete
start, len(samplevalues),
[116] Fix | Delete
mymin, myavg, mymedian, my90th, my95th, my99th, mymax))
[117] Fix | Delete
[118] Fix | Delete
# advance to next interval
[119] Fix | Delete
start += ctx.interval
[120] Fix | Delete
end += ctx.interval
[121] Fix | Delete
[122] Fix | Delete
def median(values):
[123] Fix | Delete
s=sorted(values)
[124] Fix | Delete
return float(s[(len(s)-1)/2]+s[(len(s)/2)])/2
[125] Fix | Delete
[126] Fix | Delete
def percentile(values, p):
[127] Fix | Delete
s = sorted(values)
[128] Fix | Delete
k = (len(s)-1) * p
[129] Fix | Delete
f = math.floor(k)
[130] Fix | Delete
c = math.ceil(k)
[131] Fix | Delete
if f == c:
[132] Fix | Delete
return s[int(k)]
[133] Fix | Delete
return (s[int(f)] * (c-k)) + (s[int(c)] * (k-f))
[134] Fix | Delete
[135] Fix | Delete
def print_default(ctx, series):
[136] Fix | Delete
ftime = get_ftime(series)
[137] Fix | Delete
start = 0
[138] Fix | Delete
end = ctx.interval
[139] Fix | Delete
averages = []
[140] Fix | Delete
weights = []
[141] Fix | Delete
[142] Fix | Delete
while (start < ftime):
[143] Fix | Delete
end = ftime if ftime < end else end
[144] Fix | Delete
results = [ts.get_value(start, end) for ts in series]
[145] Fix | Delete
averages.append(sum(results))
[146] Fix | Delete
weights.append(end-start)
[147] Fix | Delete
start += ctx.interval
[148] Fix | Delete
end += ctx.interval
[149] Fix | Delete
[150] Fix | Delete
total = 0
[151] Fix | Delete
for i in range(0, len(averages)):
[152] Fix | Delete
total += averages[i]*weights[i]
[153] Fix | Delete
print('%0.3f' % (total/sum(weights)))
[154] Fix | Delete
[155] Fix | Delete
class TimeSeries(object):
[156] Fix | Delete
def __init__(self, ctx, fn):
[157] Fix | Delete
self.ctx = ctx
[158] Fix | Delete
self.last = None
[159] Fix | Delete
self.samples = []
[160] Fix | Delete
self.read_data(fn)
[161] Fix | Delete
[162] Fix | Delete
def read_data(self, fn):
[163] Fix | Delete
f = open(fn, 'r')
[164] Fix | Delete
p_time = 0
[165] Fix | Delete
for line in f:
[166] Fix | Delete
(time, value, foo, bar) = line.rstrip('\r\n').rsplit(', ')
[167] Fix | Delete
self.add_sample(p_time, int(time), int(value))
[168] Fix | Delete
p_time = int(time)
[169] Fix | Delete
[170] Fix | Delete
def add_sample(self, start, end, value):
[171] Fix | Delete
sample = Sample(ctx, start, end, value)
[172] Fix | Delete
if not self.last or self.last.end < end:
[173] Fix | Delete
self.last = sample
[174] Fix | Delete
self.samples.append(sample)
[175] Fix | Delete
[176] Fix | Delete
def get_samples(self, start, end):
[177] Fix | Delete
sample_list = []
[178] Fix | Delete
for s in self.samples:
[179] Fix | Delete
if s.start >= start and s.end <= end:
[180] Fix | Delete
sample_list.append(s)
[181] Fix | Delete
return sample_list
[182] Fix | Delete
[183] Fix | Delete
def get_value(self, start, end):
[184] Fix | Delete
value = 0
[185] Fix | Delete
for sample in self.samples:
[186] Fix | Delete
value += sample.get_contribution(start, end)
[187] Fix | Delete
return value
[188] Fix | Delete
[189] Fix | Delete
class Sample(object):
[190] Fix | Delete
def __init__(self, ctx, start, end, value):
[191] Fix | Delete
self.ctx = ctx
[192] Fix | Delete
self.start = start
[193] Fix | Delete
self.end = end
[194] Fix | Delete
self.value = value
[195] Fix | Delete
[196] Fix | Delete
def get_contribution(self, start, end):
[197] Fix | Delete
# short circuit if not within the bound
[198] Fix | Delete
if (end < self.start or start > self.end):
[199] Fix | Delete
return 0
[200] Fix | Delete
[201] Fix | Delete
sbound = self.start if start < self.start else start
[202] Fix | Delete
ebound = self.end if end > self.end else end
[203] Fix | Delete
ratio = float(ebound-sbound) / (end-start)
[204] Fix | Delete
return self.value*ratio/ctx.divisor
[205] Fix | Delete
[206] Fix | Delete
[207] Fix | Delete
if __name__ == '__main__':
[208] Fix | Delete
ctx = parse_args()
[209] Fix | Delete
series = []
[210] Fix | Delete
for fn in ctx.FILE:
[211] Fix | Delete
series.append(TimeSeries(ctx, fn))
[212] Fix | Delete
if ctx.sum:
[213] Fix | Delete
print_sums(ctx, series)
[214] Fix | Delete
elif ctx.average:
[215] Fix | Delete
print_averages(ctx, series)
[216] Fix | Delete
elif ctx.full:
[217] Fix | Delete
print_full(ctx, series)
[218] Fix | Delete
elif ctx.allstats:
[219] Fix | Delete
print_all_stats(ctx, series)
[220] Fix | Delete
else:
[221] Fix | Delete
print_default(ctx, series)
[222] Fix | Delete
[223] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function