bluepill 0.0.63 → 0.0.64
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +13 -0
- data/bin/bluepill +2 -1
- data/bluepill.gemspec +1 -1
- data/lib/bluepill/application.rb +3 -1
- data/lib/bluepill/process.rb +1 -1
- data/lib/bluepill/process_conditions/running_time.rb +18 -0
- data/lib/bluepill/system.rb +23 -3
- data/lib/bluepill/version.rb +1 -1
- data/local-bluepill +3 -2
- data/spec/lib/bluepill/application_spec.rb +31 -0
- data/spec/lib/bluepill/system_spec.rb +9 -0
- data/spec/spec_helper.rb +6 -0
- metadata +9 -6
data/README.md
CHANGED
@@ -87,6 +87,19 @@ To watch the modification time of a file, e.g. a log file to ensure the process
|
|
87
87
|
end
|
88
88
|
```
|
89
89
|
|
90
|
+
To restart process if it's running too long:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
Bluepill.application("app_name") do |app|
|
94
|
+
app.process("process_name") do |process|
|
95
|
+
process.start_command = "/usr/bin/some_start_command"
|
96
|
+
process.pid_file = "/tmp/some_pid_file.pid"
|
97
|
+
|
98
|
+
process.checks :running_time, :every => 10.minutes, :below => 24.hours
|
99
|
+
end
|
100
|
+
end
|
101
|
+
```
|
102
|
+
|
90
103
|
|
91
104
|
|
92
105
|
We can tell bluepill to give a process some grace time to start/stop/restart before resuming monitoring:
|
data/bin/bluepill
CHANGED
@@ -12,7 +12,7 @@ RbConfig = Config unless Object.const_defined?(:RbConfig)
|
|
12
12
|
# Default options
|
13
13
|
options = {
|
14
14
|
:log_file => "/var/log/bluepill.log",
|
15
|
-
:base_dir => "/var/run/bluepill",
|
15
|
+
:base_dir => ENV['BLUEPILL_BASE_DIR'] || (::Process.euid != 0 ? File.join(ENV['HOME'], '.bluepill') : "/var/run/bluepill"),
|
16
16
|
:privileged => true,
|
17
17
|
:timeout => 10,
|
18
18
|
:attempts => 1
|
@@ -111,6 +111,7 @@ if options[:command] == "load"
|
|
111
111
|
ruby = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
|
112
112
|
load_path = File.expand_path("#{File.dirname(__FILE__)}/../lib")
|
113
113
|
file_path = File.expand_path(file)
|
114
|
+
ENV['BLUEPILL_BASE_DIR'] = options[:base_dir]
|
114
115
|
|
115
116
|
exec(ruby, "-I#{load_path}", '-rbluepill', file_path)
|
116
117
|
|
data/bluepill.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
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.}
|
16
16
|
|
17
17
|
s.add_dependency 'daemons', ['~> 1.1.4']
|
18
|
-
s.add_dependency 'state_machine', '~> 1.1
|
18
|
+
s.add_dependency 'state_machine', '~> 1.1'
|
19
19
|
s.add_dependency 'activesupport', '>= 3.0.0'
|
20
20
|
s.add_dependency 'i18n', '>= 0.5.0'
|
21
21
|
|
data/lib/bluepill/application.rb
CHANGED
@@ -16,7 +16,9 @@ module Bluepill
|
|
16
16
|
|
17
17
|
@foreground = options[:foreground]
|
18
18
|
self.log_file = options[:log_file]
|
19
|
-
self.base_dir = ProcessJournal.base_dir = options[:base_dir] ||
|
19
|
+
self.base_dir = ProcessJournal.base_dir = options[:base_dir] ||
|
20
|
+
ENV['BLUEPILL_BASE_DIR'] ||
|
21
|
+
(::Process.euid != 0 ? File.join(ENV['HOME'], '.bluepill') : "/var/run/bluepill")
|
20
22
|
self.pid_file = File.join(self.base_dir, 'pids', self.name + ".pid")
|
21
23
|
self.pids_dir = File.join(self.base_dir, 'pids', self.name)
|
22
24
|
self.kill_timeout = options[:kill_timeout] || 10
|
data/lib/bluepill/process.rb
CHANGED
@@ -281,7 +281,7 @@ module Bluepill
|
|
281
281
|
logger.warning "Executing start command: #{start_command}"
|
282
282
|
if self.daemonize?
|
283
283
|
daemon_id = System.daemonize(start_command, self.system_command_options)
|
284
|
-
if daemon_id
|
284
|
+
if daemon_id
|
285
285
|
ProcessJournal.append_pid_to_journal(name, daemon_id)
|
286
286
|
children.each {|child|
|
287
287
|
ProcessJournal.append_pid_to_journal(name, child.actual_id)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module Bluepill
|
3
|
+
module ProcessConditions
|
4
|
+
class RunningTime < ProcessCondition
|
5
|
+
def initialize(options = {})
|
6
|
+
@below = options[:below]
|
7
|
+
end
|
8
|
+
|
9
|
+
def run(pid, include_children)
|
10
|
+
System.running_time(pid)
|
11
|
+
end
|
12
|
+
|
13
|
+
def check(value)
|
14
|
+
value < @below
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/bluepill/system.rb
CHANGED
@@ -14,7 +14,8 @@ module Bluepill
|
|
14
14
|
:pid => 0,
|
15
15
|
:ppid => 1,
|
16
16
|
:pcpu => 2,
|
17
|
-
:rss => 3
|
17
|
+
:rss => 3,
|
18
|
+
:etime => 4
|
18
19
|
}
|
19
20
|
|
20
21
|
def pid_alive?(pid)
|
@@ -48,6 +49,12 @@ module Bluepill
|
|
48
49
|
mem_used
|
49
50
|
end
|
50
51
|
|
52
|
+
def running_time(pid)
|
53
|
+
ps = ps_axu
|
54
|
+
return unless ps[pid]
|
55
|
+
parse_elapsed_time(ps[pid][IDX_MAP[:etime]])
|
56
|
+
end
|
57
|
+
|
51
58
|
def get_children(parent_pid)
|
52
59
|
child_pids = Array.new
|
53
60
|
ps_axu.each_pair do |pid, chunks|
|
@@ -189,7 +196,7 @@ module Bluepill
|
|
189
196
|
wr.write Marshal.dump(result)
|
190
197
|
wr.close
|
191
198
|
|
192
|
-
exit
|
199
|
+
::Process.exit!
|
193
200
|
end
|
194
201
|
end
|
195
202
|
|
@@ -205,7 +212,7 @@ module Bluepill
|
|
205
212
|
# TODO: need a mutex here
|
206
213
|
store[:ps_axu] ||= begin
|
207
214
|
# BSD style ps invocation
|
208
|
-
lines = `ps axo pid,ppid,pcpu,rss`.split("\n")
|
215
|
+
lines = `ps axo pid,ppid,pcpu,rss,etime`.split("\n")
|
209
216
|
|
210
217
|
lines.inject(Hash.new) do |mem, line|
|
211
218
|
chunks = line.split(/\s+/)
|
@@ -217,6 +224,19 @@ module Bluepill
|
|
217
224
|
end
|
218
225
|
end
|
219
226
|
|
227
|
+
def parse_elapsed_time(str)
|
228
|
+
# [[dd-]hh:]mm:ss
|
229
|
+
if str =~ /(?:(?:(\d+)-)?(\d\d):)?(\d\d):(\d\d)/
|
230
|
+
days = ($1 || 0).to_i
|
231
|
+
hours = ($2 || 0).to_i
|
232
|
+
mins = $3.to_i
|
233
|
+
secs = $4.to_i
|
234
|
+
((days*24 + hours)*60 + mins)*60 + secs
|
235
|
+
else
|
236
|
+
0
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
220
240
|
# be sure to call this from a fork otherwise it will modify the attributes
|
221
241
|
# of the bluepill daemon
|
222
242
|
def drop_privileges(uid, gid, supplementary_groups)
|
data/lib/bluepill/version.rb
CHANGED
data/local-bluepill
CHANGED
@@ -17,7 +17,7 @@ RbConfig = Config unless Object.const_defined?(:RbConfig)
|
|
17
17
|
# Default options
|
18
18
|
options = {
|
19
19
|
:log_file => "/var/log/bluepill.log",
|
20
|
-
:base_dir => "/var/run/bluepill",
|
20
|
+
:base_dir => ENV['BLUEPILL_BASE_DIR'] || (::Process.euid != 0 ? File.join(ENV['HOME'], '.bluepill') : "/var/run/bluepill"),
|
21
21
|
:privileged => true,
|
22
22
|
:timeout => 10,
|
23
23
|
:attempts => 1
|
@@ -114,8 +114,9 @@ if options[:command] == "load"
|
|
114
114
|
# Restart the ruby interpreter for the config file so that anything loaded here
|
115
115
|
# does not stay in memory for the daemon
|
116
116
|
ruby = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
|
117
|
-
load_path = File.expand_path("#{File.dirname(__FILE__)}
|
117
|
+
load_path = File.expand_path("#{File.dirname(__FILE__)}/lib")
|
118
118
|
file_path = File.expand_path(file)
|
119
|
+
ENV['BLUEPILL_BASE_DIR'] = options[:base_dir]
|
119
120
|
|
120
121
|
exec(ruby, "-I#{load_path}", '-rbluepill', file_path)
|
121
122
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
describe Bluepill::Application do
|
2
|
+
describe "#initialize" do
|
3
|
+
let(:options){ {} }
|
4
|
+
subject {described_class.new('test', options)}
|
5
|
+
before(:each) {described_class.any_instance.should_receive(:setup_pids_dir)}
|
6
|
+
|
7
|
+
context "when euid is not root" do
|
8
|
+
before(:each) {::Process.stub(:euid).and_return(1)}
|
9
|
+
its(:base_dir){ should eq(File.join(ENV['HOME'], '.bluepill')) }
|
10
|
+
end
|
11
|
+
context "when euid is root" do
|
12
|
+
before(:each) {::Process.stub(:euid).and_return(0)}
|
13
|
+
its(:base_dir) { should eq('/var/run/bluepill') }
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when option base_dir is specified" do
|
17
|
+
let(:options) { {:base_dir=>'/var/bluepill'} }
|
18
|
+
its(:base_dir) { should eq(options[:base_dir]) }
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when environment BLUEPILL_BASE_DIR is specified" do
|
22
|
+
before(:each) {ENV['BLUEPILL_BASE_DIR'] = '/bluepill'}
|
23
|
+
its(:base_dir) { should eq(ENV['BLUEPILL_BASE_DIR']) }
|
24
|
+
|
25
|
+
context "and option base_dir is specified" do
|
26
|
+
let(:options) { {:base_dir=>'/var/bluepill'} }
|
27
|
+
its(:base_dir) { should eq(options[:base_dir]) }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -33,4 +33,13 @@ describe Bluepill::System do
|
|
33
33
|
Bluepill::System.store.should be_empty
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
describe :parse_etime do
|
38
|
+
it "should parse etime format" do
|
39
|
+
Bluepill::System.parse_elapsed_time("400-00:04:01").should be_equal(34560241)
|
40
|
+
Bluepill::System.parse_elapsed_time("02:04:02").should be_equal(7442)
|
41
|
+
Bluepill::System.parse_elapsed_time("20:03").should be_equal(1203)
|
42
|
+
Bluepill::System.parse_elapsed_time("invalid").should be_equal(0)
|
43
|
+
end
|
44
|
+
end
|
36
45
|
end
|
data/spec/spec_helper.rb
CHANGED
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.64
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-
|
14
|
+
date: 2013-05-29 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: daemons
|
@@ -36,7 +36,7 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - ~>
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: 1.1
|
39
|
+
version: '1.1'
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 1.1
|
47
|
+
version: '1.1'
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: activesupport
|
50
50
|
requirement: !ruby/object:Gem::Requirement
|
@@ -207,6 +207,7 @@ files:
|
|
207
207
|
- lib/bluepill/process_conditions/http.rb
|
208
208
|
- lib/bluepill/process_conditions/mem_usage.rb
|
209
209
|
- lib/bluepill/process_conditions/process_condition.rb
|
210
|
+
- lib/bluepill/process_conditions/running_time.rb
|
210
211
|
- lib/bluepill/process_journal.rb
|
211
212
|
- lib/bluepill/process_statistics.rb
|
212
213
|
- lib/bluepill/socket.rb
|
@@ -216,6 +217,7 @@ files:
|
|
216
217
|
- lib/bluepill/util/rotational_array.rb
|
217
218
|
- lib/bluepill/version.rb
|
218
219
|
- local-bluepill
|
220
|
+
- spec/lib/bluepill/application_spec.rb
|
219
221
|
- spec/lib/bluepill/logger_spec.rb
|
220
222
|
- spec/lib/bluepill/process_spec.rb
|
221
223
|
- spec/lib/bluepill/process_statistics_spec.rb
|
@@ -235,7 +237,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
235
237
|
version: '0'
|
236
238
|
segments:
|
237
239
|
- 0
|
238
|
-
hash:
|
240
|
+
hash: -2865814049117051220
|
239
241
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
240
242
|
none: false
|
241
243
|
requirements:
|
@@ -244,7 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
244
246
|
version: '0'
|
245
247
|
segments:
|
246
248
|
- 0
|
247
|
-
hash:
|
249
|
+
hash: -2865814049117051220
|
248
250
|
requirements: []
|
249
251
|
rubyforge_project:
|
250
252
|
rubygems_version: 1.8.24
|
@@ -252,6 +254,7 @@ signing_key:
|
|
252
254
|
specification_version: 3
|
253
255
|
summary: A process monitor written in Ruby with stability and minimalism in mind.
|
254
256
|
test_files:
|
257
|
+
- spec/lib/bluepill/application_spec.rb
|
255
258
|
- spec/lib/bluepill/logger_spec.rb
|
256
259
|
- spec/lib/bluepill/process_spec.rb
|
257
260
|
- spec/lib/bluepill/process_statistics_spec.rb
|