Class: TourWatch

Inherits:
Object
  • Object
show all
Defined in:
lib/tour_watch.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ TourWatch

Returns a new instance of TourWatch.



4
5
6
7
8
9
10
11
12
13
# File 'lib/tour_watch.rb', line 4

def initialize(options={})
  @processes = if options[:processes]
                 options[:processes].split(/,/) * '|'
               else 
                 "ruby|mysql|apache|http|rails|mongrel"
               end
  @cores = options[:cores] || 4
  @logfile = options[:outfile]
  @mac = options[:mac]
end

Instance Attribute Details

#processesObject (readonly)

Returns the value of attribute processes.



2
3
4
# File 'lib/tour_watch.rb', line 2

def processes
  @processes
end

Instance Method Details

#bargraph(value, max = 100, length = 40, on = '#', off = '.') ⇒ Object



79
80
81
# File 'lib/tour_watch.rb', line 79

def bargraph(value, max=100, length=40, on='#', off='.')
  (on * (([[value, 0].max, max].min * length) / max).to_i).ljust(length, off)
end

#fields(parts) ⇒ Object



28
29
30
# File 'lib/tour_watch.rb', line 28

def fields(parts)
  @mac ? fields_mac(parts) : fields_linux(parts)
end

#fields_linux(fields) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/tour_watch.rb', line 49

def fields_linux(fields)
  # linux top isn't much smarter. It spits out a blank field ahead
  # of the pid if the pid is too short, which makes the indexes
  # shift off by one.
  a,b,c = if fields.size == 13
            [-1,1,9]
          else
            [-1,0,8]
          end
  name,pid,cpu = fields[a], fields[b].to_i, fields[c].to_f
end

#fields_mac(fields) ⇒ Object



40
41
42
# File 'lib/tour_watch.rb', line 40

def fields_mac(fields)
  name,pid,cpu = fields[1], fields[0].to_i, fields[2].to_f
end

#log(message) ⇒ Object



83
84
85
86
87
# File 'lib/tour_watch.rb', line 83

def log(message)
  msg = "#{Time.now.strftime('%F %H:%M:%S')} TourWatch: #{message}"
  puts msg
  File.open(@logfile, "a") {|f| f.puts msg } if @logfile
end

#runObject



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/tour_watch.rb', line 62

def run()
  while(true)
    now = Time.now.to_i
    if @time != now
      log '--'
      lines = stats
      lines.sort! {|a,b| a[1]==b[1] ? a[2]<=>b[2] : a[1]<=>b[1] }
      lines.each do |vars|
        vars << bargraph(vars[2], 100 * @cores)
        log "%#{@longest[:name]}s %#{@longest[:pid]}d CPU: %6.2f%% [%-40s]" % vars 
      end
    end
    sleep 0.1
    @time = now
  end
end

#statsObject



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/tour_watch.rb', line 15

def stats
  top = @mac ? top_mac : top_linux
  lines = []
  @longest = Hash.new(0)
  top.each_line do |line|
    name,pid,cpu = fields(line.split(/\s+/))
    lines << [name,pid,cpu]
    @longest[:name] = name.size if name.size > @longest[:name]
    @longest[:pid] = pid.to_s.size if pid.to_s.size > @longest[:pid]
  end
  lines
end

#top_linuxObject



44
45
46
# File 'lib/tour_watch.rb', line 44

def top_linux
  top = `top -bn 1 | grep -E '(#{@processes})'`
end

#top_macObject

Note: MacOSX is so awesome I just cacked. Top will report 0.0% cpu the first time you run top, every time. The only way to get actual CPU% here is to wait for it to send another page and then throw away the first page. Isn’t that just awesome?!? I KNOW!!!



36
37
38
# File 'lib/tour_watch.rb', line 36

def top_mac
  top = `top -l 1 | grep -E '(#{@processes})'`
end