zombie_passenger_killer 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +1 -1
- data/Readme.md +9 -1
- data/bin/zombie_passenger_killer +7 -10
- data/lib/zombie_passenger_killer/reaper.rb +17 -2
- data/lib/zombie_passenger_killer/version.rb +1 -1
- data/spec/zombie_passenger_killer_spec.rb +50 -9
- metadata +4 -4
data/Gemfile.lock
CHANGED
data/Readme.md
CHANGED
@@ -27,8 +27,9 @@ Usage
|
|
27
27
|
-g, --grace [SECONDS] Wait SECONDS before hard-killing (-9) a process (default: 5)
|
28
28
|
-i, --interval [SECONDS] Check every SECONDS (default: 10)
|
29
29
|
-p, --pattern [PATTERN] Find processes with this pattern (default: ' Rack: ')
|
30
|
-
-h, --help Show this
|
30
|
+
-h, --help Show this
|
31
31
|
-v, --version Show Version
|
32
|
+
-t, --time Show time in output
|
32
33
|
|
33
34
|
|
34
35
|
### Bluepill script
|
@@ -40,6 +41,13 @@ Usage
|
|
40
41
|
process.daemonize = true
|
41
42
|
end
|
42
43
|
|
44
|
+
### Monit script
|
45
|
+
|
46
|
+
check process zombie_killer
|
47
|
+
with pidfile "/var/run/zombie_passenger_killer.pid"
|
48
|
+
start program = "/bin/bash -c 'export PATH=$PATH:/usr/local/bin HOME=/home;zombie_passenger_killer --max 5 --history 10 --cpu 30 --interval 10 &>/var/log/zombie_passenger_killer.log & &>/dev/null;echo $! > /var/run/zombie_passenger_killer.pid'"
|
49
|
+
stop program = "/bin/bash -c 'PIDF=/var/run/zombie_passenger_killer.pid;/bin/kill `cat $PIDF` && rm -f $PIDF'"
|
50
|
+
group zombie_killer
|
43
51
|
|
44
52
|
### God script
|
45
53
|
|
data/bin/zombie_passenger_killer
CHANGED
@@ -5,6 +5,7 @@ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
|
5
5
|
require 'zombie_passenger_killer'
|
6
6
|
|
7
7
|
options = {}
|
8
|
+
version = ZombiePassengerKiller::VERSION
|
8
9
|
OptionParser.new do |opts|
|
9
10
|
opts.banner = <<BANNER
|
10
11
|
Guaranteed zombie passengers death
|
@@ -20,17 +21,13 @@ BANNER
|
|
20
21
|
opts.on("-g", "--grace [SECONDS]", Integer, "Wait SECONDS before hard-killing (-9) a process (default: 5)") {|i| options[:grace]=i }
|
21
22
|
opts.on("-i", "--interval [SECONDS]", Integer, "Check every SECONDS (default: 10)") {|i| options[:interval]=i }
|
22
23
|
opts.on("-p", "--pattern [PATTERN]", String, "Find processes with this pattern (default: ' Rack: ')") {|i| options[:pattern]=i }
|
23
|
-
opts.on("-h", "--help","Show this
|
24
|
-
opts.on(
|
24
|
+
opts.on("-h", "--help","Show this") { puts opts; exit }
|
25
|
+
opts.on("-v", "--version","Show Version"){ puts version; exit }
|
26
|
+
opts.on("-t", "--timing","Show timing on output") { options[:show_times]=true }
|
25
27
|
end.parse!
|
26
28
|
|
27
29
|
$stdout.sync = true
|
28
|
-
puts "Started at #{Time.now}"
|
30
|
+
puts "PID: #{$$} Version: #{version} Started at #{Time.now}"
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
$0 = File.basename(__FILE__)
|
33
|
-
loop do
|
34
|
-
killer.hunt_zombies
|
35
|
-
sleep options[:interval] || 10
|
36
|
-
end
|
32
|
+
$0 = File.basename(__FILE__) + '-' + version
|
33
|
+
ZombiePassengerKiller::Reaper.new(options).lurk
|
@@ -10,10 +10,22 @@ module ZombiePassengerKiller
|
|
10
10
|
@high_cpu = options[:cpu] || 70
|
11
11
|
@grace_time = options[:grace] || 5
|
12
12
|
@pattern = options[:pattern] || ' Rack: '
|
13
|
+
@show_times = options[:show_times] || false
|
14
|
+
@interval = options[:interval] || 10
|
13
15
|
@strace_time = 5
|
14
16
|
@out = STDOUT
|
15
17
|
end
|
16
18
|
|
19
|
+
def lurk
|
20
|
+
loop do
|
21
|
+
hunt_zombies
|
22
|
+
sleep @interval
|
23
|
+
end
|
24
|
+
rescue Interrupt
|
25
|
+
log "Exiting..."
|
26
|
+
raise $!
|
27
|
+
end
|
28
|
+
|
17
29
|
def store_current_cpu(processes)
|
18
30
|
keys_to_remove = @history.keys - processes.map{|x| x[:pid] }
|
19
31
|
keys_to_remove.each{|k| !@history.delete k }
|
@@ -64,12 +76,15 @@ module ZombiePassengerKiller
|
|
64
76
|
end
|
65
77
|
|
66
78
|
def kill_zombie(pid)
|
67
|
-
|
68
|
-
|
79
|
+
log "Killing passenger process #{pid}"
|
80
|
+
log get_strace(pid, @strace_time)
|
69
81
|
Process.kill('TERM', pid) rescue nil
|
70
82
|
sleep @grace_time # wait for it to die
|
71
83
|
Process.kill('KILL', pid) rescue nil
|
72
84
|
end
|
73
85
|
|
86
|
+
def log(msg)
|
87
|
+
@out.puts "#{@show_times ? "** [#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}] #$$: " : ''}#{msg}"
|
88
|
+
end
|
74
89
|
end
|
75
90
|
end
|
@@ -2,11 +2,17 @@ require File.expand_path('spec/spec_helper')
|
|
2
2
|
|
3
3
|
describe ZombiePassengerKiller do
|
4
4
|
let(:killer){
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
ZombiePassengerKiller::Reaper.new(@options || {}).tap do |k|
|
6
|
+
k.stub!(:passenger_pids).and_return([111])
|
7
|
+
k.out = StringIO.new
|
8
|
+
end
|
8
9
|
}
|
9
10
|
|
11
|
+
def output
|
12
|
+
killer.out.rewind
|
13
|
+
killer.out.read
|
14
|
+
end
|
15
|
+
|
10
16
|
it "has a VERSION" do
|
11
17
|
ZombiePassengerKiller::VERSION.should =~ /^\d+\.\d+\.\d+$/
|
12
18
|
end
|
@@ -60,7 +66,6 @@ describe ZombiePassengerKiller do
|
|
60
66
|
|
61
67
|
describe "#kill_zombies" do
|
62
68
|
before do
|
63
|
-
killer.out = StringIO.new
|
64
69
|
killer.instance_eval{
|
65
70
|
@grace_time = 0.1
|
66
71
|
@strace_time = 0.1
|
@@ -87,11 +92,6 @@ describe ZombiePassengerKiller do
|
|
87
92
|
false
|
88
93
|
end
|
89
94
|
|
90
|
-
def output
|
91
|
-
killer.out.rewind
|
92
|
-
killer.out.read
|
93
|
-
end
|
94
|
-
|
95
95
|
it "kills normal processes" do
|
96
96
|
pid = start_bogus_process
|
97
97
|
lambda{
|
@@ -125,6 +125,47 @@ describe ZombiePassengerKiller do
|
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
128
|
+
describe "#log" do
|
129
|
+
it "logs simple when :show_times is not given" do
|
130
|
+
killer.log "X"
|
131
|
+
output.should == "X\n"
|
132
|
+
end
|
133
|
+
|
134
|
+
it "logs simple when :show_times is not given" do
|
135
|
+
@options = {:show_times => true}
|
136
|
+
killer.log "X"
|
137
|
+
output.should include(Time.now.year.to_s)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "#lurk" do
|
142
|
+
it "sleeps after checking" do
|
143
|
+
killer.should_receive(:hunt_zombies)
|
144
|
+
killer.should_receive(:sleep).with(10).and_raise "LOOP-BREAKER"
|
145
|
+
lambda{
|
146
|
+
killer.lurk
|
147
|
+
}.should raise_error "LOOP-BREAKER"
|
148
|
+
end
|
149
|
+
|
150
|
+
it "calls sleep with the given interval" do
|
151
|
+
@options = {:interval => 5}
|
152
|
+
killer.stub(:hunt_zombies)
|
153
|
+
killer.should_receive(:sleep).with(5).and_raise "LOOP-BREAKER"
|
154
|
+
lambda{
|
155
|
+
killer.lurk
|
156
|
+
}.should raise_error "LOOP-BREAKER"
|
157
|
+
end
|
158
|
+
|
159
|
+
it "prints Exiting on Interrupt" do
|
160
|
+
killer.stub(:hunt_zombies)
|
161
|
+
killer.should_receive(:sleep).and_raise Interrupt.new
|
162
|
+
lambda{
|
163
|
+
killer.lurk
|
164
|
+
}.should raise_error Interrupt
|
165
|
+
output.should include("Exiting")
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
128
169
|
describe "cli" do
|
129
170
|
it "prints its version" do
|
130
171
|
`./bin/zombie_passenger_killer -v`.should =~ /^\d+\.\d+\.\d+$/m
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zombie_passenger_killer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 1
|
10
|
+
version: 0.2.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Michael Grosser
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-02-
|
18
|
+
date: 2012-02-11 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description:
|