bluepill 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/TODO +2 -3
- data/VERSION +1 -1
- data/bluepill.gemspec +3 -2
- data/lib/bluepill.rb +2 -0
- data/lib/bluepill/application.rb +9 -7
- data/lib/bluepill/process.rb +10 -5
- data/lib/bluepill/process_conditions/cpu_usage.rb +2 -1
- data/lib/bluepill/process_conditions/mem_usage.rb +2 -1
- data/lib/bluepill/system.rb +32 -0
- data/lib/bluepill/trigger.rb +9 -4
- data/lib/bluepill/triggers/flapping.rb +5 -2
- data/lib/example.rb +3 -3
- metadata +3 -2
data/TODO
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
* Flap detection
|
2
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.
|
3
|
-
* Proper implementation of the cpu and mem watches. Possibly not forking to use ps ax?
|
4
2
|
* Better error output than just vanilla exception traces
|
5
3
|
* Better output for cli commands than just "ok"
|
6
4
|
* munin support?
|
@@ -10,4 +8,5 @@ Issues encountered in the wild
|
|
10
8
|
------------------------------
|
11
9
|
|
12
10
|
1. There were weird dependencies on xml-simple and builder gems when you try to use the bluepill cli.
|
13
|
-
|
11
|
+
2. 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.
|
12
|
+
3. Whenever a command is sent to a process group, execute them in parallel for each process in the group instead of serially.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.5
|
data/bluepill.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
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.5"
|
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-10-
|
12
|
+
s.date = %q{2009-10-14}
|
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}
|
@@ -47,6 +47,7 @@ Gem::Specification.new do |s|
|
|
47
47
|
"lib/bluepill/process_conditions/mem_usage.rb",
|
48
48
|
"lib/bluepill/process_conditions/process_condition.rb",
|
49
49
|
"lib/bluepill/socket.rb",
|
50
|
+
"lib/bluepill/system.rb",
|
50
51
|
"lib/bluepill/trigger.rb",
|
51
52
|
"lib/bluepill/triggers/flapping.rb",
|
52
53
|
"lib/bluepill/util/rotational_array.rb",
|
data/lib/bluepill.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
|
3
3
|
require 'thread'
|
4
|
+
require 'monitor'
|
4
5
|
require 'syslog'
|
5
6
|
|
6
7
|
require 'active_support/inflector'
|
@@ -18,6 +19,7 @@ require "bluepill/condition_watch"
|
|
18
19
|
require 'bluepill/trigger'
|
19
20
|
require 'bluepill/triggers/flapping'
|
20
21
|
require "bluepill/dsl"
|
22
|
+
require "bluepill/system"
|
21
23
|
|
22
24
|
require "bluepill/process_conditions"
|
23
25
|
|
data/lib/bluepill/application.rb
CHANGED
@@ -107,13 +107,13 @@ private
|
|
107
107
|
Thread.new(self) do |app|
|
108
108
|
begin
|
109
109
|
loop do
|
110
|
-
logger.info("Server | Command loop started:")
|
110
|
+
# logger.info("Server | Command loop started:")
|
111
111
|
client = socket.accept
|
112
|
-
logger.info("Server: Handling Request")
|
112
|
+
# logger.info("Server: Handling Request")
|
113
113
|
cmd = client.readline.strip
|
114
|
-
logger.info("Server: #{cmd}")
|
114
|
+
# logger.info("Server: #{cmd}")
|
115
115
|
response = app.send(*cmd.split(":"))
|
116
|
-
logger.info("Server: Sending Response")
|
116
|
+
# logger.info("Server: Sending Response")
|
117
117
|
client.write(response)
|
118
118
|
client.close
|
119
119
|
end
|
@@ -126,11 +126,11 @@ private
|
|
126
126
|
def worker
|
127
127
|
Thread.new(self) do |app|
|
128
128
|
loop do
|
129
|
-
app.logger.info("Server | worker loop started:")
|
129
|
+
# app.logger.info("Server | worker loop started:")
|
130
130
|
job = self.work_queue.pop
|
131
|
-
app.logger.info("Server | worker job recieved:")
|
131
|
+
# app.logger.info("Server | worker job recieved:")
|
132
132
|
send_to_process_or_group(job[0], job[1], false)
|
133
|
-
app.logger.info("Server | worker job processed:")
|
133
|
+
# app.logger.info("Server | worker job processed:")
|
134
134
|
end
|
135
135
|
end
|
136
136
|
end
|
@@ -165,6 +165,8 @@ private
|
|
165
165
|
|
166
166
|
def run
|
167
167
|
loop do
|
168
|
+
System.reset_data
|
169
|
+
|
168
170
|
self.groups.each do |_, group|
|
169
171
|
group.tick
|
170
172
|
end
|
data/lib/bluepill/process.rb
CHANGED
@@ -20,7 +20,7 @@ module Bluepill
|
|
20
20
|
attr_accessor *CONFIGURABLE_ATTRIBUTES
|
21
21
|
|
22
22
|
state_machine :initial => :unmonitored do
|
23
|
-
state :unmonitored, :up, :down
|
23
|
+
state :unmonitored, :up, :down, :restarting
|
24
24
|
|
25
25
|
event :tick do
|
26
26
|
transition :unmonitored => :unmonitored
|
@@ -29,21 +29,24 @@ module Bluepill
|
|
29
29
|
transition :up => :down, :unless => :process_running?
|
30
30
|
|
31
31
|
transition :down => :up, :if => lambda {|process| process.process_running? || process.start_process }
|
32
|
+
|
33
|
+
transition :restarting => :up, :if => :process_running?
|
34
|
+
transition :restarting => :down, :unless => :process_running?
|
32
35
|
end
|
33
36
|
|
34
37
|
event :start do
|
35
38
|
transition :unmonitored => :up, :if => lambda {|process| process.process_running? || process.start_process }
|
36
|
-
transition :up => :up
|
39
|
+
transition [:restarting, :up] => :up
|
37
40
|
transition :down => :up, :if => :start_process
|
38
41
|
end
|
39
42
|
|
40
43
|
event :stop do
|
41
44
|
transition [:unmonitored, :down] => :unmonitored
|
42
|
-
transition :up => :unmonitored, :if => :stop_process
|
45
|
+
transition [:up, :restarting] => :unmonitored, :if => :stop_process
|
43
46
|
end
|
44
47
|
|
45
48
|
event :restart do
|
46
|
-
transition all => :
|
49
|
+
transition all => :restarting, :if => :restart_process
|
47
50
|
end
|
48
51
|
|
49
52
|
event :unmonitor do
|
@@ -63,7 +66,7 @@ module Bluepill
|
|
63
66
|
|
64
67
|
def initialize(process_name, options = {})
|
65
68
|
@name = process_name
|
66
|
-
@event_mutex =
|
69
|
+
@event_mutex = Monitor.new
|
67
70
|
@transition_history = Util::RotationalArray.new(10)
|
68
71
|
@watches = []
|
69
72
|
@triggers = []
|
@@ -205,6 +208,8 @@ module Bluepill
|
|
205
208
|
stop_process
|
206
209
|
start_process
|
207
210
|
end
|
211
|
+
|
212
|
+
true
|
208
213
|
end
|
209
214
|
|
210
215
|
def daemonize?
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "singleton"
|
2
|
+
module Bluepill
|
3
|
+
# This class represents the system that bluepill is running on.. It's mainly used to memoize
|
4
|
+
# results of running ps auxx etc so that every watch in the every process will not result in a fork
|
5
|
+
module System
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def store
|
9
|
+
@store ||= Hash.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def reset_data
|
13
|
+
store.clear unless store.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
def ps_axu
|
17
|
+
store[:ps_axu] ||= begin
|
18
|
+
# BSD style ps invocation
|
19
|
+
lines = `ps axu`.split("\n")
|
20
|
+
|
21
|
+
lines.inject(Hash.new) do |mem, line|
|
22
|
+
# There are 11 cols in the ps ax output. This keeps programs that use spaces in $0 in one chunk
|
23
|
+
chunks = line.split(/\s+/, 11)
|
24
|
+
pid = chunks[1].to_i
|
25
|
+
mem[pid] = chunks
|
26
|
+
|
27
|
+
mem
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/bluepill/trigger.rb
CHANGED
@@ -26,10 +26,15 @@ module Bluepill
|
|
26
26
|
|
27
27
|
def schedule_event(event, delay)
|
28
28
|
# TODO: maybe wrap this in a ScheduledEvent class with methods like cancel
|
29
|
-
Thread.new do
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
Thread.new(self) do |trigger|
|
30
|
+
begin
|
31
|
+
sleep delay.to_i
|
32
|
+
trigger.logger.info("Retrying from flapping")
|
33
|
+
trigger.process.dispatch!(event)
|
34
|
+
rescue Exception => e
|
35
|
+
trigger.logger.error(e)
|
36
|
+
trigger.logger.error(e.backtrace.join("\n"))
|
37
|
+
end
|
33
38
|
end
|
34
39
|
end
|
35
40
|
|
@@ -1,7 +1,10 @@
|
|
1
1
|
module Bluepill
|
2
2
|
module Triggers
|
3
3
|
class Flapping < Bluepill::Trigger
|
4
|
-
|
4
|
+
TRIGGER_STATES = [
|
5
|
+
[:up, :down],
|
6
|
+
[:up, :restarting]
|
7
|
+
]
|
5
8
|
|
6
9
|
PARAMS = [:times, :within, :retry_in]
|
7
10
|
|
@@ -20,7 +23,7 @@ module Bluepill
|
|
20
23
|
end
|
21
24
|
|
22
25
|
def notify(transition)
|
23
|
-
if [transition.from_name, transition.to_name]
|
26
|
+
if TRIGGER_STATES.include?([transition.from_name, transition.to_name])
|
24
27
|
self.timeline << Time.now.to_i
|
25
28
|
self.check_flapping
|
26
29
|
end
|
data/lib/example.rb
CHANGED
@@ -22,15 +22,15 @@ ROOT_DIR = "/tmp/bp"
|
|
22
22
|
Bluepill.application(:sample_app) do |app|
|
23
23
|
1.times do |i|
|
24
24
|
app.process("process_#{i}") do |process|
|
25
|
-
process.start_command = "sleep
|
25
|
+
process.start_command = "while true; do echo ''; sleep 0.01; done"
|
26
26
|
process.daemonize = true
|
27
27
|
process.pid_file = "#{ROOT_DIR}/pids/process_#{i}.pid"
|
28
28
|
process.uid = "admin"
|
29
29
|
process.gid = "staff"
|
30
30
|
|
31
31
|
|
32
|
-
|
33
|
-
process.checks :flapping, :times => 2, :within => 30, :retry_in =>
|
32
|
+
process.checks :cpu_usage, :every => 5, :below => 0.5, :times => [2, 5]
|
33
|
+
process.checks :flapping, :times => 2, :within => 30.seconds, :retry_in => 7.seconds
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
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.5
|
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-10-
|
14
|
+
date: 2009-10-14 00:00:00 -07:00
|
15
15
|
default_executable: bluepill
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- lib/bluepill/process_conditions/mem_usage.rb
|
93
93
|
- lib/bluepill/process_conditions/process_condition.rb
|
94
94
|
- lib/bluepill/socket.rb
|
95
|
+
- lib/bluepill/system.rb
|
95
96
|
- lib/bluepill/trigger.rb
|
96
97
|
- lib/bluepill/triggers/flapping.rb
|
97
98
|
- lib/bluepill/util/rotational_array.rb
|