bluepill 0.0.69 → 0.0.70
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -9
- data/bin/bluepill +5 -5
- data/bin/sample_forking_server +1 -1
- data/bluepill.gemspec +4 -5
- data/lib/bluepill/application.rb +1 -1
- data/lib/bluepill/condition_watch.rb +1 -2
- data/lib/bluepill/controller.rb +3 -3
- data/lib/bluepill/group.rb +1 -1
- data/lib/bluepill/process.rb +12 -12
- data/lib/bluepill/process_conditions/file_time.rb +1 -5
- data/lib/bluepill/process_conditions/http.rb +12 -10
- data/lib/bluepill/process_conditions/mem_usage.rb +3 -1
- data/lib/bluepill/process_journal.rb +5 -5
- data/lib/bluepill/process_statistics.rb +1 -1
- data/lib/bluepill/system.rb +4 -4
- data/lib/bluepill/version.rb +43 -1
- metadata +7 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca369ae6619f45191580eb53378cf3e05c6c9611
|
4
|
+
data.tar.gz: 31f9694d4caa9f1479b6ea2da3d327b7367cfaef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82a4ac380dbebf046006a4942e5bad1d9c9ce3213afd9480f04b85f749bf9f180e079b06cf581a03b6c8cbabcdcc64c68a9426b6e07be7df49bc0b80e85a2094
|
7
|
+
data.tar.gz: c42f5bcdb3436b435c2a1fc98ae84db35dcfe8c052b5808665a27fd29ceff39172dcdf66ec4f9e14e5611ff041a0d6ad171c979bb62bd24753dee8c69050570b
|
data/README.md
CHANGED
@@ -1,10 +1,17 @@
|
|
1
1
|
# Bluepill
|
2
2
|
Bluepill is a simple process monitoring tool written in Ruby.
|
3
3
|
|
4
|
-
[![
|
5
|
-
[![
|
6
|
-
[![
|
7
|
-
[![
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/bluepill.svg)][gem]
|
5
|
+
[![Build Status](https://travis-ci.org/bluepill-rb/bluepill.svg?branch=master)][travis]
|
6
|
+
[![Dependency Status](https://gemnasium.com/bluepill-rb/bluepill.svg)][gemnasium]
|
7
|
+
[![Code Climate](https://codeclimate.com/github/bluepill-rb/bluepill/badges/gpa.svg)][codeclimate]
|
8
|
+
[![Coverage Status](https://coveralls.io/repos/bluepill-rb/bluepill/badge.svg?branch=master&service=github)][coveralls]
|
9
|
+
|
10
|
+
[gem]: https://rubygems.org/gems/bluepill
|
11
|
+
[travis]: https://travis-ci.org/bluepill-rb/bluepill
|
12
|
+
[gemnasium]: https://gemnasium.com/bluepill-rb/bluepill
|
13
|
+
[codeclimate]: https://codeclimate.com/github/bluepill-rb/bluepill
|
14
|
+
[coveralls]: https://coveralls.io/github/bluepill-rb/bluepill?branch=master
|
8
15
|
|
9
16
|
## Installation
|
10
17
|
It's hosted on [rubygems.org][rubygems].
|
@@ -374,11 +381,9 @@ implementations:
|
|
374
381
|
* Ruby 1.9.3
|
375
382
|
* Ruby 2.0.0
|
376
383
|
* Ruby 2.1
|
377
|
-
*
|
378
|
-
*
|
379
|
-
|
380
|
-
[jruby]: http://jruby.org/
|
381
|
-
[rubinius]: http://rubini.us/
|
384
|
+
* Ruby 2.2
|
385
|
+
* JRuby 1.7
|
386
|
+
* JRuby 9.0.0.0
|
382
387
|
|
383
388
|
If something doesn't work on one of these interpreters, please open an issue.
|
384
389
|
|
data/bin/bluepill
CHANGED
@@ -11,11 +11,11 @@ RbConfig = Config unless Object.const_defined?(:RbConfig)
|
|
11
11
|
|
12
12
|
# Default options
|
13
13
|
options = {
|
14
|
-
:log_file
|
15
|
-
:base_dir
|
14
|
+
:log_file => '/var/log/bluepill.log',
|
15
|
+
:base_dir => ENV['BLUEPILL_BASE_DIR'] || (::Process.euid != 0 ? File.join(ENV['HOME'], '.bluepill') : '/var/run/bluepill'),
|
16
16
|
:privileged => true,
|
17
|
-
:timeout
|
18
|
-
:attempts
|
17
|
+
:timeout => 10,
|
18
|
+
:attempts => 1,
|
19
19
|
}
|
20
20
|
|
21
21
|
OptionParser.new do |opts|
|
@@ -29,7 +29,7 @@ OptionParser.new do |opts|
|
|
29
29
|
end
|
30
30
|
|
31
31
|
opts.on('-v', '--version') do
|
32
|
-
puts "bluepill, version #{Bluepill::
|
32
|
+
puts "bluepill, version #{Bluepill::Version}"
|
33
33
|
exit
|
34
34
|
end
|
35
35
|
|
data/bin/sample_forking_server
CHANGED
data/bluepill.gemspec
CHANGED
@@ -4,7 +4,7 @@ require 'bluepill/version'
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = 'bluepill'
|
7
|
-
s.version = Bluepill::
|
7
|
+
s.version = Bluepill::Version
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ['Arya Asemanfar', 'Gary Tsang', 'Rohith Ravi']
|
10
10
|
s.email = ['entombedvirus@gmail.com']
|
@@ -13,13 +13,12 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.description = "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."
|
14
14
|
s.license = 'MIT'
|
15
15
|
|
16
|
-
s.add_dependency 'activesupport', ['>= 3', '< 5']
|
17
|
-
s.add_dependency 'blue-daemons', '~> 1.1
|
18
|
-
s.add_dependency 'i18n', '~> 0.5'
|
16
|
+
s.add_dependency 'activesupport', ['>= 3.2', '< 5']
|
17
|
+
s.add_dependency 'blue-daemons', '~> 1.1'
|
19
18
|
s.add_dependency 'state_machine', '~> 1.1'
|
20
19
|
s.add_development_dependency 'bundler', '~> 1.3'
|
21
20
|
|
22
21
|
s.files = %w(CONTRIBUTING.md DESIGN.md LICENSE README.md bluepill.gemspec) + Dir['bin/*'] + Dir['lib/**/*.rb']
|
23
|
-
s.executables = Dir['bin/*'].
|
22
|
+
s.executables = Dir['bin/*'].collect { |f| File.basename(f) }
|
24
23
|
s.require_paths = ['lib']
|
25
24
|
end
|
data/lib/bluepill/application.rb
CHANGED
data/lib/bluepill/controller.rb
CHANGED
@@ -16,7 +16,7 @@ module Bluepill
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def running_applications
|
19
|
-
Dir[File.join(sockets_dir, '*.sock')].
|
19
|
+
Dir[File.join(sockets_dir, '*.sock')].collect { |x| File.basename(x, '.sock') }
|
20
20
|
end
|
21
21
|
|
22
22
|
def handle_command(application, command, *args)
|
@@ -107,8 +107,8 @@ module Bluepill
|
|
107
107
|
|
108
108
|
def verify_version!(application)
|
109
109
|
version = Socket.client_command(base_dir, application, 'version')
|
110
|
-
if version != Bluepill::
|
111
|
-
abort("The running version of your daemon seems to be out of date.\nDaemon Version: #{version}, CLI Version: #{Bluepill::
|
110
|
+
if version != Bluepill::Version
|
111
|
+
abort("The running version of your daemon seems to be out of date.\nDaemon Version: #{version}, CLI Version: #{Bluepill::Version}")
|
112
112
|
end
|
113
113
|
rescue ArgumentError
|
114
114
|
abort('The running version of your daemon seems to be out of date.')
|
data/lib/bluepill/group.rb
CHANGED
@@ -54,8 +54,8 @@ module Bluepill
|
|
54
54
|
lines << "#{name}:" if name
|
55
55
|
|
56
56
|
processes.each do |process|
|
57
|
-
next unless process.monitor_children?
|
58
57
|
lines << format('%s%s(pid:%s): %s', prefix, process.name, process.actual_pid, process.state)
|
58
|
+
next unless process.monitor_children?
|
59
59
|
process.children.each do |child|
|
60
60
|
lines << format(' %s%s: %s', prefix, child.name, child.state)
|
61
61
|
end
|
data/lib/bluepill/process.rb
CHANGED
@@ -129,7 +129,7 @@ module Bluepill
|
|
129
129
|
end
|
130
130
|
|
131
131
|
# These defaults are overriden below if it's configured to be something else.
|
132
|
-
@monitor_children =
|
132
|
+
@monitor_children = false
|
133
133
|
@cache_actual_pid = true
|
134
134
|
@start_grace_time = @stop_grace_time = @restart_grace_time = 3
|
135
135
|
@environment = {}
|
@@ -232,7 +232,7 @@ module Bluepill
|
|
232
232
|
end
|
233
233
|
end
|
234
234
|
events
|
235
|
-
end.each do |
|
235
|
+
end.each do |event, reason| # rubocop:disable Style/MultilineBlockChain
|
236
236
|
break if @transitioned
|
237
237
|
self.dispatch!(event, reason)
|
238
238
|
end
|
@@ -286,7 +286,7 @@ module Bluepill
|
|
286
286
|
if daemon_id
|
287
287
|
ProcessJournal.append_pid_to_journal(name, daemon_id)
|
288
288
|
children.each do|child|
|
289
|
-
ProcessJournal.append_pid_to_journal(name, child.
|
289
|
+
ProcessJournal.append_pid_to_journal(name, child.actual_pid)
|
290
290
|
end if self.monitor_children?
|
291
291
|
end
|
292
292
|
daemon_id
|
@@ -470,7 +470,7 @@ module Bluepill
|
|
470
470
|
@children.delete_if { |child| !child.process_running?(true) }
|
471
471
|
|
472
472
|
# Add new found children to the list
|
473
|
-
new_children_pids = System.get_children(actual_pid) - @children.
|
473
|
+
new_children_pids = System.get_children(actual_pid) - @children.collect(&:actual_pid)
|
474
474
|
|
475
475
|
unless new_children_pids.empty?
|
476
476
|
logger.info "Existing children: #{@children.collect(&:actual_pid).join(',')}. Got new children: #{new_children_pids.inspect} for #{actual_pid}"
|
@@ -478,7 +478,7 @@ module Bluepill
|
|
478
478
|
|
479
479
|
# Construct a new process wrapper for each new found children
|
480
480
|
new_children_pids.each do |child_pid|
|
481
|
-
ProcessJournal.append_pid_to_journal(name, child_pid)
|
481
|
+
ProcessJournal.append_pid_to_journal(name, child_pid) if daemonize?
|
482
482
|
child_name = "<child(pid:#{child_pid})>"
|
483
483
|
logger = self.logger.prefix_with(child_name)
|
484
484
|
|
@@ -493,15 +493,15 @@ module Bluepill
|
|
493
493
|
|
494
494
|
def system_command_options
|
495
495
|
{
|
496
|
-
:uid
|
497
|
-
:gid
|
496
|
+
:uid => uid,
|
497
|
+
:gid => gid,
|
498
498
|
:working_dir => working_dir,
|
499
499
|
:environment => environment,
|
500
|
-
:pid_file
|
501
|
-
:logger
|
502
|
-
:stdin
|
503
|
-
:stdout
|
504
|
-
:stderr
|
500
|
+
:pid_file => pid_file,
|
501
|
+
:logger => logger,
|
502
|
+
:stdin => stdin,
|
503
|
+
:stdout => stdout,
|
504
|
+
:stderr => stderr,
|
505
505
|
:supplementary_groups => supplementary_groups,
|
506
506
|
}
|
507
507
|
end
|
@@ -6,14 +6,16 @@ module Bluepill
|
|
6
6
|
class Http < ProcessCondition
|
7
7
|
def initialize(options = {})
|
8
8
|
@uri = URI.parse(options[:url])
|
9
|
-
@kind =
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
@kind = begin
|
10
|
+
case options[:kind]
|
11
|
+
when Fixnum
|
12
|
+
Net::HTTPResponse::CODE_TO_OBJ[options[:kind].to_s]
|
13
|
+
when String, Symbol
|
14
|
+
Net.const_get("HTTP#{options[:kind].to_s.camelize}")
|
15
|
+
else
|
16
|
+
Net::HTTPSuccess
|
17
|
+
end
|
18
|
+
end
|
17
19
|
@pattern = options[:pattern] || nil
|
18
20
|
@open_timeout = (options[:open_timeout] || options[:timeout] || 5).to_i
|
19
21
|
@read_timeout = (options[:read_timeout] || options[:timeout] || 5).to_i
|
@@ -41,7 +43,7 @@ module Bluepill
|
|
41
43
|
return false unless value.is_a?(@kind)
|
42
44
|
return true unless @pattern
|
43
45
|
return false unless value.class.body_permitted?
|
44
|
-
@pattern
|
46
|
+
@pattern =~ value.body
|
45
47
|
end
|
46
48
|
|
47
49
|
private
|
@@ -50,7 +52,7 @@ module Bluepill
|
|
50
52
|
yield
|
51
53
|
rescue NoMethodError => e
|
52
54
|
if e.to_s =~ /#{Regexp.escape("undefined method `closed?' for nil:NilClass")}/
|
53
|
-
raise(Errno::ECONNREFUSED
|
55
|
+
raise(Errno::ECONNREFUSED, "Connection refused attempting to contact #{@uri.scheme}://#{@uri.host}:#{@uri.port}")
|
54
56
|
else
|
55
57
|
raise
|
56
58
|
end
|
@@ -65,7 +65,7 @@ module Bluepill
|
|
65
65
|
|
66
66
|
def pid_journal(filename)
|
67
67
|
logger.debug("pid journal file: #{filename}")
|
68
|
-
result = File.open(filename, 'r').readlines.
|
68
|
+
result = File.open(filename, 'r').readlines.collect(&:to_i).reject { |pid| skip_pid?(pid) }
|
69
69
|
logger.debug("pid journal = #{result.join(' ')}")
|
70
70
|
result
|
71
71
|
rescue Errno::ENOENT
|
@@ -74,7 +74,7 @@ module Bluepill
|
|
74
74
|
|
75
75
|
def pgid_journal(filename)
|
76
76
|
logger.debug("pgid journal file: #{filename}")
|
77
|
-
result = File.open(filename, 'r').readlines.
|
77
|
+
result = File.open(filename, 'r').readlines.collect(&:to_i).reject { |pgid| skip_pgid?(pgid) }
|
78
78
|
logger.debug("pgid journal = #{result.join(' ')}")
|
79
79
|
result
|
80
80
|
rescue Errno::ENOENT
|
@@ -88,7 +88,7 @@ module Bluepill
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def kill_all_from_all_journals
|
91
|
-
pids = Dir['.bluepill_pids_journal.*'].
|
91
|
+
pids = Dir['.bluepill_pids_journal.*'].collect { |p| p.sub(/^\.bluepill_pids_journal\./, '') }
|
92
92
|
pids.reject! { |p| p =~ /\.lock$/ }
|
93
93
|
pids.each do |journal_name|
|
94
94
|
kill_all_from_journal(journal_name)
|
@@ -114,7 +114,7 @@ module Bluepill
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
|
-
if j.
|
117
|
+
if j.count { |pgid| System.pid_alive?(pgid) } > 1
|
118
118
|
sleep(1)
|
119
119
|
j.each do |pgid|
|
120
120
|
begin
|
@@ -147,7 +147,7 @@ module Bluepill
|
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
|
-
if j.
|
150
|
+
if j.count { |pid| System.pid_alive?(pid) } > 1
|
151
151
|
sleep(1)
|
152
152
|
j.each do |pid|
|
153
153
|
begin
|
data/lib/bluepill/system.rb
CHANGED
@@ -65,7 +65,7 @@ module Bluepill
|
|
65
65
|
ps_axu.each_pair do |_pid, chunks|
|
66
66
|
child_pids << chunks[IDX_MAP[:pid]].to_i if chunks[IDX_MAP[:ppid]].to_i == parent_pid.to_i
|
67
67
|
end
|
68
|
-
grand_children = child_pids.
|
68
|
+
grand_children = child_pids.collect { |pid| get_children(pid) }.flatten
|
69
69
|
child_pids.concat grand_children
|
70
70
|
end
|
71
71
|
|
@@ -96,7 +96,7 @@ module Bluepill
|
|
96
96
|
|
97
97
|
to_daemonize = lambda do
|
98
98
|
# Setting end PWD env emulates bash behavior when dealing with symlinks
|
99
|
-
Dir.chdir(ENV['PWD'] = options[:working_dir].to_s)
|
99
|
+
Dir.chdir(ENV['PWD'] = options[:working_dir].to_s) if options[:working_dir]
|
100
100
|
options[:environment].each { |key, value| ENV[key.to_s] = value.to_s } if options[:environment]
|
101
101
|
|
102
102
|
redirect_io(*options.values_at(:stdin, :stdout, :stderr))
|
@@ -226,7 +226,7 @@ module Bluepill
|
|
226
226
|
# BSD style ps invocation
|
227
227
|
lines = `ps axo pid,ppid,pcpu,rss,etime,command`.split("\n")
|
228
228
|
|
229
|
-
lines.inject(
|
229
|
+
lines.inject({}) do |mem, line|
|
230
230
|
chunks = line.split(/\s+/)
|
231
231
|
chunks.delete_if { |c| c.strip.empty? }
|
232
232
|
pid = chunks[IDX_MAP[:pid]].strip.to_i
|
@@ -258,7 +258,7 @@ module Bluepill
|
|
258
258
|
uid_num = Etc.getpwnam(uid).uid if uid
|
259
259
|
gid_num = Etc.getgrnam(gid).gid if gid
|
260
260
|
supplementary_groups ||= []
|
261
|
-
group_nums = supplementary_groups.
|
261
|
+
group_nums = supplementary_groups.collect do |group|
|
262
262
|
Etc.getgrnam(group).gid
|
263
263
|
end
|
264
264
|
::Process.groups = [gid_num] if gid
|
data/lib/bluepill/version.rb
CHANGED
@@ -1,3 +1,45 @@
|
|
1
1
|
module Bluepill
|
2
|
-
|
2
|
+
module Version
|
3
|
+
module_function
|
4
|
+
|
5
|
+
# @return [Integer]
|
6
|
+
def major
|
7
|
+
0
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Integer]
|
11
|
+
def minor
|
12
|
+
0
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Integer]
|
16
|
+
def patch
|
17
|
+
70
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Integer, NilClass]
|
21
|
+
def pre
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Hash]
|
26
|
+
def to_h
|
27
|
+
{
|
28
|
+
:major => major,
|
29
|
+
:minor => minor,
|
30
|
+
:patch => patch,
|
31
|
+
:pre => pre,
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Array]
|
36
|
+
def to_a
|
37
|
+
to_h.values.compact
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [String]
|
41
|
+
def to_s
|
42
|
+
to_a.join('.')
|
43
|
+
end
|
44
|
+
end
|
3
45
|
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.70
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arya Asemanfar
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2015-08-14 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ">="
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: '3'
|
21
|
+
version: '3.2'
|
22
22
|
- - "<"
|
23
23
|
- !ruby/object:Gem::Version
|
24
24
|
version: '5'
|
@@ -28,7 +28,7 @@ dependencies:
|
|
28
28
|
requirements:
|
29
29
|
- - ">="
|
30
30
|
- !ruby/object:Gem::Version
|
31
|
-
version: '3'
|
31
|
+
version: '3.2'
|
32
32
|
- - "<"
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: '5'
|
@@ -38,28 +38,14 @@ dependencies:
|
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 1.1
|
42
|
-
type: :runtime
|
43
|
-
prerelease: false
|
44
|
-
version_requirements: !ruby/object:Gem::Requirement
|
45
|
-
requirements:
|
46
|
-
- - "~>"
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
version: 1.1.11
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: i18n
|
51
|
-
requirement: !ruby/object:Gem::Requirement
|
52
|
-
requirements:
|
53
|
-
- - "~>"
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version: '0.5'
|
41
|
+
version: '1.1'
|
56
42
|
type: :runtime
|
57
43
|
prerelease: false
|
58
44
|
version_requirements: !ruby/object:Gem::Requirement
|
59
45
|
requirements:
|
60
46
|
- - "~>"
|
61
47
|
- !ruby/object:Gem::Version
|
62
|
-
version: '
|
48
|
+
version: '1.1'
|
63
49
|
- !ruby/object:Gem::Dependency
|
64
50
|
name: state_machine
|
65
51
|
requirement: !ruby/object:Gem::Requirement
|
@@ -159,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
159
145
|
version: '0'
|
160
146
|
requirements: []
|
161
147
|
rubyforge_project:
|
162
|
-
rubygems_version: 2.
|
148
|
+
rubygems_version: 2.4.5
|
163
149
|
signing_key:
|
164
150
|
specification_version: 4
|
165
151
|
summary: A process monitor written in Ruby with stability and minimalism in mind.
|