bluepill-rwgps 0.0.60
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +1 -0
- data/DESIGN.md +10 -0
- data/Gemfile +10 -0
- data/LICENSE +22 -0
- data/README.md +10 -0
- data/Rakefile +38 -0
- data/bin/bluepill +124 -0
- data/bin/bpsv +3 -0
- data/bin/sample_forking_server +53 -0
- data/bluepill-rwgps.gemspec +36 -0
- data/examples/example.rb +87 -0
- data/examples/new_example.rb +89 -0
- data/examples/new_runit_example.rb +29 -0
- data/examples/runit_example.rb +26 -0
- data/lib/bluepill/application/client.rb +8 -0
- data/lib/bluepill/application/server.rb +23 -0
- data/lib/bluepill/application.rb +205 -0
- data/lib/bluepill/condition_watch.rb +50 -0
- data/lib/bluepill/controller.rb +121 -0
- data/lib/bluepill/dsl/app_proxy.rb +25 -0
- data/lib/bluepill/dsl/process_factory.rb +122 -0
- data/lib/bluepill/dsl/process_proxy.rb +44 -0
- data/lib/bluepill/dsl.rb +12 -0
- data/lib/bluepill/group.rb +72 -0
- data/lib/bluepill/logger.rb +63 -0
- data/lib/bluepill/process.rb +490 -0
- data/lib/bluepill/process_conditions/always_true.rb +18 -0
- data/lib/bluepill/process_conditions/cpu_usage.rb +19 -0
- data/lib/bluepill/process_conditions/http.rb +58 -0
- data/lib/bluepill/process_conditions/mem_usage.rb +32 -0
- data/lib/bluepill/process_conditions/process_condition.rb +22 -0
- data/lib/bluepill/process_conditions.rb +14 -0
- data/lib/bluepill/process_statistics.rb +27 -0
- data/lib/bluepill/socket.rb +58 -0
- data/lib/bluepill/system.rb +238 -0
- data/lib/bluepill/trigger.rb +60 -0
- data/lib/bluepill/triggers/flapping.rb +56 -0
- data/lib/bluepill/util/rotational_array.rb +20 -0
- data/lib/bluepill/version.rb +4 -0
- data/lib/bluepill.rb +38 -0
- data/local-bluepill +129 -0
- data/spec/lib/bluepill/logger_spec.rb +3 -0
- data/spec/lib/bluepill/process_statistics_spec.rb +24 -0
- data/spec/lib/bluepill/system_spec.rb +36 -0
- data/spec/spec_helper.rb +19 -0
- metadata +264 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f840cc1cfefa5505c537c74c2b9c59f70e21c921
|
4
|
+
data.tar.gz: 554d5ade831b219c802cba6a45a86e129ac4d48f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 81538721c42b6382f14faff4bc0f7f5f560c627719d081fc844b825cb495ad26d8004c5584df4d6d0f0d49a0e8b6e126b891d3d9809f32c95ea5205d5e11d21b
|
7
|
+
data.tar.gz: c98a5a3a2309efddd2567550786f4b84002e34d86ae2c17aadf984d88ee3a9711859e2933853c72a0e190dd8251ab8a6e67126b531480b0f702d0e8d3339fc52
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
-r ./spec/spec_helper.rb -c -f progress
|
data/DESIGN.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
## Bluepill Design
|
2
|
+
Here are just some bullet points of the design. We'll add details later.
|
3
|
+
|
4
|
+
* Each process monitors a single _application_, so you can have multiple bluepill processes on a system
|
5
|
+
* Use rotational arrays for storing historical data for monitoring process conditions
|
6
|
+
* Memo-ize output of _ps_ per tick as an optimization for applications with many processes
|
7
|
+
* Use socket files to communicate between CLI and daemon
|
8
|
+
* DSL is a separate layer, the core of the monitoring just uses regular initializers, etc. DSL is simply for ease of use and should not interfere with business logic
|
9
|
+
* Sequentially process user issued commands so no weird race cases occur
|
10
|
+
* Triggers are notified by the state machine on any process state transitions
|
data/Gemfile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in bluepill.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
# YARD helper for ruby 1.8 (already embedded into ruby 1.9)
|
7
|
+
gem "ripper", :platforms => :ruby_18, :group => :development
|
8
|
+
|
9
|
+
# Code coverage tool that works on Ruby 1.9
|
10
|
+
gem "simplecov", ">= 0.4.0", :platforms => :ruby_19, :group => :test
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2009 Arya Asemanfar, Rohith Ravi, Gary Tsang
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Why this fork?
|
2
|
+
Bluepill worked well for us on http://ridewithgps.com up through version 0.0.60, after which they introduced the process journal. The Process journal is a flawed idea - persist to disk a journal of all PIDs underneath a watched process in bluepill. Due to a variety of bugs, PIDs end up in the journal (sometimes growing uncontrollably, filling log files with gigs of data) well after the original process has exited. Given that PIDs are not unique and are in fact regularly reused, and that Bluepill kills all processes with PIDs in the journal file when it is restarted, terrible bugs ensue. If not running privileged, bluepill dies. If running privileged, other unintended processes die.
|
3
|
+
|
4
|
+
This fork will likely not be maintained, aside from ensuring it works with updated ruby versions.
|
5
|
+
|
6
|
+
|
7
|
+
# Bluepill
|
8
|
+
Bluepill is a simple process monitoring tool written in Ruby.
|
9
|
+
|
10
|
+
Check out the original Bluepill repo for information about the tool: http://github.com/bluepill-rb/bluepill
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'bundler'
|
5
|
+
Bundler::GemHelper.install_tasks
|
6
|
+
rescue LoadError
|
7
|
+
$stderr.puts "Bundler not installed. You should install it with: gem install bundler"
|
8
|
+
end
|
9
|
+
|
10
|
+
$LOAD_PATH << File.expand_path('./lib', File.dirname(__FILE__))
|
11
|
+
require 'bluepill/version'
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'rspec/core/rake_task'
|
15
|
+
|
16
|
+
RSpec::Core::RakeTask.new
|
17
|
+
|
18
|
+
if RUBY_VERSION >= '1.9'
|
19
|
+
RSpec::Core::RakeTask.new(:cov) do |t|
|
20
|
+
ENV['ENABLE_SIMPLECOV'] = '1'
|
21
|
+
t.ruby_opts = '-w'
|
22
|
+
t.rcov_opts = %q[-Ilib --exclude "spec/*,gems/*"]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
rescue LoadError
|
26
|
+
$stderr.puts "RSpec not available. Install it with: gem install rspec-core rspec-expectations rr faker"
|
27
|
+
end
|
28
|
+
|
29
|
+
begin
|
30
|
+
require 'yard'
|
31
|
+
YARD::Rake::YardocTask.new do |yard|
|
32
|
+
yard.options << "--title='bluepill #{Bluepill::VERSION}'"
|
33
|
+
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
$stderr.puts "Please install YARD with: gem install yard"
|
37
|
+
end
|
38
|
+
|
data/bin/bluepill
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
require 'bluepill'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'rbconfig'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
9
|
+
|
10
|
+
RbConfig = Config unless Object.const_defined?(:RbConfig)
|
11
|
+
|
12
|
+
# Default options
|
13
|
+
options = {
|
14
|
+
:log_file => "/var/log/bluepill.log",
|
15
|
+
:base_dir => "/var/run/bluepill",
|
16
|
+
:privileged => true,
|
17
|
+
:timeout => 10,
|
18
|
+
:attempts => 1
|
19
|
+
}
|
20
|
+
|
21
|
+
OptionParser.new do |opts|
|
22
|
+
opts.banner = "Usage: bluepill [app] cmd [options]"
|
23
|
+
opts.on('-l', "--logfile LOGFILE", "Path to logfile, defaults to #{options[:log_file]}") do |file|
|
24
|
+
options[:log_file] = file
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on('-c', "--base-dir DIR", "Directory to store bluepill socket and pid files, defaults to #{options[:base_dir]}") do |base_dir|
|
28
|
+
options[:base_dir] = base_dir
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on("-v", "--version") do
|
32
|
+
puts "bluepill, version #{Bluepill::VERSION}"
|
33
|
+
exit
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on("--[no-]privileged", "Allow/disallow to run #{$0} as non-privileged process. disallowed by default") do |v|
|
37
|
+
options[:privileged] = v
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on('-t', '--timeout Seconds', Integer, "Timeout for commands sent to the daemon, in seconds. Defaults to 10.") do |timeout|
|
41
|
+
options[:timeout] = timeout
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on('--attempts Count', Integer, "Attempts for commands sent to the daemon, in seconds. Defaults to 1.") do |attempts|
|
45
|
+
options[:attempts] = attempts
|
46
|
+
end
|
47
|
+
|
48
|
+
help = proc do
|
49
|
+
puts opts
|
50
|
+
puts
|
51
|
+
puts "Commands:"
|
52
|
+
puts " load CONFIG_FILE\t\tLoads new instance of bluepill using the specified config file"
|
53
|
+
puts " status\t\t\tLists the status of the proceses for the specified app"
|
54
|
+
puts " start [TARGET]\t\tIssues the start command for the target process or group, defaults to all processes"
|
55
|
+
puts " stop [TARGET]\t\tIssues the stop command for the target process or group, defaults to all processes"
|
56
|
+
puts " restart [TARGET]\t\tIssues the restart command for the target process or group, defaults to all processes"
|
57
|
+
puts " unmonitor [TARGET]\t\tStop monitoring target process or group, defaults to all processes"
|
58
|
+
puts " log [TARGET]\t\tShow the log for the specified process or group, defaults to all for app"
|
59
|
+
puts " quit\t\t\tStop bluepill"
|
60
|
+
puts
|
61
|
+
puts "See http://github.com/arya/bluepill for README"
|
62
|
+
exit
|
63
|
+
end
|
64
|
+
|
65
|
+
opts.on_tail('-h','--help', 'Show this message', &help)
|
66
|
+
help.call if ARGV.empty?
|
67
|
+
end.parse!
|
68
|
+
|
69
|
+
# Check for root
|
70
|
+
if options[:privileged] && ::Process.euid != 0
|
71
|
+
$stderr.puts "You must run bluepill as root or use --no-privileged option."
|
72
|
+
exit(3)
|
73
|
+
end
|
74
|
+
|
75
|
+
APPLICATION_COMMANDS = %w(status start stop restart unmonitor quit log)
|
76
|
+
|
77
|
+
controller = Bluepill::Controller.new(options.slice(:base_dir, :log_file))
|
78
|
+
|
79
|
+
if controller.running_applications.include?(File.basename($0)) && File.symlink?($0)
|
80
|
+
# bluepill was called as a symlink with the name of the target application
|
81
|
+
options[:application] = File.basename($0)
|
82
|
+
elsif controller.running_applications.include?(ARGV.first)
|
83
|
+
# the first arg is the application name
|
84
|
+
options[:application] = ARGV.shift
|
85
|
+
elsif APPLICATION_COMMANDS.include?(ARGV.first)
|
86
|
+
if controller.running_applications.length == 1
|
87
|
+
# there is only one, let's just use that
|
88
|
+
options[:application] = controller.running_applications.first
|
89
|
+
elsif controller.running_applications.length > 1
|
90
|
+
# There is more than one, tell them the list and exit
|
91
|
+
$stderr.puts "You must specify an application name to run that command. Here's the list of running applications:"
|
92
|
+
controller.running_applications.each_with_index do |app, index|
|
93
|
+
$stderr.puts " #{index + 1}. #{app}"
|
94
|
+
end
|
95
|
+
$stderr.puts "Usage: bluepill [app] cmd [options]"
|
96
|
+
exit(1)
|
97
|
+
else
|
98
|
+
# There are none running AND they aren't trying to start one
|
99
|
+
$stderr.puts "Error: There are no running bluepill daemons.\nTo start a bluepill daemon, use: bluepill load <config file>"
|
100
|
+
exit(2)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
options[:command] = ARGV.shift
|
105
|
+
|
106
|
+
if options[:command] == "load"
|
107
|
+
file = ARGV.shift
|
108
|
+
if File.exists?(file)
|
109
|
+
# Restart the ruby interpreter for the config file so that anything loaded here
|
110
|
+
# does not stay in memory for the daemon
|
111
|
+
ruby = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
|
112
|
+
load_path = File.expand_path("#{File.dirname(__FILE__)}/../lib")
|
113
|
+
file_path = File.expand_path(file)
|
114
|
+
|
115
|
+
exec(ruby, "-I#{load_path}", '-rbluepill', file_path)
|
116
|
+
|
117
|
+
else
|
118
|
+
$stderr.puts "Can't find file: #{file}"
|
119
|
+
end
|
120
|
+
else
|
121
|
+
target = ARGV.shift
|
122
|
+
controller.handle_command(options[:application], options[:command], target)
|
123
|
+
end
|
124
|
+
|
data/bin/bpsv
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
# This is a modified version found at http://tomayko.com/writings/unicorn-is-unix
|
4
|
+
# It is modified to trigger various states like increase memory consumption so that
|
5
|
+
# I could write watches for them.
|
6
|
+
|
7
|
+
# Instructions for running the test
|
8
|
+
#
|
9
|
+
# (1) Edit the example config and fix the path to this file. Around line 16.
|
10
|
+
# (2) Load up the config and run the bluepill daemon
|
11
|
+
# (3) Run watch -n0.2 'sudo ruby bin/bluepill status 2>/dev/null; echo; ps ajxu | egrep "(CPU|forking|bluepill|sleep|ruby)" | grep -v grep | sort'
|
12
|
+
# (4) After verifying that the "sleep" workers are properly being restarted, telnet to localhost 4242 and say something. You should get it echoed back and the worker which answered your request should now be over the allowed memory limit
|
13
|
+
# (5) Observe the worker being killed in the watch you started in step 3.
|
14
|
+
|
15
|
+
require 'socket'
|
16
|
+
|
17
|
+
port = ARGV[0].to_i
|
18
|
+
port = 4242 if port == 0
|
19
|
+
|
20
|
+
acceptor = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
21
|
+
address = Socket.pack_sockaddr_in(port, '127.0.0.1')
|
22
|
+
acceptor.bind(address)
|
23
|
+
acceptor.listen(10)
|
24
|
+
|
25
|
+
children = []
|
26
|
+
trap('EXIT') { acceptor.close; children.each {|c| Process.kill('QUIT', c)} }
|
27
|
+
|
28
|
+
|
29
|
+
3.times do
|
30
|
+
children << fork do
|
31
|
+
trap('QUIT') {$0 = "forking_server| QUIT received shutting down gracefully..."; sleep 5; exit}
|
32
|
+
trap('INT') {$0 = "forking_server| INT received shutting down UN-gracefully..."; sleep 3; exit}
|
33
|
+
|
34
|
+
puts "child #$$ accepting on shared socket (localhost:#{port})"
|
35
|
+
loop {
|
36
|
+
socket, addr = acceptor.accept
|
37
|
+
socket.write "child #$$ echo> "
|
38
|
+
socket.flush
|
39
|
+
message = socket.gets
|
40
|
+
socket.write message
|
41
|
+
socket.close
|
42
|
+
puts "child #$$ echo'd: '#{message.strip}'"
|
43
|
+
|
44
|
+
# cause a spike in mem usage
|
45
|
+
temp = "*" * (100 * 1024)
|
46
|
+
}
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
trap('INT') { puts "\nbailing" ; exit }
|
52
|
+
|
53
|
+
Process.waitall
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
$LOAD_PATH.push File.expand_path("../lib", __FILE__)
|
4
|
+
|
5
|
+
require "bluepill/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "bluepill-rwgps"
|
9
|
+
s.version = Bluepill::VERSION.dup
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.authors = ["Cullen King", "Arya Asemanfar", "Gary Tsang", "Rohith Ravi"]
|
12
|
+
s.email = ["cullenk@gmail.com"]
|
13
|
+
s.homepage = "http://github.com/kingcu/bluepill-rwgps"
|
14
|
+
s.summary = %q{Fork of bluepill process monitory, reverting back to stable code with no global PID journal.}
|
15
|
+
s.description = %q{The original bluepill process monitor worked well. In 2013 several changes were introduced that were detrimental to the stability of bluepill, as well as the system running it. This fork reverts back to the stable/non-destructive code.}
|
16
|
+
|
17
|
+
s.add_dependency 'daemons', ['~> 1.1.4']
|
18
|
+
s.add_dependency 'state_machine', '~> 1.1.0'
|
19
|
+
s.add_dependency 'activesupport', ['>= 3', '< 4.1']
|
20
|
+
s.add_dependency 'i18n', '>= 0.5.0'
|
21
|
+
|
22
|
+
s.add_development_dependency 'bundler', '>= 1.0.10'
|
23
|
+
s.add_development_dependency 'rake', '!= 0.9.0'
|
24
|
+
s.add_development_dependency 'rspec-core', '~> 2.0'
|
25
|
+
s.add_development_dependency 'rspec-expectations', '~> 2.0'
|
26
|
+
s.add_development_dependency 'rr', '~> 1.0'
|
27
|
+
s.add_development_dependency 'faker', '~> 0.9'
|
28
|
+
s.add_development_dependency 'yard', '~> 0.7'
|
29
|
+
|
30
|
+
s.files = `git ls-files`.split("\n")
|
31
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
32
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
s.extra_rdoc_files = ["LICENSE", "README.md"]
|
35
|
+
end
|
36
|
+
|
data/examples/example.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bluepill'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
ROOT_DIR = "/tmp/bp"
|
6
|
+
|
7
|
+
# Watch with
|
8
|
+
# watch -n0.2 'ps axu | egrep "(CPU|forking|bluepill|sleep)" | grep -v grep | sort'
|
9
|
+
Bluepill.application(:sample_app) do |app|
|
10
|
+
0.times do |i|
|
11
|
+
app.process("process_#{i}") do |process|
|
12
|
+
process.pid_file = "#{ROOT_DIR}/pids/process_#{i}.pid"
|
13
|
+
|
14
|
+
# Example of use of pid_command option to find memcached process
|
15
|
+
# process.pid_command = "ps -ef | awk '/memcached$/{ print $2 }'"
|
16
|
+
|
17
|
+
# I could not figure out a portable way to
|
18
|
+
# specify the path to the sample forking server across the diff developer laptops.
|
19
|
+
# Since this code is eval'ed we cannot reliably use __FILE__
|
20
|
+
process.start_command = "/Users/rohith/work/bluepill/bin/sample_forking_server #{4242 + i}"
|
21
|
+
process.stop_command = "kill -INT {{PID}}"
|
22
|
+
process.daemonize = true
|
23
|
+
|
24
|
+
process.start_grace_time = 1.seconds
|
25
|
+
process.restart_grace_time = 7.seconds
|
26
|
+
process.stop_grace_time = 7.seconds
|
27
|
+
|
28
|
+
process.uid = "rohith"
|
29
|
+
process.gid = "staff"
|
30
|
+
|
31
|
+
# process.checks :cpu_usage, :every => 10, :below => 0.5, :times => [5, 5]
|
32
|
+
process.checks :flapping, :times => 2, :within => 30.seconds, :retry_in => 7.seconds
|
33
|
+
|
34
|
+
process.monitor_children do |child_process|
|
35
|
+
# child_process.checks :cpu_usage,
|
36
|
+
# :every => 10,
|
37
|
+
# :below => 0.5,
|
38
|
+
# :times => [5, 5]
|
39
|
+
|
40
|
+
# child_process.checks :mem_usage,
|
41
|
+
# :every => 3,
|
42
|
+
# :below => 600.kilobytes,
|
43
|
+
# :times => [3, 5],
|
44
|
+
# :fires => [:stop]
|
45
|
+
|
46
|
+
child_process.stop_command = "kill -QUIT {{PID}}"
|
47
|
+
# child_process.checks :flapping, :times => 2, :within => 30.seconds, :retry_in => 7.seconds
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
0.times do |i|
|
53
|
+
app.process("group_process_#{i}") do |process|
|
54
|
+
process.group = "group_1"
|
55
|
+
process.pid_file = "/Users/rohith/ffs/tmp/pids/mongrel_#{i}.pid"
|
56
|
+
process.start_command = "cd ~/ffs && mongrel_rails start -P #{process.pid_file} -p 3000 -d"
|
57
|
+
|
58
|
+
process.start_grace_time = 10.seconds
|
59
|
+
|
60
|
+
process.uid = "rohith"
|
61
|
+
process.gid = "staff"
|
62
|
+
|
63
|
+
# process.checks :always_true, :every => 10
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
1.times do |i|
|
68
|
+
app.process("group_process_#{i}") do |process|
|
69
|
+
process.auto_start = false
|
70
|
+
|
71
|
+
process.uid = "rohith"
|
72
|
+
process.gid = "wheel"
|
73
|
+
|
74
|
+
process.stderr = "/tmp/err.log"
|
75
|
+
process.stdout = "/tmp/err.log"
|
76
|
+
|
77
|
+
|
78
|
+
process.group = "grouped"
|
79
|
+
process.start_command = %Q{cd /tmp && ruby -e '$stderr.puts("hello stderr");$stdout.puts("hello stdout"); $stdout.flush; $stderr.flush; sleep 10'}
|
80
|
+
process.daemonize = true
|
81
|
+
process.pid_file = "/tmp/noperm/p_#{process.group}_#{i}.pid"
|
82
|
+
|
83
|
+
# process.checks :always_true, :every => 5
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bluepill'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
# Note that this syntax supported from bluepill 0.0.50
|
6
|
+
|
7
|
+
ROOT_DIR = "/tmp/bp"
|
8
|
+
|
9
|
+
# Watch with
|
10
|
+
# watch -n0.2 'ps axu | egrep "(CPU|forking|bluepill|sleep)" | grep -v grep | sort'
|
11
|
+
Bluepill.application(:sample_app) do
|
12
|
+
0.times do |i|
|
13
|
+
process("process_#{i}") do
|
14
|
+
pid_file "#{ROOT_DIR}/pids/process_#{i}.pid"
|
15
|
+
|
16
|
+
# Example of use of pid_command option to find memcached process
|
17
|
+
# pid_command = "ps -ef | awk '/memcached$/{ print $2 }'"
|
18
|
+
|
19
|
+
# I could not figure out a portable way to
|
20
|
+
# specify the path to the sample forking server across the diff developer laptops.
|
21
|
+
# Since this code is eval'ed we cannot reliably use __FILE__
|
22
|
+
start_command "/Users/rohith/work/bluepill/bin/sample_forking_server #{4242 + i}"
|
23
|
+
stop_command "kill -INT {{PID}}"
|
24
|
+
daemonize!
|
25
|
+
|
26
|
+
start_grace_time 1.seconds
|
27
|
+
restart_grace_time 7.seconds
|
28
|
+
stop_grace_time 7.seconds
|
29
|
+
|
30
|
+
uid "rohith"
|
31
|
+
gid "staff"
|
32
|
+
|
33
|
+
# checks :cpu_usage, :every => 10, :below => 0.5, :times => [5, 5]
|
34
|
+
checks :flapping, :times => 2, :within => 30.seconds, :retry_in => 7.seconds
|
35
|
+
|
36
|
+
monitor_children do
|
37
|
+
# checks :cpu_usage,
|
38
|
+
# :every => 10,
|
39
|
+
# :below => 0.5,
|
40
|
+
# :times => [5, 5]
|
41
|
+
|
42
|
+
# checks :mem_usage,
|
43
|
+
# :every => 3,
|
44
|
+
# :below => 600.kilobytes,
|
45
|
+
# :times => [3, 5],
|
46
|
+
# :fires => [:stop]
|
47
|
+
|
48
|
+
stop_command "kill -QUIT {{PID}}"
|
49
|
+
# checks :flapping, :times => 2, :within => 30.seconds, :retry_in => 7.seconds
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
0.times do |i|
|
55
|
+
process("group_process_#{i}") do
|
56
|
+
group "group_1"
|
57
|
+
pid_file "/Users/rohith/ffs/tmp/pids/mongrel_#{i}.pid"
|
58
|
+
start_command "cd ~/ffs && mongrel_rails start -P #{pid_file} -p 3000 -d"
|
59
|
+
|
60
|
+
start_grace_time 10.seconds
|
61
|
+
|
62
|
+
uid "rohith"
|
63
|
+
gid "staff"
|
64
|
+
|
65
|
+
# checks :always_true, :every => 10
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
1.times do |i|
|
70
|
+
process("group_process_#{i}") do
|
71
|
+
auto_start false
|
72
|
+
|
73
|
+
uid "rohith"
|
74
|
+
gid "wheel"
|
75
|
+
|
76
|
+
stderr "/tmp/err.log"
|
77
|
+
stdout "/tmp/err.log"
|
78
|
+
|
79
|
+
|
80
|
+
group "grouped"
|
81
|
+
start_command %Q{cd /tmp && ruby -e '$stderr.puts("hello stderr");$stdout.puts("hello stdout"); $stdout.flush; $stderr.flush; sleep 10'}
|
82
|
+
daemonize!
|
83
|
+
pid_file "/tmp/noperm/p_#{group}_#{i}.pid"
|
84
|
+
|
85
|
+
# checks :always_true, :every => 5
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bluepill'
|
4
|
+
require 'logger'
|
5
|
+
|
6
|
+
# ATTENTION:
|
7
|
+
# You must declare only one application per config when foreground mode specified
|
8
|
+
#
|
9
|
+
# http://github.com/Undev/runit-man used as example of monitored application.
|
10
|
+
|
11
|
+
# Note that this syntax supported from bluepill 0.0.50
|
12
|
+
|
13
|
+
Bluepill.application(:runit_man, :foreground => true) do
|
14
|
+
process("runit-man") do
|
15
|
+
pid_file "/etc/service/runit-man/supervise/pid"
|
16
|
+
|
17
|
+
start_command "/usr/bin/sv start runit-man"
|
18
|
+
stop_command "/usr/bin/sv stop runit-man"
|
19
|
+
restart_command "/usr/bin/sv restart runit-man"
|
20
|
+
|
21
|
+
start_grace_time 1.seconds
|
22
|
+
restart_grace_time 7.seconds
|
23
|
+
stop_grace_time 7.seconds
|
24
|
+
|
25
|
+
checks :http, :within => 30.seconds, :retry_in => 7.seconds, :every => 30.seconds,
|
26
|
+
:url => 'http://localhost:4567/', :kind => :success, :pattern => /html/, :timeout => 3.seconds
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bluepill'
|
4
|
+
require 'logger'
|
5
|
+
|
6
|
+
# ATTENTION:
|
7
|
+
# You must declare only one application per config when foreground mode specified
|
8
|
+
#
|
9
|
+
# http://github.com/Undev/runit-man used as example of monitored application.
|
10
|
+
|
11
|
+
Bluepill.application(:runit_man, :foreground => true) do |app|
|
12
|
+
app.process("runit-man") do |process|
|
13
|
+
process.pid_file = "/etc/service/runit-man/supervise/pid"
|
14
|
+
|
15
|
+
process.start_command = "/usr/bin/sv start runit-man"
|
16
|
+
process.stop_command = "/usr/bin/sv stop runit-man"
|
17
|
+
process.restart_command = "/usr/bin/sv restart runit-man"
|
18
|
+
|
19
|
+
process.start_grace_time = 1.seconds
|
20
|
+
process.restart_grace_time = 7.seconds
|
21
|
+
process.stop_grace_time = 7.seconds
|
22
|
+
|
23
|
+
process.checks :http, :within => 30.seconds, :retry_in => 7.seconds, :every => 30.seconds,
|
24
|
+
:url => 'http://localhost:4567/', :kind => :success, :pattern => /html/, :timeout => 3.seconds
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module Bluepill
|
3
|
+
module Application
|
4
|
+
module ServerMethods
|
5
|
+
|
6
|
+
def status
|
7
|
+
self.processes.collect do |process|
|
8
|
+
"#{process.name} #{process.state}"
|
9
|
+
end.join("\n")
|
10
|
+
end
|
11
|
+
|
12
|
+
def restart
|
13
|
+
self.socket = Bluepill::Socket.new(name, base_dir).client
|
14
|
+
socket.send("restart\n", 0)
|
15
|
+
end
|
16
|
+
|
17
|
+
def stop
|
18
|
+
self.socket = Bluepill::Socket.new(name, base_dir).client
|
19
|
+
socket.send("stop\n", 0)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|