Skip to content

Instantly share code, notes, and snippets.

@masuidrive
Created December 25, 2015 17:39
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 masuidrive/f7fcbf1fd4d78674f175 to your computer and use it in GitHub Desktop.
Save masuidrive/f7fcbf1fd4d78674f175 to your computer and use it in GitHub Desktop.
ざっくりとしたメモリとCPU利用率を調べるプロファイラ
#!/usr/bin/env ruby
# ざっくりとしたメモリとCPU利用率を調べるプロファイラ
# ./profiler.rb "HOGE -foo" を実行するとHOGEコマンドを実行して
# メモリとCPUの利用率をSTDOUTに書き出します
# -p PIDを指定すると、指定したコマンドと同時に指定されたプロセスも
# 記録します
require "csv"
require "optparse"
out = STDOUT
interval = 1.0
pids = []
opt = OptionParser.new
opt.on("-p PID"){|v| pids << v.to_i}
argv = opt.parse!(ARGV)
# get process information
def proc_info(pid)
s = open("/proc/#{pid}/stat").gets.split(/\s/)
{
cmd: s[1],
utime: s[13].to_i,
stime: s[14].to_i,
mem: s[22].to_i
}
end
# get cpu time
def cpu_time
open("/proc/stat").readlines.grep(/^cpu\s/).first
.split(/\s/).map(&:to_i).inject(:+)
end
main_pid = Process.spawn(argv.join(" "))
time_total_before = cpu_time
procs = {}
([main_pid] + (pids || [])).each do |pid|
procs[pid] = proc_info(pid)
end
time = Time.now.to_i
while Process.waitpid(main_pid, Process::WNOHANG).nil?
sleep interval
procs.each do |pid, proc_before|
t = Time.now.to_i - time
proc_after = proc_info(pid)
time_total_after = cpu_time
time_total = time_total_after - time_total_before
ucpu = 100.0 * (proc_after[:utime] - proc_before[:utime]) / time_total
scpu = 100.0 * (proc_after[:stime] - proc_before[:stime]) / time_total
out.puts CSV.generate_line([
t,
pid,
proc_after[:cmd],
ucpu,
scpu,
proc_after[:mem]
])
procs[pid] = proc_after
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment