1 #!/usr/bin/env ruby
2
3 ##
4 # A small application to change the title of an xterm to a meter with the
5 # current CPU usage (works only on Linux with a properly configured
6 # /proc)
7 #
8
9 ##
10 # Get the cpu info for the cpu with the given name. "cpu" is for all
11 # cpus, or cpu0 for the first cpu, etc. Returns:
12 # [ name, total_user, total_nice, total_system, total_idle ]
13 def get_cpuinfo(name = "cpu")
14 stats = File.readlines('/proc/stat')
15 begin
16 cpustat = stats[0].split(/\s+/)
17 end while cpustat[0] != name
18 return [ cpustat[0], *(cpustat[1..-1].map { |x| x.to_i }) ]
19 end
20
21 ##
22 # Given two return value from get_cpuinfo, return the difference between
23 # them. Returns:
24 # [ diff_user, diff_nice, diff_system, diff_idle ]
25 def cpudiff(oldcpuinfo, cpuinfo)
26 diff = []
27 (1..4).each do |idx|
28 diff.push(cpuinfo[idx] - oldcpuinfo[idx])
29 end
30 return diff
31 end
32
33 ##
34 # Run a loop that yields the difference in cpu usage since the last
35 # yield every interval seconds.
36 def cpu_stat_loop(name = "cpu", interval = 1)
37 oldcpuinfo = get_cpuinfo(name)
38 loop do
39 sleep interval
40 cpuinfo = get_cpuinfo(name)
41 diff = cpudiff(oldcpuinfo, cpuinfo)
42 yield diff
43 oldcpuinfo = cpuinfo
44 end
45 end
46
47 ##
48 # Return a string holding an ascii representation of a meter.
49 def ascii_meter(percent, total_bar_size)
50 bar_size = (total_bar_size * percent)
51 not_bar_size = (total_bar_size - bar_size)
52 return ('I' * bar_size) + (':' * (not_bar_size))
53 end
54
55 ##
56 # Set the title of an xterm.
57 def set_xterm_title(x)
58 $stdout.print "\033]0;#{x}\007"
59 $stdout.flush
60 end
61
62 # Main
63 TOTAL_BAR_SIZE = 20
64 cpu_stat_loop do |diff|
65 total = (diff[0] + diff[1] + diff[2] + diff[3])
66 idle_percent = diff[3].to_f / total
67 set_xterm_title(
68 ascii_meter(1.0 - idle_percent, TOTAL_BAR_SIZE) +
69 ' ' +
70 ("%2.1f" % (100.0 * (1.0 - idle_percent))))
71 end