Skip to content

Instantly share code, notes, and snippets.

@justinstoller
Created March 18, 2019 21:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justinstoller/fe6d338b8bfdfb4d1caad4ef4c5adc42 to your computer and use it in GitHub Desktop.
Save justinstoller/fe6d338b8bfdfb4d1caad4ef4c5adc42 to your computer and use it in GitHub Desktop.
require 'date'
require 'pp'
pid = /^(\d+)\s*/
time = /\s*(\d{2}:\d{2}:\d{2}\.\d+)\s*/
scall = /\s*(\w+)\(/
rescall = /<\.\.\. (\w+) resumed/
status = /\s=\s(-?\d+)/
dur = /\s*<(\d+\.\d+)>/
fin_line = /#{pid}#{time}#{scall}.*#{status}.*#{dur}$/
refin_line = /#{pid}#{time}#{rescall}.*#{status}.*#{dur}$/
unfin_line = /#{pid}#{time}#{scall}.*/
sig_line = /#{pid}#{time}.*(SIG\w+).*/
results = {'totals' => {}}
per_pid = {}
file = ARGV[0]
lines = File.read(file).lines.lazy
lines.each do |line|
next if line =~ /detached/
if line =~ /unfinished/
match = line.match(unfin_line)
_, pids, times, scalls = match.to_a
puts "scalls" + line if ! scalls
results[scalls] ||= {}
results[scalls]['interrupts'] ||= 0
results[scalls]['interrupts'] += 1
elsif line =~ /signo=SIG/
match = line.match(sig_line)
_, pids, times, scalls = match.to_a
puts 'sigs' + line if ! scalls
results[scalls] ||= {}
results[scalls]['count'] ||= 0
results[scalls]['count'] += 1
elsif line =~ /exit\(|exited with/
next
else
rezmatch = line.match(refin_line)
if rezmatch
match = rezmatch
else
match = line.match(fin_line)
end
_, pids, times, scalls, statuss, durs = match.to_a
puts 'else' + line if ! scalls
results[scalls] ||= {}
results[scalls]['count'] ||= 0
results[scalls]['count'] += 1
results['totals']['count'] ||= 0
results['totals']['count'] += 1
if statuss && statuss.to_i < 0
results[scalls]['errors'] ||= 0
results[scalls]['errors'] += 1
results['totals']['errors'] ||= 0
results['totals']['errors'] += 1
end
results[scalls]['durations'] ||= []
results[scalls]['durations'] << durs.to_f
results[scalls]['duration'] ||= 0.0
results[scalls]['duration'] += durs.to_f
results['totals']['duration'] ||= 0.0
results['totals']['duration'] += durs.to_f
end
end
total_count = results['totals']['count']
total_dur = results['totals']['duration']
total_errors = results['totals']['errors']
csv = sprintf("%12s %12s %10s %12s %12s %10s %10s %10s %10s %10s %10s %10s %12s %s\n",
"% time", "seconds", "median", "avg call(s)", "avg", "min", "max", "% calls", "calls", "call err %", "errors", "interrupts", "int/call", "syscall")
results.each_pair do |scalld, data|
if scalld =~ /SIG/
str = sprintf("%12s %12s %10s %12s %12s %10s %10s %10s %10.6f %10d %10s %10s %10s %12s %s\n",
"n/a", "n/a", "n/a", "n/a", "n/a", "n/a", "n/a", "n/a",
((data['count'].to_f / total_count.to_f) * 100),
data['count'],
"n/a", "n/a", "n/a", "n/a",
scalld)
else
if data['durations']
sorted = data['durations'].sort
min = sorted[0]
max = sorted[-1]
median = sorted[sorted.length / 2]
avg = sorted.reduce(:+) / sorted.length.to_f
avg1 = data['duration'] / data['count']
else
min = max = median = avg = avg1 = 0
end
str = sprintf("%12.6f %12.6f %10.6f %12.6f %12.6f %10.6f %10.6f %10.6f %10d %10.6f %10d %10d %12.6f %s\n",
((data['duration'] / total_dur) * 100),
data['duration'].to_f,
median,
avg1,
avg,
min,
max,
((data['count'].to_f / total_count.to_f) * 100),
data['count'].to_i,
(data['errors'].to_f / data['count'].to_f),
data['errors'].to_i,
data['interrupts'].to_i,
(data['interrupts'].to_f / data['count'].to_f),
scalld)
end
csv << str
end
puts csv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment