public
Fork of mojombo/god
Description: Ruby process monitor
Homepage: http://god.rubyforge.org
Clone URL: git://github.com/Bertg/god.git
added more to site docs
mojombo (author)
Sun Jun 17 14:15:26 -0700 2007
commit  aeb2a0e3e7619f89acf087e28be87953e66f2890
tree    982dbbebb417c9118138d04c2cf873b255c1672c
parent  ab2d6d0ac0cf95ef8cae240605710945f0073f0a
...
12
13
14
 
 
15
16
17
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
20
21
...
12
13
14
15
16
17
18
19
 
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
0
@@ -12,10 +12,26 @@ God.meddle do |god|
0
       w.cwd = RAILS_ROOT
0
       w.start = "mongrel_rails cluster::start --only #{port}"
0
       w.stop = "mongrel_rails cluster::stop --only #{port}"
0
+
0
+ pid_file = File.join(RAILS_ROOT, "log/mongrel.#{port}.pid")
0
 
0
       w.start_if do |start|
0
         start.condition(:process_not_running) do |c|
0
- c.pid_file = File.join(RAILS_ROOT, "log/mongrel.#{port}.pid")
0
+ c.pid_file = pid_file
0
+ end
0
+ end
0
+
0
+ w.restart_if do |restart|
0
+ restart.condition(:memory_usage) do |c|
0
+ c.pid_file = pid_file
0
+ c.above = (150 * 1024) # 150mb
0
+ c.times = [3, 5] # 3 out of 5 intervals
0
+ end
0
+
0
+ restart.condition(:cpu_usage) do |c|
0
+ c.pid_file = pid_file
0
+ c.above = 50 # percent
0
+ c.times = 5
0
         end
0
       end
0
     end
...
145
146
147
148
149
150
151
152
 
 
 
 
 
153
154
155
156
157
158
159
...
218
219
220
221
 
 
 
222
223
224
...
232
233
234
 
 
235
236
237
238
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
240
241
242
243
244
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
246
247
...
145
146
147
 
148
149
150
151
152
153
154
155
156
157
158
159
 
160
161
162
...
221
222
223
 
224
225
226
227
228
229
...
237
238
239
240
241
242
243
244
 
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
 
 
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
0
@@ -145,15 +145,18 @@ ul.features li {
0
 
0
 
0
 pre {
0
- font-size: 1.2em;
0
   line-height: 1.5;
0
   border: 1px solid #ccc;
0
   padding: 1em;
0
   background-color: #efefef;
0
+ margin: 1em 0;
0
+}
0
+
0
+code {
0
+ font-size: 1.2em;
0
 }
0
 
0
 .ruby .keywords {
0
- font-weight: bold;
0
   color: blue;
0
 }
0
 
0
@@ -218,7 +221,9 @@ pre {
0
   <h1>Finally, a Config File that Makes Sense</h1>
0
   <p>The easiest way to understand how god will make your life better is by looking at a sample config file. The following configuration file is what I use at <a href="http://site.gravatar.com/">gravatar.com</a> to keep the mongrels running:</p>
0
   
0
-<pre><code class="ruby"># This is the actual config file used to keep the mongrels of
0
+<pre><code class="ruby"># file: gravatar.god
0
+#
0
+# This is the actual config file used to keep the mongrels of
0
 # gravatar.com running.
0
 
0
 RAILS_ROOT = "/var/www/gravatar2/current"
0
@@ -232,16 +237,99 @@ God.meddle do |god|
0
       w.cwd = RAILS_ROOT
0
       w.start = "mongrel_rails cluster::start --only #{port}"
0
       w.stop = "mongrel_rails cluster::stop --only #{port}"
0
+
0
+ pid_file = File.join(RAILS_ROOT, "log/mongrel.#{port}.pid")
0
 
0
       w.start_if do |start|
0
         start.condition(:process_not_running) do |c|
0
- c.pid_file = File.join(RAILS_ROOT, "log/mongrel.#{port}.pid")
0
+ c.pid_file = pid_file
0
+ end
0
+ end
0
+
0
+ w.restart_if do |restart|
0
+ restart.condition(:memory_usage) do |c|
0
+ c.pid_file = pid_file
0
+ c.above = (150 * 1024) # 150mb
0
+ c.times = [3, 5] # 3 out of 5 intervals
0
+ end
0
+
0
+ restart.condition(:cpu_usage) do |c|
0
+ c.pid_file = pid_file
0
+ c.above = 50 # percent
0
+ c.times = 5
0
         end
0
       end
0
     end
0
   end
0
-end
0
-</code></pre>
0
+end</code></pre>
0
+
0
+<p>That's a lot to take in at once, so I'll break it down by section and explain what's going on in each.</p>
0
+
0
+<pre><code class="ruby">RAILS_ROOT = "/var/www/gravatar2/current"</code></pre>
0
+
0
+<p>Here I've set a constant that is used throughout the file. Keeping the <code>RAILS_ROOT</code> value in a constant makes it easy to adapt this script to other applications. Because the config file is Ruby code, I can set whatever variables or constants I want that make the configuration more concise and easier to work with.</p>
0
+
0
+<pre><code class="ruby">God.meddle do |god|
0
+ god.interval = 30 # seconds
0
+
0
+ ...
0
+end</code></pre>
0
+
0
+<p>The meat of the config file is defined inside a <code>God.meddle</code> block. At this level, you set system wide settings like <code>interval</code>. In this case, we've specified that god should do a check every 30 seconds.</p>
0
+
0
+<pre><code class="ruby"> %w{8200 8201 8202}.each do |port|
0
+ ...
0
+ end</code></pre>
0
+
0
+<p>Because the config file is written in actual Ruby code, we can construct loops and do other intelligent things that are impossible in your every day, run of the mill config file. I need to watch three mongrels, so I simply loop over their port numbers, eliminating duplication and making my life a whole lot easier.</p>
0
+
0
+<pre><code class="ruby"> god.watch do |w|
0
+ w.name = "gravatar2-mongrel-#{port}"
0
+ w.cwd = RAILS_ROOT
0
+ w.start = "mongrel_rails cluster::start --only #{port}"
0
+ w.stop = "mongrel_rails cluster::stop --only #{port}"
0
+
0
+ ...
0
+ end</code></pre>
0
+
0
+<p>A <code>watch</code> represents a single process or task that has concrete start, stop, (and possibly restart) operations. You can define as many watches as you like inside the <code>God.meddle</code> block. In the example above, I've got a Rails instance running in a Mongrel that I need to keep alive. Every watch must have a unique <code>name</code> so that it can be identified later on. The optional <code>cwd</code> attribute tells god to switch to that directory before executing any commands. The <code>start</code> and <code>stop</code> attributes specify the commands to start and stop the process. If no <code>restart</code> attribute is set, restart will be represented by a call to stop followed by a call to start.</p>
0
+
0
+<pre><code class="ruby"> pid_file = File.join(RAILS_ROOT, "log/mongrel.#{port}.pid")</code></pre>
0
+
0
+<p>Another variable to hold the location of the PID file.</p>
0
+
0
+<pre><code class="ruby"> w.start_if do |start|
0
+ start.condition(:process_not_running) do |c|
0
+ c.pid_file = pid_file
0
+ end
0
+ end</code></pre>
0
+
0
+<p>Watches contain conditions grouped by the action to execute should they fail. I start with a <code>start_if</code> block that contains a single condition. Conditions are specified by calling <code>condition</code> with an identifier, in this case
0
+<code>:process_not_running</code>. This condition checks to see if the process corresponding to the PID found in the <code>pid_file</code> is currently running. If it's not, the condition will fail causing a start command to be issued. The <code>process_not_running</code> condition will take care of cleaning up orphaned PID files by default, so we don't have to worry about it. We could turn that behavior off by adding <code>c.clean = false</code>.
0
+
0
+<pre><code class="ruby"> w.restart_if do |restart|
0
+ restart.condition(:memory_usage) do |c|
0
+ c.pid_file = pid_file
0
+ c.above = (150 * 1024) # 150mb
0
+ c.times = [3, 5] # 3 out of 5 intervals
0
+ end
0
+
0
+ ...
0
+ end</code></pre>
0
+
0
+<p>Similar to <code>start_if</code> there is a <code>restart_if</code> command that groups conditions that should trigger a restart. The <code>memory_usage</code> condition will fail if the specified process is using too much memory. Once again, the <code>pid_file</code> must be set. The maximum allowable amount of memory is specified with the <code>above</code> attribute in units of kilobytes. The number of times the test needs to fail in order to trigger a restart is set with <code>times</code>. This can be either an integer or an array. An integer means it must fail that many times in a row while an array [x, y] means it must fail x times out of the last y tests.</p>
0
+
0
+<pre><code class="ruby"> w.restart_if do |restart|
0
+ ...
0
+
0
+ restart.condition(:cpu_usage) do |c|
0
+ c.pid_file = pid_file
0
+ c.above = 50 # percent
0
+ c.times = 5
0
+ end
0
+ end</code></pre>
0
+
0
+<p></p>
0
 
0
 </div>
0
 <div id="footer">
...
20
21
22
 
23
24
25
...
20
21
22
23
24
25
26
0
@@ -20,6 +20,7 @@ class TestWatch < Test::Unit::TestCase
0
       @watch.start = 'start'
0
       @watch.stop = 'stop'
0
       @watch.restart = 'restart'
0
+ @watch.grace = 5
0
     end
0
   end
0
   

Comments

    No one has commented yet.