bluepill 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- data/DESIGN.markdown +10 -0
- data/README.markdown +149 -0
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/bluepill.gemspec +12 -11
- metadata +17 -9
- data/README +0 -0
- data/README.rdoc +0 -18
- data/TODO +0 -22
data/DESIGN.markdown
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/README.markdown
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
# Bluepill
|
2
|
+
Bluepill is a simple process monitoring tool written in Ruby.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
It's hosted on [gemcutter.org][gemcutter].
|
6
|
+
|
7
|
+
sudo gem install bluepill
|
8
|
+
|
9
|
+
In order to take advantage of logging, 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
|
+
|
11
|
+
local6.* /var/log/bluepill.log
|
12
|
+
|
13
|
+
You'll also want to add _/var/log/bluepill.log_ to _/etc/logrotate.d/syslog_ so that it gets rotated.
|
14
|
+
|
15
|
+
Lastly, create the _/var/bluepill_ directory for bluepill to store its pid and sock files.
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
### DSL
|
19
|
+
Bluepill organizes processes into 3 levels: application -> group -> process. Each process has a few attributes that tell 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
|
+
|
21
|
+
The minimum config file looks something like this:
|
22
|
+
|
23
|
+
Bluepill.application("app_name") do |app|
|
24
|
+
app.process("process_name") do |process|
|
25
|
+
process.start_command = "/usr/bin/some_start_command"
|
26
|
+
process.pid_file = "/tmp/some_pid_file.pid"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Note that since we specified a PID file and start command, bluepill assumes the process will daemonize itself. If we wanted bluepill to daemonize it for us, we can do:
|
31
|
+
|
32
|
+
Bluepill.application("app_name") do |app|
|
33
|
+
app.process("process_name") do |process|
|
34
|
+
process.start_command = "/usr/bin/some_start_command"
|
35
|
+
process.daemonize = true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
If you don't specify a stop command, a TERM signal will be sent by default. Similarly, the default restart action is to issue stop and then start.
|
40
|
+
|
41
|
+
Now if we want to do something more meaningful, like actually monitor the process, we do:
|
42
|
+
|
43
|
+
Bluepill.application("app_name") do |app|
|
44
|
+
app.process("process_name") do |process|
|
45
|
+
process.start_command = "/usr/bin/some_start_command"
|
46
|
+
process.pid_file = "/tmp/some_pid_file.pid"
|
47
|
+
|
48
|
+
process.checks :cpu_usage, :every => 10.seconds, :below => 5, :times => 3
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
We added a line that checks every 10 seconds to make sure the cpu usage of this process is below 5 percent; 3 failed checks results in a restart. We can specify a two-element array for the _times_ option to say that it 3 out of 5 failed attempts results in a restart.
|
53
|
+
|
54
|
+
To watch memory usage, we just add one more line:
|
55
|
+
|
56
|
+
Bluepill.application("app_name") do |app|
|
57
|
+
app.process("process_name") do |process|
|
58
|
+
process.start_command = "/usr/bin/some_start_command"
|
59
|
+
process.pid_file = "/tmp/some_pid_file.pid"
|
60
|
+
|
61
|
+
process.checks :cpu_usage, :every => 10.seconds, :below => 5, :times => 3
|
62
|
+
process.checks :mem_usage, :every => 10.seconds, :below => 100.megabytes, :times => [3,5]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
We can tell bluepill to give a process some grace time to start/stop/restart before resuming monitoring:
|
67
|
+
|
68
|
+
Bluepill.application("app_name") do |app|
|
69
|
+
app.process("process_name") do |process|
|
70
|
+
process.start_command = "/usr/bin/some_start_command"
|
71
|
+
process.pid_file = "/tmp/some_pid_file.pid"
|
72
|
+
process.start_grace_time = 3.seconds
|
73
|
+
process.stop_grace_time = 5.seconds
|
74
|
+
process.restart_grace_time = 8.seconds
|
75
|
+
|
76
|
+
process.checks :cpu_usage, :every => 10.seconds, :below => 5, :times => 3
|
77
|
+
process.checks :mem_usage, :every => 10.seconds, :below => 100.megabytes, :times => [3,5]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
We can group processes by name:
|
82
|
+
|
83
|
+
Bluepill.application("app_name") do |app|
|
84
|
+
5.times do |i|
|
85
|
+
app.process("process_name_#{i}") do |process|
|
86
|
+
process.group = "mongrels"
|
87
|
+
process.start_command = "/usr/bin/some_start_command"
|
88
|
+
process.pid_file = "/tmp/some_pid_file.pid"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
If you want to run the process as someone other than root:
|
94
|
+
|
95
|
+
Bluepill.application("app_name") do |app|
|
96
|
+
app.process("process_name") do |process|
|
97
|
+
process.start_command = "/usr/bin/some_start_command"
|
98
|
+
process.pid_file = "/tmp/some_pid_file.pid"
|
99
|
+
process.uid = "deploy"
|
100
|
+
process.gid = "deploy"
|
101
|
+
|
102
|
+
process.checks :cpu_usage, :every => 10.seconds, :below => 5, :times => 3
|
103
|
+
process.checks :mem_usage, :every => 10.seconds, :below => 100.megabytes, :times => [3,5]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
To check for flapping:
|
108
|
+
|
109
|
+
process.checks :flapping, :times => 2, :within => 30.seconds, :retry_in => 7.seconds
|
110
|
+
|
111
|
+
And lastly, to monitor child processes:
|
112
|
+
|
113
|
+
process.monitor_children do |child_process|
|
114
|
+
child_process.checks :cpu_usage, :every => 10, :below => 5, :times => 3
|
115
|
+
child_process.checks :mem_usage, :every => 10, :below => 100.megabytes, :times => [3, 5]
|
116
|
+
|
117
|
+
child_process.stop_command = "kill -QUIT {{PID}}"
|
118
|
+
end
|
119
|
+
|
120
|
+
Note {{PID}} will be substituted for the pid of process in both the stop and restart commands.
|
121
|
+
|
122
|
+
### CLI
|
123
|
+
To start a bluepill process and load a config:
|
124
|
+
|
125
|
+
sudo bluepill load /path/to/production.pill
|
126
|
+
|
127
|
+
To act on a process or group:
|
128
|
+
|
129
|
+
sudo bluepill <start|stop|restart|unmonitor> <process_or_group_name>
|
130
|
+
|
131
|
+
To view process statuses:
|
132
|
+
|
133
|
+
sudo bluepill status
|
134
|
+
|
135
|
+
To view the log for a process or group:
|
136
|
+
|
137
|
+
sudo bluepill log <process_or_group_name>
|
138
|
+
|
139
|
+
To quit bluepill:
|
140
|
+
|
141
|
+
sudo bluepill quit
|
142
|
+
|
143
|
+
## Contribute
|
144
|
+
Code: [http://github.com/arya/bluepill](http://github.com/arya/bluepill)
|
145
|
+
Bugs/Features: [http://github.com/arya/bluepill/issues](http://github.com/arya/bluepill/issues)
|
146
|
+
|
147
|
+
|
148
|
+
[gemcutter]: http://gemcutter.org
|
149
|
+
|
data/Rakefile
CHANGED
@@ -13,7 +13,8 @@ begin
|
|
13
13
|
gem.add_development_dependency "rspec"
|
14
14
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
15
|
gem.add_dependency("daemons", ">= 1.0.9")
|
16
|
-
gem.add_dependency("
|
16
|
+
gem.add_dependency("blankslate", ">= 2.1.2.2")
|
17
|
+
gem.add_dependency("state_machine", ">= 0.8.0")
|
17
18
|
gem.add_dependency("activesupport", ">= 2.3.4")
|
18
19
|
|
19
20
|
gem.files -= ["bin/sample_forking_server"]
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.11
|
data/bluepill.gemspec
CHANGED
@@ -5,28 +5,26 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bluepill}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.11"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Arya Asemanfar", "Gary Tsang", "Rohith Ravi"]
|
12
|
-
s.date = %q{2009-
|
12
|
+
s.date = %q{2009-11-03}
|
13
13
|
s.default_executable = %q{bluepill}
|
14
14
|
s.description = %q{Bluepill 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.}
|
15
15
|
s.email = %q{entombedvirus@gmail.com}
|
16
16
|
s.executables = ["bluepill"]
|
17
17
|
s.extra_rdoc_files = [
|
18
18
|
"LICENSE",
|
19
|
-
"README"
|
20
|
-
"README.rdoc"
|
19
|
+
"README.markdown"
|
21
20
|
]
|
22
21
|
s.files = [
|
23
22
|
".document",
|
24
23
|
".gitignore",
|
24
|
+
"DESIGN.markdown",
|
25
25
|
"LICENSE",
|
26
|
-
"README",
|
27
|
-
"README.rdoc",
|
26
|
+
"README.markdown",
|
28
27
|
"Rakefile",
|
29
|
-
"TODO",
|
30
28
|
"VERSION",
|
31
29
|
"bin/bluepill",
|
32
30
|
"bluepill.gemspec",
|
@@ -59,7 +57,7 @@ Gem::Specification.new do |s|
|
|
59
57
|
s.homepage = %q{http://github.com/arya/bluepill}
|
60
58
|
s.rdoc_options = ["--charset=UTF-8"]
|
61
59
|
s.require_paths = ["lib"]
|
62
|
-
s.rubygems_version = %q{1.3.
|
60
|
+
s.rubygems_version = %q{1.3.4}
|
63
61
|
s.summary = %q{A process monitor written in Ruby with stability and minimalism in mind.}
|
64
62
|
s.test_files = [
|
65
63
|
"spec/blue-pill_spec.rb",
|
@@ -74,18 +72,21 @@ Gem::Specification.new do |s|
|
|
74
72
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
75
73
|
s.add_development_dependency(%q<rspec>, [">= 0"])
|
76
74
|
s.add_runtime_dependency(%q<daemons>, [">= 1.0.9"])
|
77
|
-
s.add_runtime_dependency(%q<
|
75
|
+
s.add_runtime_dependency(%q<blankslate>, [">= 2.1.2.2"])
|
76
|
+
s.add_runtime_dependency(%q<state_machine>, [">= 0.8.0"])
|
78
77
|
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.4"])
|
79
78
|
else
|
80
79
|
s.add_dependency(%q<rspec>, [">= 0"])
|
81
80
|
s.add_dependency(%q<daemons>, [">= 1.0.9"])
|
82
|
-
s.add_dependency(%q<
|
81
|
+
s.add_dependency(%q<blankslate>, [">= 2.1.2.2"])
|
82
|
+
s.add_dependency(%q<state_machine>, [">= 0.8.0"])
|
83
83
|
s.add_dependency(%q<activesupport>, [">= 2.3.4"])
|
84
84
|
end
|
85
85
|
else
|
86
86
|
s.add_dependency(%q<rspec>, [">= 0"])
|
87
87
|
s.add_dependency(%q<daemons>, [">= 1.0.9"])
|
88
|
-
s.add_dependency(%q<
|
88
|
+
s.add_dependency(%q<blankslate>, [">= 2.1.2.2"])
|
89
|
+
s.add_dependency(%q<state_machine>, [">= 0.8.0"])
|
89
90
|
s.add_dependency(%q<activesupport>, [">= 2.3.4"])
|
90
91
|
end
|
91
92
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bluepill
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arya Asemanfar
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2009-
|
14
|
+
date: 2009-11-03 00:00:00 -08:00
|
15
15
|
default_executable: bluepill
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
@@ -35,7 +35,17 @@ dependencies:
|
|
35
35
|
version: 1.0.9
|
36
36
|
version:
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
|
-
name:
|
38
|
+
name: blankslate
|
39
|
+
type: :runtime
|
40
|
+
version_requirement:
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.1.2.2
|
46
|
+
version:
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: state_machine
|
39
49
|
type: :runtime
|
40
50
|
version_requirement:
|
41
51
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -62,16 +72,14 @@ extensions: []
|
|
62
72
|
|
63
73
|
extra_rdoc_files:
|
64
74
|
- LICENSE
|
65
|
-
- README
|
66
|
-
- README.rdoc
|
75
|
+
- README.markdown
|
67
76
|
files:
|
68
77
|
- .document
|
69
78
|
- .gitignore
|
79
|
+
- DESIGN.markdown
|
70
80
|
- LICENSE
|
71
|
-
- README
|
72
|
-
- README.rdoc
|
81
|
+
- README.markdown
|
73
82
|
- Rakefile
|
74
|
-
- TODO
|
75
83
|
- VERSION
|
76
84
|
- bin/bluepill
|
77
85
|
- bluepill.gemspec
|
@@ -124,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
132
|
requirements: []
|
125
133
|
|
126
134
|
rubyforge_project:
|
127
|
-
rubygems_version: 1.3.
|
135
|
+
rubygems_version: 1.3.4
|
128
136
|
signing_key:
|
129
137
|
specification_version: 3
|
130
138
|
summary: A process monitor written in Ruby with stability and minimalism in mind.
|
data/README
DELETED
File without changes
|
data/README.rdoc
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
= little-blue-pill
|
2
|
-
|
3
|
-
Description goes here.
|
4
|
-
|
5
|
-
== Note on Patches/Pull Requests
|
6
|
-
|
7
|
-
* Fork the project.
|
8
|
-
* Make your feature addition or bug fix.
|
9
|
-
* Add tests for it. This is important so I don't break it in a
|
10
|
-
future version unintentionally.
|
11
|
-
* Commit, do not mess with rakefile, version, or history.
|
12
|
-
(if you want to have your own version, that is fine but
|
13
|
-
bump version in a commit by itself I can ignore when I pull)
|
14
|
-
* Send me a pull request. Bonus points for topic branches.
|
15
|
-
|
16
|
-
== Copyright
|
17
|
-
|
18
|
-
Copyright (c) 2009 garru. See LICENSE for details.
|
data/TODO
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
* Figure out proper logger lvl for each msg. So a person can choose only to log local6.warn and get only state transition messages and not any of the watch chatter.
|
2
|
-
* Better error output than just vanilla exception traces
|
3
|
-
* Better output for cli commands than just "ok"
|
4
|
-
* munin support?
|
5
|
-
|
6
|
-
|
7
|
-
Issues encountered in the wild
|
8
|
-
------------------------------
|
9
|
-
|
10
|
-
* Whenever bluepill executes user specified commands (like start_command, stop_command, restart_command), it should execute it in such a way that it does not affect the stability of bluepill daemon itself.
|
11
|
-
|
12
|
-
* Whenever a command is sent to a process group, execute them in parallel for each process in the group instead of serially.
|
13
|
-
|
14
|
-
* Issuing commands to the running bluepill daemon using the cli can trigger flapping condition. So, running bluepill restart <blah> can cause a flapping trigger to be fired depending on internal state.
|
15
|
-
|
16
|
-
* Have validations for easy to make mistakes in the config file. For ex:
|
17
|
-
+ Accidently specifying the same pid file for multiple processes.
|
18
|
-
+ Accidently specifying the same process name for multiple processes.
|
19
|
-
+ Validate the minimum number of config options to setup successful monitoring.
|
20
|
-
|
21
|
-
For example, for a valid "process", the only 2 things that are required are the start command and the pid file. We should tell a user at the time of loading whether the config file is syntactically and semantically valid.
|
22
|
-
|