evented_bluepill 0.0.47 → 0.0.50
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +14 -0
- data/DESIGN.md +2 -2
- data/README.md +35 -37
- data/Rakefile +9 -0
- data/bin/bluepill +9 -102
- data/bin/evented_bluepill +13 -0
- data/evented_bluepill.gemspec +10 -6
- data/{lib → example}/example.rb +4 -7
- data/{lib → example}/runit_example.rb +2 -2
- data/{bin → example}/sample_forking_server +2 -2
- data/lib/bluepill.rb +3 -31
- data/lib/{bluepill → evented_bluepill}/application/client.rb +1 -1
- data/lib/evented_bluepill/application/server.rb +24 -0
- data/lib/{bluepill → evented_bluepill}/application.rb +14 -14
- data/lib/{bluepill → evented_bluepill}/controller.rb +30 -20
- data/lib/{bluepill → evented_bluepill}/dsl/app_proxy.rb +3 -3
- data/lib/{bluepill → evented_bluepill}/dsl/process_factory.rb +8 -5
- data/lib/{bluepill → evented_bluepill}/dsl/process_proxy.rb +3 -3
- data/lib/{bluepill → evented_bluepill}/dsl.rb +5 -2
- data/lib/{bluepill → evented_bluepill}/event.rb +1 -1
- data/lib/{bluepill → evented_bluepill}/group.rb +2 -2
- data/lib/{bluepill → evented_bluepill}/logger.rb +5 -2
- data/lib/evented_bluepill/options.rb +121 -0
- data/lib/{bluepill → evented_bluepill}/process.rb +12 -16
- data/lib/{bluepill → evented_bluepill}/process_conditions/always_true.rb +7 -3
- data/lib/evented_bluepill/process_conditions/cpu_usage.rb +25 -0
- data/lib/{bluepill → evented_bluepill}/process_conditions/http.rb +8 -3
- data/lib/evented_bluepill/process_conditions/mem_usage.rb +41 -0
- data/lib/evented_bluepill/process_conditions/process_condition.rb +72 -0
- data/lib/{bluepill → evented_bluepill}/process_conditions.rb +2 -2
- data/lib/{bluepill → evented_bluepill}/process_statistics.rb +10 -10
- data/lib/{bluepill → evented_bluepill}/socket.rb +2 -1
- data/lib/{bluepill → evented_bluepill}/system.rb +24 -21
- data/lib/{bluepill → evented_bluepill}/trigger.rb +4 -4
- data/lib/{bluepill → evented_bluepill}/triggers/flapping.rb +3 -8
- data/lib/evented_bluepill/util/rotational_array.rb +21 -0
- data/lib/evented_bluepill/version.rb +12 -0
- data/lib/evented_bluepill.rb +22 -0
- data/spec/always_true_spec.rb +19 -0
- data/spec/cpu_usage_spec.rb +28 -0
- data/spec/mem_usage_spec.rb +46 -0
- data/spec/process_condition_spec.rb +30 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/system_spec.rb +15 -0
- metadata +137 -122
- data/lib/bluepill/application/server.rb +0 -26
- data/lib/bluepill/condition_watch.rb +0 -61
- data/lib/bluepill/process_conditions/cpu_usage.rb +0 -20
- data/lib/bluepill/process_conditions/mem_usage.rb +0 -33
- data/lib/bluepill/process_conditions/process_condition.rb +0 -23
- data/lib/bluepill/util/rotational_array.rb +0 -74
- data/lib/bluepill/version.rb +0 -5
data/CHANGELOG.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
## 0.0.50 (March 5, 2011)
|
2
|
+
|
3
|
+
* deprecate the use of bluepill, use evented\_bluepill instead
|
4
|
+
* internal refactoring
|
5
|
+
* updated dependencies
|
6
|
+
|
7
|
+
## 0.0.47 (January 10, 2011)
|
8
|
+
|
9
|
+
* actually use the new evented code
|
10
|
+
* switched from jeweler to bundler for gem creation and dependency tracking
|
11
|
+
|
12
|
+
## 0.0.46 (January 10, 2011)
|
13
|
+
|
14
|
+
* initial evented release
|
data/DESIGN.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
##
|
1
|
+
## EventedBluepill Design
|
2
2
|
Here are just some bullet points of the design. We'll add details later.
|
3
3
|
|
4
|
-
* Each process monitors a single _application_, so you can have multiple
|
4
|
+
* Each process monitors a single _application_, so you can have multiple evented\_bluepill processes on a system
|
5
5
|
* Use rotational arrays for storing historical data for monitoring process conditions
|
6
6
|
* Memo-ize output of _ps_ per tick as an optimization for applications with many processes
|
7
7
|
* Use socket files to communicate between CLI and daemon
|
data/README.md
CHANGED
@@ -1,35 +1,35 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# EventedBluepill
|
2
|
+
EventedBluepill is a simple process monitoring tool written in Ruby.
|
3
3
|
|
4
4
|
## Installation
|
5
5
|
It's hosted on [gemcutter.org][gemcutter].
|
6
6
|
|
7
|
-
sudo gem install
|
7
|
+
sudo gem install evented_bluepill
|
8
8
|
|
9
9
|
In order to take advantage of logging with syslog, you also need to setup your syslog to log the local6 facility. Edit the appropriate config file for your syslogger (/etc/syslog.conf for syslog) and add a line for local6:
|
10
10
|
|
11
|
-
local6.* /var/log/
|
11
|
+
local6.* /var/log/evented_bluepill.log
|
12
12
|
|
13
|
-
You'll also want to add _/var/log/
|
13
|
+
You'll also want to add _/var/log/evented\_bluepill.log_ to _/etc/logrotate.d/syslog_ so that it gets rotated.
|
14
14
|
|
15
|
-
Lastly, create the _/var/
|
15
|
+
Lastly, create the _/var/evented\_bluepill_ directory for evented\_bluepill to store its pid and sock files.
|
16
16
|
|
17
17
|
## Usage
|
18
18
|
### Config
|
19
|
-
|
19
|
+
EventedBluepill organizes processes into 3 levels: application -> group -> process. Each process has a few attributes that tell evented\_bluepill how to start, stop, and restart it, where to look or put the pid file, what process conditions to monitor and the options for each of those.
|
20
20
|
|
21
21
|
The minimum config file looks something like this:
|
22
22
|
|
23
|
-
|
23
|
+
EventedBluepill.application("app_name") do |app|
|
24
24
|
app.process("process_name") do |process|
|
25
25
|
process.start_command = "/usr/bin/some_start_command"
|
26
26
|
process.pid_file = "/tmp/some_pid_file.pid"
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
Note that since we specified a PID file and start command,
|
30
|
+
Note that since we specified a PID file and start command, evented\_bluepill assumes the process will daemonize itself. If we wanted evented\_bluepill to daemonize it for us, we can do (note we still need to specify a PID file):
|
31
31
|
|
32
|
-
|
32
|
+
EventedBluepill.application("app_name") do |app|
|
33
33
|
app.process("process_name") do |process|
|
34
34
|
process.start_command = "/usr/bin/some_start_command"
|
35
35
|
process.pid_file = "/tmp/some_pid_file.pid"
|
@@ -41,7 +41,7 @@ If you don't specify a stop command, a TERM signal will be sent by default. Simi
|
|
41
41
|
|
42
42
|
Now if we want to do something more meaningful, like actually monitor the process, we do:
|
43
43
|
|
44
|
-
|
44
|
+
EventedBluepill.application("app_name") do |app|
|
45
45
|
app.process("process_name") do |process|
|
46
46
|
process.start_command = "/usr/bin/some_start_command"
|
47
47
|
process.pid_file = "/tmp/some_pid_file.pid"
|
@@ -54,7 +54,7 @@ We added a line that checks every 10 seconds to make sure the cpu usage of this
|
|
54
54
|
|
55
55
|
To watch memory usage, we just add one more line:
|
56
56
|
|
57
|
-
|
57
|
+
EventedBluepill.application("app_name") do |app|
|
58
58
|
app.process("process_name") do |process|
|
59
59
|
process.start_command = "/usr/bin/some_start_command"
|
60
60
|
process.pid_file = "/tmp/some_pid_file.pid"
|
@@ -64,9 +64,9 @@ To watch memory usage, we just add one more line:
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
We can tell
|
67
|
+
We can tell evented\_bluepill to give a process some grace time to start/stop/restart before resuming monitoring:
|
68
68
|
|
69
|
-
|
69
|
+
EventedBluepill.application("app_name") do |app|
|
70
70
|
app.process("process_name") do |process|
|
71
71
|
process.start_command = "/usr/bin/some_start_command"
|
72
72
|
process.pid_file = "/tmp/some_pid_file.pid"
|
@@ -81,7 +81,7 @@ We can tell bluepill to give a process some grace time to start/stop/restart bef
|
|
81
81
|
|
82
82
|
We can group processes by name:
|
83
83
|
|
84
|
-
|
84
|
+
EventedBluepill.application("app_name") do |app|
|
85
85
|
5.times do |i|
|
86
86
|
app.process("process_name_#{i}") do |process|
|
87
87
|
process.group = "mongrels"
|
@@ -93,7 +93,7 @@ We can group processes by name:
|
|
93
93
|
|
94
94
|
If you want to run the process as someone other than root:
|
95
95
|
|
96
|
-
|
96
|
+
EventedBluepill.application("app_name") do |app|
|
97
97
|
app.process("process_name") do |process|
|
98
98
|
process.start_command = "/usr/bin/some_start_command"
|
99
99
|
process.pid_file = "/tmp/some_pid_file.pid"
|
@@ -107,7 +107,7 @@ If you want to run the process as someone other than root:
|
|
107
107
|
|
108
108
|
You can also set an app-wide uid/gid:
|
109
109
|
|
110
|
-
|
110
|
+
EventedBluepill.application("app_name") do |app|
|
111
111
|
app.uid = "deploy"
|
112
112
|
app.gid = "deploy"
|
113
113
|
app.process("process_name") do |process|
|
@@ -122,7 +122,7 @@ To check for flapping:
|
|
122
122
|
|
123
123
|
To set the working directory to _cd_ into when starting the command:
|
124
124
|
|
125
|
-
|
125
|
+
EventedBluepill.application("app_name") do |app|
|
126
126
|
app.process("process_name") do |process|
|
127
127
|
process.start_command = "/usr/bin/some_start_command"
|
128
128
|
process.pid_file = "/tmp/some_pid_file.pid"
|
@@ -133,7 +133,7 @@ To set the working directory to _cd_ into when starting the command:
|
|
133
133
|
You can also have an app-wide working directory:
|
134
134
|
|
135
135
|
|
136
|
-
|
136
|
+
EventedBluepill.application("app_name") do |app|
|
137
137
|
app.working_dir = "/path/to/some_directory"
|
138
138
|
app.process("process_name") do |process|
|
139
139
|
process.start_command = "/usr/bin/some_start_command"
|
@@ -159,7 +159,7 @@ Note {{PID}} will be substituted for the pid of process in both the stop and res
|
|
159
159
|
|
160
160
|
While you can specify shell tricks like the following in the start_command of a process:
|
161
161
|
|
162
|
-
|
162
|
+
EventedBluepill.application("app_name") do |app|
|
163
163
|
app.process("process_name") do |process|
|
164
164
|
process.start_command = "cd /tmp/some_dir && SOME_VAR=1 /usr/bin/some_start_command > /tmp/server.log 2>&1"
|
165
165
|
process.pid_file = "/tmp/some_pid_file.pid"
|
@@ -168,7 +168,7 @@ While you can specify shell tricks like the following in the start_command of a
|
|
168
168
|
|
169
169
|
We recommend that you _not_ do that and instead use the config options to capture output from your daemons. Like so:
|
170
170
|
|
171
|
-
|
171
|
+
EventedBluepill.application("app_name") do |app|
|
172
172
|
app.process("process_name") do |process|
|
173
173
|
process.start_command = "/usr/bin/env SOME_VAR=1 /usr/bin/some_start_command"
|
174
174
|
|
@@ -179,50 +179,48 @@ We recommend that you _not_ do that and instead use the config options to captur
|
|
179
179
|
end
|
180
180
|
end
|
181
181
|
|
182
|
-
The main benefit of using the config options is that
|
182
|
+
The main benefit of using the config options is that EventedBluepill will be able to monitor the correct process instead of just watching the shell that spawned your actual server.
|
183
183
|
|
184
184
|
### CLI
|
185
|
-
To start a
|
185
|
+
To start a evented_bluepill process and load a config:
|
186
186
|
|
187
|
-
sudo
|
187
|
+
sudo evented_bluepill load /path/to/production.pill
|
188
188
|
|
189
189
|
To act on a process or group:
|
190
190
|
|
191
|
-
sudo
|
191
|
+
sudo evented_bluepill <start|stop|restart|unmonitor> <process_or_group_name>
|
192
192
|
|
193
193
|
To view process statuses:
|
194
194
|
|
195
|
-
sudo
|
195
|
+
sudo evented_bluepill status
|
196
196
|
|
197
197
|
To view the log for a process or group:
|
198
198
|
|
199
|
-
sudo
|
199
|
+
sudo evented_bluepill log <process_or_group_name>
|
200
200
|
|
201
|
-
To quit
|
201
|
+
To quit evented_bluepill:
|
202
202
|
|
203
|
-
sudo
|
203
|
+
sudo evented_bluepill quit
|
204
204
|
|
205
205
|
### Logging
|
206
|
-
By default,
|
206
|
+
By default, evented\_bluepill uses syslog local6 facility as described in the installation section. But if for any reason you don't want to use syslog, you can use a log file. You can do this by setting the :log\_file option in the config:
|
207
207
|
|
208
|
-
|
208
|
+
EventedBluepill.application("app_name", :log_file => "/path/to/evented_bluepill.log") do |app|
|
209
209
|
# ...
|
210
210
|
end
|
211
211
|
|
212
212
|
Keep in mind that you still need to set up log rotation (described in the installation section) to keep the log file from growing huge.
|
213
213
|
|
214
214
|
### Extra options
|
215
|
-
You can run
|
215
|
+
You can run evented\_bluepill in the foreground:
|
216
216
|
|
217
|
-
|
217
|
+
EventedBluepill.application("app_name", :foreground => true) do |app|
|
218
218
|
# ...
|
219
219
|
end
|
220
220
|
|
221
221
|
## Links
|
222
|
-
Code: [http://github.com/
|
223
|
-
Bugs/Features: [http://github.com/
|
224
|
-
Mailing List: [http://groups.google.com/group/bluepill-rb](http://groups.google.com/group/bluepill-rb)
|
225
|
-
|
222
|
+
Code: [http://github.com/msnexploder/evented_bluepill](http://github.com/msnexploder/evented_bluepill)
|
223
|
+
Bugs/Features: [http://github.com/msnexploder/evented_bluepill/issues](http://github.com/msnexploder/evented_bluepill/issues)
|
226
224
|
|
227
225
|
[gemcutter]: http://gemcutter.org
|
228
226
|
|
data/Rakefile
CHANGED
data/bin/bluepill
CHANGED
@@ -1,108 +1,15 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
# -*- encoding: utf-8 -*-
|
3
|
-
require '
|
4
|
-
require '
|
3
|
+
require 'evented_bluepill/options'
|
4
|
+
require 'evented_bluepill/controller'
|
5
5
|
|
6
|
-
|
7
|
-
options = {
|
8
|
-
:log_file => "/var/log/bluepill.log",
|
9
|
-
:base_dir => "/var/bluepill",
|
10
|
-
:privileged => true
|
11
|
-
}
|
6
|
+
STDERR.puts "*** DEPRECATION WARNING: using 'bluepill' is deprecated. Please use 'evented_bluepill' instead ***"
|
12
7
|
|
13
|
-
|
14
|
-
opts.banner = "Usage: bluepill [app] cmd [options]"
|
15
|
-
opts.on('-l', "--logfile LOGFILE", "Path to logfile, defaults to #{options[:log_file]}") do |file|
|
16
|
-
options[:log_file] = file
|
17
|
-
end
|
8
|
+
EventedBluepill::Options.parse!
|
18
9
|
|
19
|
-
|
20
|
-
|
21
|
-
|
10
|
+
command = ARGV.shift
|
11
|
+
target = ARGV.shift
|
12
|
+
application = EventedBluepill::Options[:application]
|
22
13
|
|
23
|
-
|
24
|
-
|
25
|
-
exit
|
26
|
-
end
|
27
|
-
|
28
|
-
opts.on("--[no-]privileged", "Allow/disallow to run #{$0} as non-privileged process. disallowed by default") do |v|
|
29
|
-
options[:privileged] = v
|
30
|
-
end
|
31
|
-
|
32
|
-
help = proc do
|
33
|
-
puts opts
|
34
|
-
puts
|
35
|
-
puts "Commands:"
|
36
|
-
puts " load CONFIG_FILE\t\tLoads new instance of bluepill using the specified config file"
|
37
|
-
puts " status\t\t\tLists the status of the proceses for the specified app"
|
38
|
-
puts " start [TARGET]\t\tIssues the start command for the target process or group, defaults to all processes"
|
39
|
-
puts " stop [TARGET]\t\tIssues the stop command for the target process or group, defaults to all processes"
|
40
|
-
puts " restart [TARGET]\t\tIssues the restart command for the target process or group, defaults to all processes"
|
41
|
-
puts " unmonitor [TARGET]\t\tStop monitoring target process or group, defaults to all processes"
|
42
|
-
puts " log [TARGET]\t\tShow the log for the specified process or group, defaults to all for app"
|
43
|
-
puts " quit\t\t\tStop bluepill"
|
44
|
-
puts
|
45
|
-
puts "See http://github.com/arya/bluepill for README"
|
46
|
-
exit
|
47
|
-
end
|
48
|
-
|
49
|
-
opts.on_tail('-h','--help', 'Show this message', &help)
|
50
|
-
help.call if ARGV.empty?
|
51
|
-
end.parse!
|
52
|
-
|
53
|
-
# Check for root
|
54
|
-
if options[:privileged] && ::Process.euid != 0
|
55
|
-
$stderr.puts "You must run bluepill as root or use --no-privileged option."
|
56
|
-
exit(3)
|
57
|
-
end
|
58
|
-
|
59
|
-
APPLICATION_COMMANDS = %w(status start stop restart unmonitor quit log)
|
60
|
-
|
61
|
-
controller = Bluepill::Controller.new(options.slice(:base_dir, :log_file))
|
62
|
-
|
63
|
-
if controller.running_applications.include?(File.basename($0)) && File.symlink?($0)
|
64
|
-
# bluepill was called as a symlink with the name of the target application
|
65
|
-
options[:application] = File.basename($0)
|
66
|
-
elsif controller.running_applications.include?(ARGV.first)
|
67
|
-
# the first arg is the application name
|
68
|
-
options[:application] = ARGV.shift
|
69
|
-
elsif APPLICATION_COMMANDS.include?(ARGV.first)
|
70
|
-
if controller.running_applications.length == 1
|
71
|
-
# there is only one, let's just use that
|
72
|
-
options[:application] = controller.running_applications.first
|
73
|
-
elsif controller.running_applications.length > 1
|
74
|
-
# There is more than one, tell them the list and exit
|
75
|
-
$stderr.puts "You must specify an application name to run that command. Here's the list of running applications:"
|
76
|
-
controller.running_applications.each_with_index do |app, index|
|
77
|
-
$stderr.puts " #{index + 1}. #{app}"
|
78
|
-
end
|
79
|
-
$stderr.puts "Usage: bluepill [app] cmd [options]"
|
80
|
-
exit(1)
|
81
|
-
else
|
82
|
-
# There are none running AND they aren't trying to start one
|
83
|
-
$stderr.puts "Error: There are no running bluepill daemons.\nTo start a bluepill daemon, use: bluepill load <config file>"
|
84
|
-
exit(2)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
options[:command] = ARGV.shift
|
89
|
-
|
90
|
-
if options[:command] == "load"
|
91
|
-
file = ARGV.shift
|
92
|
-
if File.exists?(file)
|
93
|
-
# Restart the ruby interpreter for the config file so that anything loaded here
|
94
|
-
# does not stay in memory for the daemon
|
95
|
-
require 'rbconfig'
|
96
|
-
ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
|
97
|
-
load_path = File.expand_path("#{File.dirname(__FILE__)}/../lib")
|
98
|
-
file_path = File.expand_path(file)
|
99
|
-
|
100
|
-
exec(ruby, "-I#{load_path}", '-rbluepill', file_path)
|
101
|
-
|
102
|
-
else
|
103
|
-
$stderr.puts "Can't find file: #{file}"
|
104
|
-
end
|
105
|
-
else
|
106
|
-
target = ARGV.shift
|
107
|
-
controller.handle_command(options[:application], options[:command], target)
|
108
|
-
end
|
14
|
+
controller = EventedBluepill::Controller.new
|
15
|
+
controller.handle_command(application, command, target)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
require 'evented_bluepill/options'
|
4
|
+
require 'evented_bluepill/controller'
|
5
|
+
|
6
|
+
EventedBluepill::Options.parse!
|
7
|
+
|
8
|
+
command = ARGV.shift
|
9
|
+
target = ARGV.shift
|
10
|
+
application = EventedBluepill::Options[:application]
|
11
|
+
|
12
|
+
controller = EventedBluepill::Controller.new
|
13
|
+
controller.handle_command(application, command, target)
|
data/evented_bluepill.gemspec
CHANGED
@@ -1,23 +1,27 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
$:.push File.expand_path("../lib", __FILE__)
|
3
|
-
require "
|
3
|
+
require "evented_bluepill/version"
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = "evented_bluepill"
|
7
|
-
s.version =
|
7
|
+
s.version = EventedBluepill::VERSION::STRING
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ["Stefan Huber", "Arya Asemanfar", "Gary Tsang", "Rohith Ravi"]
|
10
10
|
s.email = ["MSNexploder@gmail.com"]
|
11
11
|
s.homepage = "http://github.com/msnexploder/evented_bluepill"
|
12
12
|
s.summary = %q{A process monitor written in Ruby with stability and minimalism in mind.}
|
13
|
-
s.description = %q{
|
13
|
+
s.description = %q{EventedBluepill keeps your daemons up while taking up as little resources as possible. After all you probably want the resources of your server to be used by whatever daemons you are running rather than the thing that's supposed to make sure they are brought back up, should they die or misbehave.}
|
14
14
|
|
15
|
-
s.add_dependency 'daemons', '~> 1.0
|
15
|
+
s.add_dependency 'daemons', '~> 1.1.0'
|
16
16
|
s.add_dependency 'blankslate', '~> 2.1.2.3'
|
17
|
-
s.add_dependency 'state_machine', '~> 0.
|
18
|
-
s.add_dependency 'activesupport', '~>
|
17
|
+
s.add_dependency 'state_machine', '~> 0.9.4'
|
18
|
+
s.add_dependency 'activesupport', '~> 3.0.0'
|
19
|
+
s.add_dependency 'i18n', '~> 0.5.0'
|
19
20
|
s.add_dependency 'cool.io', '~> 1.0.0'
|
20
21
|
|
22
|
+
s.add_development_dependency 'minitest', '~> 2.0.2'
|
23
|
+
s.add_development_dependency 'mocha', '~> 0.9.12'
|
24
|
+
|
21
25
|
s.rubyforge_project = "evented_bluepill"
|
22
26
|
|
23
27
|
s.files = `git ls-files`.split("\n")
|
data/{lib → example}/example.rb
RENAMED
@@ -1,16 +1,13 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
# -*- encoding: utf-8 -*-
|
3
3
|
|
4
|
-
require '
|
5
|
-
require 'bluepill'
|
6
|
-
require 'active_support'
|
7
|
-
require 'logger'
|
4
|
+
require 'evented_bluepill'
|
8
5
|
|
9
6
|
ROOT_DIR = "/tmp/bp"
|
10
7
|
|
11
8
|
# Watch with
|
12
|
-
# watch -n0.2 'ps axu | egrep "(CPU|forking|
|
13
|
-
|
9
|
+
# watch -n0.2 'ps axu | egrep "(CPU|forking|evented_bluepill|sleep)" | grep -v grep | sort'
|
10
|
+
EventedBluepill.application(:sample_app, :foreground => true, :log_file => '/tmp/bp/sample_app.log') do |app|
|
14
11
|
1.times do |i|
|
15
12
|
app.process("process_#{i}") do |process|
|
16
13
|
process.pid_file = "#{ROOT_DIR}/pids/process_#{i}.pid"
|
@@ -18,7 +15,7 @@ Bluepill.application(:sample_app, :foreground => true, :log_file => '/tmp/bp/sam
|
|
18
15
|
# I could not figure out a portable way to
|
19
16
|
# specify the path to the sample forking server across the diff developer laptops.
|
20
17
|
# Since this code is eval'ed we cannot reliably use __FILE__
|
21
|
-
process.start_command = "/Users/stefan/Documents/projects/
|
18
|
+
process.start_command = "/Users/stefan/Documents/projects/evented_bluepill/example/sample_forking_server #{4242 + i}"
|
22
19
|
process.stop_command = "kill -INT {{PID}}"
|
23
20
|
process.daemonize = true
|
24
21
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
-
require '
|
4
|
+
require 'evented_bluepill'
|
5
5
|
require 'logger'
|
6
6
|
|
7
7
|
# ATTENTION:
|
@@ -9,7 +9,7 @@ require 'logger'
|
|
9
9
|
#
|
10
10
|
# http://github.com/akzhan/runit-man used as example of monitored application.
|
11
11
|
|
12
|
-
|
12
|
+
EventedBluepill.application(:runit_man, :foreground => true) do |app|
|
13
13
|
app.process("runit-man") do |process|
|
14
14
|
process.pid_file = "/etc/service/runit-man/supervise/pid"
|
15
15
|
|
@@ -8,8 +8,8 @@
|
|
8
8
|
# Instructions for running the test
|
9
9
|
#
|
10
10
|
# (1) Edit the example config and fix the path to this file. Around line 16.
|
11
|
-
# (2) Load up the config and run the
|
12
|
-
# (3) Run watch -n0.2 'sudo ruby bin/
|
11
|
+
# (2) Load up the config and run the evented_bluepill daemon
|
12
|
+
# (3) Run watch -n0.2 'sudo ruby bin/evented_bluepill status 2>/dev/null; echo; ps ajxu | egrep "(CPU|forking|evented_bluepill|sleep|ruby)" | grep -v grep | sort'
|
13
13
|
# (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
|
14
14
|
# (5) Observe the worker being killed in the watch you started in step 3.
|
15
15
|
|
data/lib/bluepill.rb
CHANGED
@@ -1,34 +1,6 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
|
-
require '
|
3
|
+
STDERR.puts "*** DEPRECATION WARNING: require 'bluepill' and the Bluepill constant are deprecated. Please use require 'evented_bluepill' and the EventedBluepill constant instead ***"
|
4
4
|
|
5
|
-
require '
|
6
|
-
|
7
|
-
require 'timeout'
|
8
|
-
require 'logger'
|
9
|
-
|
10
|
-
require 'active_support/core_ext/numeric'
|
11
|
-
require 'active_support/core_ext/hash'
|
12
|
-
|
13
|
-
require 'bluepill/event'
|
14
|
-
require 'bluepill/application'
|
15
|
-
require 'bluepill/controller'
|
16
|
-
require 'bluepill/socket'
|
17
|
-
require "bluepill/process"
|
18
|
-
require "bluepill/process_statistics"
|
19
|
-
require "bluepill/group"
|
20
|
-
require "bluepill/logger"
|
21
|
-
require "bluepill/condition_watch"
|
22
|
-
require 'bluepill/trigger'
|
23
|
-
require 'bluepill/triggers/flapping'
|
24
|
-
require 'bluepill/dsl/process_factory'
|
25
|
-
require 'bluepill/dsl/process_proxy'
|
26
|
-
require 'bluepill/dsl/app_proxy'
|
27
|
-
require "bluepill/dsl"
|
28
|
-
require "bluepill/system"
|
29
|
-
|
30
|
-
require "bluepill/process_conditions"
|
31
|
-
|
32
|
-
require "bluepill/util/rotational_array"
|
33
|
-
|
34
|
-
require "bluepill/version"
|
5
|
+
require 'evented_bluepill'
|
6
|
+
Bluepill = EventedBluepill
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module EventedBluepill
|
4
|
+
module Application
|
5
|
+
module ServerMethods
|
6
|
+
|
7
|
+
def status
|
8
|
+
self.processes.collect do |process|
|
9
|
+
"#{process.name} #{process.state}"
|
10
|
+
end.join("\n")
|
11
|
+
end
|
12
|
+
|
13
|
+
def restart
|
14
|
+
self.socket = EventedBluepill::Socket.new(name, base_dir).client
|
15
|
+
socket.send("restart\n", 0)
|
16
|
+
end
|
17
|
+
|
18
|
+
def stop
|
19
|
+
self.socket = EventedBluepill::Socket.new(name, base_dir).client
|
20
|
+
socket.send("stop\n", 0)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
|
-
module
|
3
|
+
module EventedBluepill
|
4
4
|
class Application
|
5
5
|
PROCESS_COMMANDS = [:start, :stop, :restart, :unmonitor, :status]
|
6
6
|
|
@@ -13,13 +13,13 @@ module Bluepill
|
|
13
13
|
|
14
14
|
@foreground = options[:foreground]
|
15
15
|
self.log_file = options[:log_file]
|
16
|
-
self.base_dir = options[:base_dir] || '/var/
|
16
|
+
self.base_dir = options[:base_dir] || '/var/evented_bluepill'
|
17
17
|
self.pid_file = File.join(self.base_dir, 'pids', self.name + ".pid")
|
18
18
|
self.pids_dir = File.join(self.base_dir, 'pids', self.name)
|
19
19
|
|
20
20
|
self.groups = {}
|
21
21
|
|
22
|
-
self.logger =
|
22
|
+
self.logger = EventedBluepill::Logger.new(:log_file => self.log_file, :stdout => foreground?).prefix_with(self.name)
|
23
23
|
|
24
24
|
self.setup_signal_traps
|
25
25
|
self.setup_pids_dir
|
@@ -33,7 +33,7 @@ module Bluepill
|
|
33
33
|
begin
|
34
34
|
self.start_server
|
35
35
|
rescue StandardError => e
|
36
|
-
$stderr.puts "Failed to start
|
36
|
+
$stderr.puts "Failed to start evented_bluepill:"
|
37
37
|
$stderr.puts "%s `%s`" % [e.class.name, e.message]
|
38
38
|
$stderr.puts e.backtrace
|
39
39
|
exit(5)
|
@@ -56,7 +56,7 @@ module Bluepill
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def version
|
59
|
-
|
59
|
+
EventedBluepill::VERSION::STRING
|
60
60
|
end
|
61
61
|
|
62
62
|
protected
|
@@ -91,23 +91,23 @@ module Bluepill
|
|
91
91
|
self.groups.each {|_, group| group.determine_initial_state }
|
92
92
|
|
93
93
|
self.write_pid_file
|
94
|
-
self.cmd_listener =
|
95
|
-
|
96
|
-
|
94
|
+
self.cmd_listener = EventedBluepill::Socket.server(self.base_dir, self.name, self)
|
95
|
+
EventedBluepill::Event.attach(self.cmd_listener)
|
96
|
+
EventedBluepill::Event.run
|
97
97
|
|
98
98
|
cleanup
|
99
99
|
end
|
100
100
|
|
101
101
|
def cleanup
|
102
102
|
# TODO ugly
|
103
|
-
File.unlink(
|
103
|
+
File.unlink(EventedBluepill::Socket.socket_path(self.base_dir, self.name)) if self.cmd_listener
|
104
104
|
File.unlink(self.pid_file) if File.exists?(self.pid_file)
|
105
105
|
end
|
106
106
|
|
107
107
|
def setup_signal_traps
|
108
108
|
terminator = Proc.new do
|
109
109
|
puts "Terminating..."
|
110
|
-
|
110
|
+
EventedBluepill::Event.stop
|
111
111
|
end
|
112
112
|
|
113
113
|
Signal.trap("TERM", &terminator)
|
@@ -121,7 +121,7 @@ module Bluepill
|
|
121
121
|
def setup_pids_dir
|
122
122
|
FileUtils.mkdir_p(self.pids_dir) unless File.exists?(self.pids_dir)
|
123
123
|
# we need everybody to be able to write to the pids_dir as processes managed by
|
124
|
-
#
|
124
|
+
# evented_bluepill will be writing to this dir after they've dropped privileges
|
125
125
|
FileUtils.chmod(0777, self.pids_dir)
|
126
126
|
end
|
127
127
|
|
@@ -131,10 +131,10 @@ module Bluepill
|
|
131
131
|
if System.pid_alive?(previous_pid)
|
132
132
|
begin
|
133
133
|
::Process.kill(0, previous_pid)
|
134
|
-
puts "Killing previous
|
134
|
+
puts "Killing previous evented_bluepilld[#{previous_pid}]"
|
135
135
|
::Process.kill(2, previous_pid)
|
136
136
|
rescue Exception => e
|
137
|
-
$stderr.puts "Encountered error trying to kill previous
|
137
|
+
$stderr.puts "Encountered error trying to kill previous evented_bluepill:"
|
138
138
|
$stderr.puts "#{e.class}: #{e.message}"
|
139
139
|
exit(4) unless e.is_a?(Errno::ESRCH)
|
140
140
|
else
|
@@ -144,7 +144,7 @@ module Bluepill
|
|
144
144
|
end
|
145
145
|
|
146
146
|
if System.pid_alive?(previous_pid)
|
147
|
-
$stderr.puts "Previous
|
147
|
+
$stderr.puts "Previous evented_bluepilld[#{previous_pid}] didn't die"
|
148
148
|
exit(4)
|
149
149
|
end
|
150
150
|
end
|