additional condition rdoc
[god.git] / lib / god / conditions / memory_usage.rb
blob4facc750458c461e86835b6ecba90dd65962c1ff
1 module God
2   module Conditions
3     
4     # Condition Symbol :memory_usage
5     # Type: Poll
6     # 
7     # Trigger when the resident memory of a process is above a specified limit.
8     #
9     # Paramaters
10     #   Required
11     #     +pid_file+ is the pid file of the process in question. Automatically
12     #                populated for Watches.
13     #     +above+ is the amount of resident memory (in kilobytes) above which
14     #             the condition should trigger. You can also use the sugar
15     #             methods #kilobytes, #megabytes, and #gigabytes to clarify
16     #             this amount (see examples).
17     #
18     # Examples
19     #
20     # Trigger if the process is using more than 100 megabytes of resident
21     # memory (from a Watch):
22     #
23     #   on.condition(:memory_usage) do |c|
24     #     c.above = 100.megabytes
25     #   end
26     #
27     # Non-Watch Tasks must specify a PID file:
28     #
29     #   on.condition(:memory_usage) do |c|
30     #     c.above = 100.megabytes
31     #     c.pid_file = "/var/run/mongrel.3000.pid"
32     #   end
33     class MemoryUsage < PollCondition
34       attr_accessor :above, :times
35       
36       def initialize
37         super
38         self.above = nil
39         self.times = [1, 1]
40       end
41       
42       def prepare
43         if self.times.kind_of?(Integer)
44           self.times = [self.times, self.times]
45         end
46         
47         @timeline = Timeline.new(self.times[1])
48       end
49       
50       def reset
51         @timeline.clear
52       end
53       
54       def valid?
55         valid = true
56         valid &= complain("Attribute 'pid_file' must be specified", self) if self.watch.pid_file.nil?
57         valid &= complain("Attribute 'above' must be specified", self) if self.above.nil?
58         valid
59       end
60       
61       def test
62         return false unless File.exist?(self.watch.pid_file)
63         
64         pid = File.read(self.watch.pid_file).strip
65         process = System::Process.new(pid)
66         @timeline.push(process.memory)
67         
68         history = "[" + @timeline.map { |x| "#{x > self.above ? '*' : ''}#{x}kb" }.join(", ") + "]"
69         
70         if @timeline.select { |x| x > self.above }.size >= self.times.first
71           self.info = "memory out of bounds #{history}"
72           return true
73         else
74           self.info = "memory within bounds #{history}"
75           return false
76         end
77       end
78     end
79     
80   end
81 end