zombie_passenger_killer 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5780e6196f2270301870a5859bf75a2ab43da51a
4
+ data.tar.gz: 032a0875bb8d4bffd797b1aadb9bb2b21ce17c1e
5
+ SHA512:
6
+ metadata.gz: 90d28d0ff5cca9d60b208a757f99bed45739a197ea920cd9032680a1b284b3fab8654c657508851fac4a8361d0dcf61e82666211b86a4f13ec4a095099e9cabb
7
+ data.tar.gz: c0f70fa2e121e6e7044b8dc99fcd81f1e47c2bcc433190b65566c31e9e9e7672e0da7abe78eadfecf98df30b82c777acccd8f77a09f799d58d6bf50ed75185bb
data/Readme.md CHANGED
@@ -13,7 +13,10 @@ Add passenger-status to `/etc/sudoers` or run with sudo.
13
13
 
14
14
  Install
15
15
  =======
16
- sudo gem install zombie_passenger_killer
16
+
17
+ ```
18
+ sudo gem install zombie_passenger_killer
19
+ ```
17
20
 
18
21
  Usage
19
22
  =====
@@ -36,12 +39,14 @@ Usage
36
39
 
37
40
  ### Bluepill script
38
41
 
39
- app.process("zombie_passenger_killer") do |process|
40
- process.start_command = "zombie_passenger_killer --max 5 --history 10 --cpu 30 --interval 10"
41
- process.stdout = process.stderr = "/var/log/autorotate/zombie_passenger_killer.log"
42
- process.pid_file = "/var/run/zombie_passenger_killer.pid"
43
- process.daemonize = true
44
- end
42
+ ```Ruby
43
+ app.process("zombie_passenger_killer") do |process|
44
+ process.start_command = "zombie_passenger_killer --max 5 --history 10 --cpu 30 --interval 10"
45
+ process.stdout = process.stderr = "/var/log/autorotate/zombie_passenger_killer.log"
46
+ process.pid_file = "/var/run/zombie_passenger_killer.pid"
47
+ process.daemonize = true
48
+ end
49
+ ```
45
50
 
46
51
  ### Monit script
47
52
 
@@ -62,9 +67,10 @@ Author
62
67
  - [Roman Heinrich](https://github.com/mindreframer)
63
68
  - [Kevin Mullin](https://github.com/kmullin)
64
69
  - [Valery Vishnyakov](https://github.com/balepc)
70
+ - [Bodo Tasche](https://github.com/bitboxer)
65
71
 
66
72
  [Michael Grosser](http://grosser.it)<br/>
67
73
  michael@grosser.it<br/>
68
74
  License: MIT<br/>
69
- [![Build Status](https://secure.travis-ci.org/grosser/zombie_passenger_killer.png)](http://travis-ci.org/grosser/zombie_passenger_killer)
75
+ [![Build Status](https://travis-ci.org/grosser/zombie_passenger_killer.png)](https://travis-ci.org/grosser/zombie_passenger_killer)
70
76
 
@@ -22,6 +22,7 @@ BANNER
22
22
  opts.on("-i", "--interval [SECONDS]", Integer, "Check every SECONDS (default: 10)") {|i| options[:interval]=i }
23
23
  opts.on("-p", "--pattern [PATTERN]", String, "Find processes with this pattern (default: ' Rack: ')") {|i| options[:pattern]=i }
24
24
  opts.on("-1", "--once", "Check once and exit") { options[:once]=true }
25
+ opts.on("--verbose", "Verbose") { options[:verbose] = true }
25
26
  opts.on("--rvmsudo", "Use `rvmsudo` to see passenger-status") { options[:rvmsudo]=true }
26
27
  opts.on("-h", "--help","Show this") { puts opts; exit }
27
28
  opts.on("-v", "--version","Show Version"){ puts version; exit }
@@ -12,6 +12,7 @@ module ZombiePassengerKiller
12
12
  @pattern = options[:pattern] || ' Rack: '
13
13
  @show_times = options[:show_times] || false
14
14
  @interval = options[:interval] || 10
15
+ @verbose = options[:verbose]
15
16
  @strace_time = 5
16
17
  @out = STDOUT
17
18
  @rvmsudo = options[:rvmsudo]
@@ -29,8 +30,13 @@ module ZombiePassengerKiller
29
30
 
30
31
  def hunt_zombies
31
32
  active_pids_in_passenger_status = passenger_pids
33
+ puts "Active pids in status: #{active_pids_in_passenger_status.inspect}" if @verbose
34
+
32
35
  active_processes_in_processlist = process_status
36
+ puts "Active pids in processlist: #{active_processes_in_processlist.inspect}" if @verbose
37
+
33
38
  zombies = active_processes_in_processlist.map{|x| x[:pid] } - active_pids_in_passenger_status rescue Array.new
39
+ puts "Zombies: #{zombies.inspect}" if @verbose
34
40
 
35
41
  # kill processes with high CPU if user wants it
36
42
  high_load = if @max_high_cpu
@@ -65,10 +71,10 @@ module ZombiePassengerKiller
65
71
  `( strace -p #{pid} 2>&1 ) & sleep #{time} ; kill $! 2>&1`
66
72
  end
67
73
 
68
- # return array of pids reported from passenger-status command, nil if passenger-status doesn't run
74
+ # return array of pids reported from passenger-status command, nil if passenger doesn't run
69
75
  def passenger_pids
70
- pids = %x(#{'rvmsudo ' if @rvmsudo}passenger-status|grep PID).split("\n").map { |x| x.strip.match(/PID: \d*/).to_s.split[1].to_i }
71
- if $?.exitstatus.zero?
76
+ pids = %x(#{'rvmsudo ' if @rvmsudo}passenger-status).split("\n").map { |l| l[/PID: (\d+)/, 1] }.compact.map(&:to_i)
77
+ if $?.success?
72
78
  pids
73
79
  else
74
80
  raise "passenger-status returned a #{$?.exitstatus} exit code. Please check if passenger-status is working properly."
@@ -76,9 +82,9 @@ module ZombiePassengerKiller
76
82
  end
77
83
 
78
84
  def process_status
79
- %x(ps -eo pid,pcpu,args|grep -v grep|egrep '#{@pattern}').split("\n").map do |line|
80
- values = line.strip.split[0..1]
81
- {:pid => values.first.to_i, :cpu => values.last.to_f}
85
+ %x(ps -eo pid,pcpu,args|grep -v grep|grep -v zombie_passenger_killer|egrep '#{@pattern}').split("\n").map do |line|
86
+ values = line.strip.split[0..1]
87
+ {:pid => values.first.to_i, :cpu => values.last.to_f}
82
88
  end
83
89
  end
84
90
 
@@ -1,3 +1,3 @@
1
1
  module ZombiePassengerKiller
2
- Version = VERSION = '0.3.0'
2
+ Version = VERSION = '0.3.1'
3
3
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zombie_passenger_killer
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.3.0
4
+ version: 0.3.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Michael Grosser
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-01-14 00:00:00.000000000 Z
11
+ date: 2014-12-04 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description:
15
14
  email: michael@grosser.it
@@ -18,47 +17,33 @@ executables:
18
17
  extensions: []
19
18
  extra_rdoc_files: []
20
19
  files:
21
- - .travis.yml
22
- - Gemfile
23
- - Gemfile.lock
24
- - Rakefile
25
20
  - Readme.md
26
21
  - bin/zombie_passenger_killer
27
22
  - lib/zombie_passenger_killer.rb
28
23
  - lib/zombie_passenger_killer/reaper.rb
29
24
  - lib/zombie_passenger_killer/version.rb
30
- - spec/spec_helper.rb
31
- - spec/zombie_passenger_killer_spec.rb
32
- - zombie_passenger_killer.gemspec
33
- homepage: http://github.com/grosser/zombie_passenger_killer
25
+ homepage: https://github.com/grosser/zombie_passenger_killer
34
26
  licenses:
35
27
  - MIT
28
+ metadata: {}
36
29
  post_install_message:
37
30
  rdoc_options: []
38
31
  require_paths:
39
32
  - lib
40
33
  required_ruby_version: !ruby/object:Gem::Requirement
41
34
  requirements:
42
- - - ! '>='
35
+ - - ">="
43
36
  - !ruby/object:Gem::Version
44
37
  version: '0'
45
- segments:
46
- - 0
47
- hash: 91186768020065310
48
- none: false
49
38
  required_rubygems_version: !ruby/object:Gem::Requirement
50
39
  requirements:
51
- - - ! '>='
40
+ - - ">="
52
41
  - !ruby/object:Gem::Version
53
42
  version: '0'
54
- segments:
55
- - 0
56
- hash: 91186768020065310
57
- none: false
58
43
  requirements: []
59
44
  rubyforge_project:
60
- rubygems_version: 1.8.24
45
+ rubygems_version: 2.2.2
61
46
  signing_key:
62
- specification_version: 3
47
+ specification_version: 4
63
48
  summary: Guaranteed zombie passengers death
64
49
  test_files: []
data/.travis.yml DELETED
@@ -1,4 +0,0 @@
1
- rvm:
2
- - ree
3
- - 1.9.2
4
- - 1.9.3
data/Gemfile DELETED
@@ -1,6 +0,0 @@
1
- source :rubygems
2
- gemspec
3
-
4
- gem 'rake'
5
- gem 'rspec', '~>2'
6
- gem 'bump'
data/Gemfile.lock DELETED
@@ -1,28 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- zombie_passenger_killer (0.3.0)
5
-
6
- GEM
7
- remote: http://rubygems.org/
8
- specs:
9
- bump (0.3.9)
10
- diff-lcs (1.1.3)
11
- rake (0.9.2)
12
- rspec (2.6.0)
13
- rspec-core (~> 2.6.0)
14
- rspec-expectations (~> 2.6.0)
15
- rspec-mocks (~> 2.6.0)
16
- rspec-core (2.6.4)
17
- rspec-expectations (2.6.0)
18
- diff-lcs (~> 1.1.2)
19
- rspec-mocks (2.6.0)
20
-
21
- PLATFORMS
22
- ruby
23
-
24
- DEPENDENCIES
25
- bump
26
- rake
27
- rspec (~> 2)
28
- zombie_passenger_killer!
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require 'bundler/gem_tasks'
2
- require 'bump/tasks'
3
-
4
- task :default do
5
- sh "rspec spec/"
6
- end
data/spec/spec_helper.rb DELETED
@@ -1 +0,0 @@
1
- require 'zombie_passenger_killer'
@@ -1,186 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ZombiePassengerKiller do
4
- let(:killer){
5
- ZombiePassengerKiller::Reaper.new(@options || {}).tap do |k|
6
- k.stub!(:passenger_pids).and_return([111])
7
- k.out = StringIO.new
8
- end
9
- }
10
-
11
- def output
12
- killer.out.rewind
13
- killer.out.read
14
- end
15
-
16
- it "has a VERSION" do
17
- ZombiePassengerKiller::VERSION.should =~ /^\d+\.\d+\.\d+$/
18
- end
19
-
20
- describe "#hunt_zombies" do
21
- it "does not kill anything by default" do
22
- killer.should_not_receive(:kill_zombie)
23
- killer.hunt_zombies
24
- end
25
-
26
- it "finds the right zombies" do
27
- killer.stub!(:passenger_pids).and_return([123])
28
- killer.stub!(:process_status).and_return([{:pid => 124, :cpu => 0}])
29
- killer.should_receive(:kill_zombie).with(124)
30
- killer.hunt_zombies
31
- end
32
-
33
- it "does not blow up when there are more processes in pids then status" do
34
- @options = {:max => 1}
35
- killer.stub!(:passenger_pids).and_return([123])
36
- killer.stub!(:process_status).and_return([{:pid => 124, :cpu => 0}])
37
- killer.should_receive(:kill_zombie).with(124)
38
- killer.hunt_zombies
39
- end
40
-
41
- it "kills zombies with high cpu over max" do
42
- @options = {:max => 1}
43
- killer.stub!(:process_status).and_return([{:pid => 111, :cpu => 100}])
44
- killer.should_receive(:kill_zombie).with(111)
45
- killer.hunt_zombies
46
- end
47
-
48
- it "does not kills zombies with high cpu under max" do
49
- @options = {:max => 2}
50
- killer.stub!(:process_status).and_return([{:pid => 111, :cpu => 100}])
51
- killer.should_not_receive(:kill_zombie).with(111)
52
- killer.hunt_zombies
53
- end
54
-
55
- it "ignores high cpu levels in old history" do
56
- @options = {:max => 2, :history => 2}
57
- killer.should_not_receive(:kill_zombie).with(111)
58
- killer.stub!(:process_status).and_return([{:pid => 111, :cpu => 100}])
59
- killer.hunt_zombies
60
- killer.stub!(:process_status).and_return([{:pid => 111, :cpu => 0}])
61
- killer.hunt_zombies
62
- killer.stub!(:process_status).and_return([{:pid => 111, :cpu => 100}])
63
- killer.hunt_zombies
64
- end
65
-
66
- it "kills on high cpu levels in recent history" do
67
- @options = {:max => 2, :history => 2}
68
- killer.stub!(:process_status).and_return([{:pid => 111, :cpu => 100}])
69
- killer.hunt_zombies
70
- killer.should_receive(:kill_zombie).with(111)
71
- killer.hunt_zombies
72
- end
73
- end
74
-
75
- describe "#kill_zombies" do
76
- before do
77
- killer.instance_eval{
78
- @grace_time = 0.1
79
- @strace_time = 0.1
80
- }
81
- end
82
-
83
- def pid_of(marker)
84
- processes = `ps -ef | grep '#{marker}' | grep -v grep`
85
- processes.strip.split("\n").last.split(/\s+/)[1].to_i
86
- end
87
-
88
- def start_bogus_process(options={})
89
- marker = "TEST---#{rand(999999999999)}"
90
- Thread.new do
91
- `ruby -e 'at_exit{ puts "proper exit"; #{'sleep 10' if options[:hang]}}; sleep 10; puts "#{marker}"' 2>&1`
92
- end
93
- sleep 1 # give process time to spin up
94
- pid_of(marker)
95
- end
96
-
97
- def process_alive?(pid)
98
- Process.getpgid(pid)
99
- rescue Errno::ESRCH
100
- false
101
- end
102
-
103
- it "kills normal processes" do
104
- pid = start_bogus_process
105
- lambda{
106
- killer.send(:kill_zombie, pid)
107
- sleep 0.1
108
- }.should change{ process_alive?(pid) }
109
- end
110
-
111
- it "kills hanging processes" do
112
- pid = start_bogus_process :hang => true
113
- lambda{
114
- killer.send(:kill_zombie, pid)
115
- sleep 0.1
116
- }.should change{ process_alive?(pid) }
117
- end
118
-
119
- it "prints an strace of the process" do
120
- pid = start_bogus_process
121
- killer.send(:kill_zombie, pid)
122
- output.should include('attach:')
123
- end
124
-
125
- it "does not take a strace of a dead process" do
126
- killer.send(:kill_zombie, 111)
127
- output.should_not include('attach:')
128
- end
129
-
130
- it "does not fail with an unknown pid" do
131
- killer.send(:kill_zombie, 111)
132
- output.should include('No such process')
133
- end
134
- end
135
-
136
- describe "#log" do
137
- it "logs simple when :show_times is not given" do
138
- killer.send(:log, "X")
139
- output.should == "X\n"
140
- end
141
-
142
- it "logs simple when :show_times is not given" do
143
- @options = {:show_times => true}
144
- killer.send(:log, "X")
145
- output.should include(Time.now.year.to_s)
146
- end
147
- end
148
-
149
- describe "#lurk" do
150
- it "sleeps after checking" do
151
- killer.should_receive(:hunt_zombies)
152
- killer.should_receive(:sleep).with(10).and_raise "LOOP-BREAKER"
153
- lambda{
154
- killer.lurk
155
- }.should raise_error "LOOP-BREAKER"
156
- end
157
-
158
- it "calls sleep with the given interval" do
159
- @options = {:interval => 5}
160
- killer.stub(:hunt_zombies)
161
- killer.should_receive(:sleep).with(5).and_raise "LOOP-BREAKER"
162
- lambda{
163
- killer.lurk
164
- }.should raise_error "LOOP-BREAKER"
165
- end
166
-
167
- it "prints Exiting on Interrupt" do
168
- killer.stub(:hunt_zombies)
169
- killer.should_receive(:sleep).and_raise Interrupt.new
170
- lambda{
171
- killer.lurk
172
- }.should raise_error Interrupt
173
- output.should include("Exiting")
174
- end
175
- end
176
-
177
- describe "cli" do
178
- it "prints its version" do
179
- `./bin/zombie_passenger_killer -v`.should =~ /^\d+\.\d+\.\d+$/m
180
- end
181
-
182
- it "prints help" do
183
- `./bin/zombie_passenger_killer -h`.should include('Usage')
184
- end
185
- end
186
- end
@@ -1,12 +0,0 @@
1
- $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2
- require 'zombie_passenger_killer/version'
3
-
4
- Gem::Specification.new "zombie_passenger_killer", ZombiePassengerKiller::VERSION do |s|
5
- s.summary = "Guaranteed zombie passengers death"
6
- s.authors = ["Michael Grosser"]
7
- s.email = "michael@grosser.it"
8
- s.homepage = "http://github.com/grosser/zombie_passenger_killer"
9
- s.files = `git ls-files`.split("\n")
10
- s.executables = ["zombie_passenger_killer"]
11
- s.license = "MIT"
12
- end