passenger_mon 0.1.0
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/README +26 -0
- data/bin/passenger_mon +87 -0
- metadata +74 -0
data/README
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
## tl;dr ##
|
2
|
+
|
3
|
+
Simple rails process monitoring for passenger 3.
|
4
|
+
|
5
|
+
## Usage ##
|
6
|
+
|
7
|
+
passenger_mon needs to be run as root to properly get access to Passenger's
|
8
|
+
`passenger-memory-stats` output.
|
9
|
+
|
10
|
+
# Check for out of control processes every 10 seconds
|
11
|
+
sudo passenger_mon --interval=10
|
12
|
+
|
13
|
+
|
14
|
+
## Problem
|
15
|
+
|
16
|
+
Currently, Passenger 3 (and previous versions) don't generate pidfiles or the
|
17
|
+
application processes it spawns. This makes it very difficult to monitor these
|
18
|
+
processes with tools like monit and [god](http://github.com/mojombo/god). Further
|
19
|
+
compounding this problem is the lack of any sort of per process memory threshold
|
20
|
+
for passenger.
|
21
|
+
|
22
|
+
|
23
|
+
## Contributors
|
24
|
+
|
25
|
+
* Rick Bradley
|
26
|
+
* Alex Sharp
|
data/bin/passenger_mon
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
|
8
|
+
op = OptionParser.new do |opts|
|
9
|
+
opts.banner = 'Usage: passenger_mon [options]'
|
10
|
+
|
11
|
+
opts.on("-i=SECONDS", "--interval=SECONDS", "Poll interval in seconds (default: 10)") do |interval|
|
12
|
+
options[:interval] = interval
|
13
|
+
end
|
14
|
+
|
15
|
+
opts.on("-m=MEMORY", "--memory=MB", "Memory threshold in MB (default: 800)") do |mb|
|
16
|
+
options[:threshold] = mb
|
17
|
+
end
|
18
|
+
|
19
|
+
opts.on_tail("-h", "--help", "show this message") do
|
20
|
+
abort(opts.to_s)
|
21
|
+
end
|
22
|
+
end.parse!
|
23
|
+
|
24
|
+
# set option defaults
|
25
|
+
options[:interval] ||= 10
|
26
|
+
options[:threshold] ||= 800
|
27
|
+
options[:threshold] = options[:threshold].to_i
|
28
|
+
|
29
|
+
process_name = 'passenger_mon'
|
30
|
+
pidfile = "/tmp/#{process_name}.pid"
|
31
|
+
|
32
|
+
# If a pidfile exists when we start up, we need to remove it.
|
33
|
+
# This probably means a non-clean shutdown the last time
|
34
|
+
# the program was shutdown.
|
35
|
+
if File.exist?(pidfile)
|
36
|
+
$stdout.puts "Existing pidfile found. Removing..."
|
37
|
+
FileUtils.rm(pidfile)
|
38
|
+
end
|
39
|
+
|
40
|
+
# remove the pidfile on shutdown
|
41
|
+
at_exit do
|
42
|
+
$stdout.puts "Removing pidfile."
|
43
|
+
FileUtils.rm(pidfile)
|
44
|
+
end
|
45
|
+
|
46
|
+
# write out the pidfile
|
47
|
+
File.open(pidfile, 'w') { |f| f.puts($$) }
|
48
|
+
|
49
|
+
require 'logger'
|
50
|
+
logger = Logger.new("/var/log/passenger_mon.log")
|
51
|
+
|
52
|
+
Signal.trap('INT') do
|
53
|
+
logger.info "Shutting down now..."
|
54
|
+
abort("\n")
|
55
|
+
end
|
56
|
+
|
57
|
+
kill_attempts = {}
|
58
|
+
|
59
|
+
loop do
|
60
|
+
logger.info "Checking for naughty processes..."
|
61
|
+
|
62
|
+
results = `passenger-memory-stats`
|
63
|
+
results = results.split("\n").grep(/Rails/)
|
64
|
+
|
65
|
+
results.each do |res|
|
66
|
+
pid, vm_size, vm_size_label, mem_res, *bullshit = res.strip.split(/\s+/)
|
67
|
+
|
68
|
+
# ultimately, we need to have some logic in here that decides when
|
69
|
+
# it's appropriate to do a kill -9. If a process has truly run out of
|
70
|
+
# control (say, it's trying to load a massive table into memory at once)
|
71
|
+
# then we need to be more aggressive with how we terminate the process.
|
72
|
+
if mem_res.to_i >= options[:threshold]
|
73
|
+
if kill_attempts.has_key?(pid)
|
74
|
+
kill_attempts[pid] += 1
|
75
|
+
else
|
76
|
+
kill_attempts[pid] = 1
|
77
|
+
end
|
78
|
+
|
79
|
+
logger.info "Killing process #{pid} using #{mem_res.to_i}mb of ram (Threshold=#{options[:threshold]}mb)"
|
80
|
+
|
81
|
+
# passenger treats the USR1 signal as a graceful shutdown.
|
82
|
+
Process.kill("USR1", pid.to_i)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
sleep options[:interval].to_i
|
87
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: passenger_mon
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Alex Sharp
|
14
|
+
- Rick Bradley
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2011-03-09 00:00:00 -08:00
|
20
|
+
default_executable:
|
21
|
+
dependencies: []
|
22
|
+
|
23
|
+
description: Need to control the memory footprint of your passenger processes. You need passenger_mon, bro.
|
24
|
+
email:
|
25
|
+
- ajsharp@gmail.com
|
26
|
+
executables:
|
27
|
+
- passenger_mon
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README
|
32
|
+
files:
|
33
|
+
- README
|
34
|
+
- bin/passenger_mon
|
35
|
+
has_rdoc: true
|
36
|
+
homepage: https://github.com/ajsharp/passenger_mon
|
37
|
+
licenses: []
|
38
|
+
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
hash: 57
|
50
|
+
segments:
|
51
|
+
- 1
|
52
|
+
- 8
|
53
|
+
- 7
|
54
|
+
version: 1.8.7
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 23
|
61
|
+
segments:
|
62
|
+
- 1
|
63
|
+
- 3
|
64
|
+
- 6
|
65
|
+
version: 1.3.6
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.3.7
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: Rails process monitoring for passenger 3
|
73
|
+
test_files: []
|
74
|
+
|