jaswope-mongrel_proctitle 1.4.1.4

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/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2008, Ryan Tomayko
2
+ Copyright (c) 2007, Alexander Staubo
3
+
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without modification, are
7
+ permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice, this list of
10
+ conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright notice, this list
13
+ of conditions and the following disclaimer in the documentation and/or other materials
14
+ provided with the distribution.
15
+
16
+ * The names of its contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND WITHOUT ANY
20
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ POSSIBILITY OF SUCH DAMAGE.
data/README ADDED
@@ -0,0 +1,95 @@
1
+ Mongrel process title GemPlugin
2
+ ===============================
3
+
4
+ This is a simple plugin for Mongrel which changes the process title to reflect
5
+ what it's currently doing. You can then determine a given Mongrel server's
6
+ status using "ps".
7
+
8
+ For example:
9
+
10
+ mongrel_rails [10010/2/5/358]: handling 127.0.0.1: HEAD /feed/cal/global/91/6de4, GET /feed/index
11
+ | | | | | | |
12
+ | | | | | | The current req (method / path)
13
+ | | | | | |
14
+ | | | | | The client IP
15
+ | | | | |
16
+ | | | | What it's doing
17
+ | | | |
18
+ | | | Requests processed during server lifetime
19
+ | | |
20
+ | | Maximum queued requests in the server lifetime
21
+ | |
22
+ | Requests currently queued/being processed concurrently
23
+ |
24
+ The port that Mongrel is serving
25
+
26
+ This is almost entirely based on Alexander Staubo's Rails plugin with the same
27
+ name:
28
+
29
+ http://purefiction.net/mongrel_proctitle/
30
+
31
+ The main difference is that the GemPlugin will automatically be loaded by all
32
+ mongrels without additional code changes or configuration.
33
+
34
+ Monitoring Mongrels
35
+ -------------------
36
+
37
+ Once the program is installed, you should be able to see the formatted process
38
+ title by running:
39
+
40
+ $ ps -axwwo pid,command | grep mongrel_rails
41
+
42
+ See ps(1) for more options. You may want to include %cpu, rsz, %mem, or other
43
+ fields in output.
44
+
45
+ There's also a `mongrel_top` executable included in the gem that works like
46
+ top(1) but displays only mongrel processes:
47
+
48
+ $ mongrel_top
49
+
50
+ By default, `mongrel_top` updates the display every 0.25 seconds and shows the
51
+ pid and process title. You can select a different interval and fields with the
52
+ -s and -o arguments, respectively:
53
+
54
+ $ mongrel_top -s 0.1 -o pid,%cpu,rsz,command
55
+
56
+ The "command" field must be included.
57
+
58
+ Installation
59
+ ------------
60
+
61
+ This version of the plugin is packaged specifically as a Mongrel GemPlugin. Install
62
+ using:
63
+
64
+ gem install mongrel_proctitle --source=http://tomayko.com
65
+
66
+ Once installed, all new mongrels will automatically load the plugin during startup. If
67
+ you would prefer to control which mongrels load the plugin, do not install this gem.
68
+ Use the directions below instead.
69
+
70
+ Installing into a specific Rails app only
71
+ -----------------------------------------
72
+
73
+ See Alexander Staubo's original project:
74
+
75
+ http://purefiction.net/mongrel_proctitle/
76
+
77
+ Showing your application-specific revision/release in the title
78
+ -------------------------------------------------------------------
79
+
80
+ In your application's start-up process, re-open Mongrel::Proctitler
81
+ and define a get_app_revision method. In a Rails app, a good place
82
+ to do this is in RAILS_ROOT/config/environments/production.rb. An
83
+ example get_app_revision method might look like:
84
+
85
+ def get_app_revision
86
+ `cat ./REVISION`.chomp
87
+ end
88
+
89
+ License
90
+ -------
91
+
92
+ I've included the LICENSE file from the original mongrel_proctitle distribution. It is
93
+ the "New and Simplified BSD License". More information on this license can be found at:
94
+
95
+ http://www.opensource.org/licenses/bsd-license.php
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/clean'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/rdoctask'
6
+ require 'rake/contrib/rubyforgepublisher'
7
+ require 'fileutils'
8
+ include FileUtils
9
+
10
+ CLEAN.include [ "pkg", "lib/*.bundle", "*.gem", ".config", "**/*.log" ]
11
+
12
+ desc "Build package"
13
+ task :default => [:package]
14
+
15
+ # Load gemspec like github to surface SAFE issues early
16
+ require 'rubygems/specification'
17
+ data = File.read('mongrel_proctitle.gemspec')
18
+ spec = nil
19
+ Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
20
+
21
+ Rake::GemPackageTask.new(spec) do |p|
22
+ p.gem_spec = spec
23
+ p.need_zip = true
24
+ p.need_tar_gz = true
25
+ end
26
+
27
+ task :install => [:package] do
28
+ sh %{gem install pkg/#{name}-#{version}.gem}
29
+ end
30
+
31
+ task :uninstall => [:clean] do
32
+ sh %{gem uninstall #{name}}
33
+ end
34
+
35
+ desc 'Publish gem and tarball to rubyforge'
36
+ task :release => [:package] do
37
+ pkg = "pkg/#{spec.name}-#{spec.version}"
38
+ sh <<-end
39
+ rubyforge add_release wink #{spec.name} #{spec.version} #{pkg}.gem &&
40
+ rubyforge add_file wink #{spec.name} #{spec.version} #{pkg}.tar.gz
41
+ end
42
+ end
data/bin/mongrel_top ADDED
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $last_update = nil
4
+ $clear_char = `tput clear`
5
+
6
+ def usage
7
+ puts "usage: #{File.basename($0)} [-s delay] [-o fields]"
8
+ end
9
+
10
+ def die(*message)
11
+ STDERR.puts "fatal: #{format(*message)}" if message.any?
12
+ exit 1
13
+ end
14
+
15
+ # clear the terminal
16
+ def clear_screen
17
+ STDOUT.write($clear_char)
18
+ end
19
+
20
+ # clear the terminal and then write output.
21
+ def update_screen(output)
22
+ if output != $last_update
23
+ clear_screen
24
+ puts(output)
25
+ end
26
+ end
27
+
28
+ def terminal_columns
29
+ @terminal_columns ||=
30
+ if (cols = `tput cols`) == ""
31
+ 80
32
+ else
33
+ cols.to_i
34
+ end
35
+ end
36
+
37
+ trap("INT") {
38
+ STDERR.puts "\nbailing ..."
39
+ exit 0
40
+ }
41
+
42
+ # time to wait between updates
43
+ interval = 0.25
44
+
45
+ # the fields to show in our display (see ps -o)
46
+ fields = "pid,command"
47
+
48
+ # parse arguments.
49
+ # TODO: use getoptlong
50
+ argv = ARGV.map { |a| a.split('=', 2) }.flatten
51
+ while argv.any?
52
+ arg = argv.shift
53
+ case arg
54
+ when /^-(s|-delay)$/
55
+ interval = argv.shift.to_f
56
+ when /^-(o|-fields)$/
57
+ fields = argv.shift
58
+ when /^-(h|-help)$/
59
+ usage and exit(0)
60
+ else
61
+ usage and die
62
+ end
63
+ end
64
+
65
+ # Builds the process output display.
66
+ def process_display(fields, interval)
67
+ now = Time.now.strftime('%a %b %d %H:%M:%S %Y')
68
+ cols = terminal_columns
69
+ processes =
70
+ `ps axww -o #{fields}`.grep(/mongrel_rails/).map do |line|
71
+ line.strip!
72
+ line.sub! /\s+SHELL=.*$/, '' # weird MacOS X issue
73
+ line.sub! /(?:ruby\d*: )?mongrel_rails /, '' # remove $0 prefix
74
+ line.sub! /\(ruby\d*\)/, '' # remove (ruby) suffix
75
+ line[0,cols].chomp
76
+ end
77
+ output = [
78
+ (' ' * (cols - now.length)) + now + "\r" +
79
+ "Mongrel Top (delay: #{interval})",
80
+ "",
81
+ processes,
82
+ "",
83
+ "#{processes.length} process(es)"
84
+ ]
85
+ output.flatten.join("\n")
86
+ end
87
+
88
+ while true
89
+ output = process_display(fields, interval)
90
+ update_screen(output)
91
+ sleep(interval)
92
+ end
@@ -0,0 +1,157 @@
1
+ require 'mongrel'
2
+
3
+ module Mongrel
4
+
5
+ # Mongrel process title modification.
6
+ class Proctitler
7
+
8
+ # Initializes titler.
9
+ def initialize(port, prefix)
10
+ @prefix = prefix
11
+ @port = port
12
+ @mutex = Mutex.new
13
+ @titles = []
14
+ @request_threads = []
15
+ @queue_length = 0
16
+ @max_queue_length = 0
17
+ @request_count = 0
18
+ end
19
+
20
+ # Returns port used in title.
21
+ def port
22
+ @port
23
+ end
24
+
25
+ # Return port used in title.
26
+ def port=(new_port)
27
+ @port = new_port
28
+ end
29
+
30
+ # Returns revision used in title.
31
+ def revision
32
+ @revision ||= get_app_revision if self.respond_to?(:get_app_revision)
33
+ end
34
+
35
+ def reset
36
+ @max_queue_length = 0
37
+ update_process_title
38
+ end
39
+
40
+ def request(&block)
41
+ titles, mutex = @titles, @mutex
42
+ mutex.synchronize do
43
+ @queue_length += 1
44
+ @max_queue_length = @queue_length if @queue_length > @max_queue_length
45
+ titles.push(self.title)
46
+ end
47
+ begin
48
+ yield
49
+ ensure
50
+ mutex.synchronize do
51
+ @queue_length -= 1
52
+ @request_count += 1
53
+ @request_threads.delete(Thread.current)
54
+ set_request_list_title
55
+ end
56
+ end
57
+ end
58
+
59
+ def set_request_list_title(excluding = nil)
60
+ if @request_threads.empty?
61
+ set_idle
62
+ else
63
+ if defined?(Rails)
64
+ # find the first awake/critical thread and put it in the front
65
+ running_thread = @request_threads.detect {|thread| thread.status == "run" && excluding != thread }
66
+ @request_threads.unshift(@request_threads.delete(running_thread)) if running_thread
67
+ # this isn't exact, but it works for most situations
68
+ end
69
+ self.title = "handling #{@request_threads.collect {|t| t[:request_str]}.join(', ')}"
70
+ end
71
+ end
72
+
73
+ # Reports process as being idle.
74
+ def set_idle
75
+ self.title = "idle"
76
+ end
77
+
78
+ # Reports process as handling a socket.
79
+ def set_processing(socket)
80
+ self.title = "handling #{socket.peeraddr.last}"
81
+ end
82
+
83
+ # Reports process as handling a socket.
84
+ def set_handling(request)
85
+ params = request.params
86
+ address = params['REMOTE_ADDR']
87
+ method = params['REQUEST_METHOD']
88
+ path = params['REQUEST_PATH']
89
+ path = "#{path[0, 60]}..." if path.length > 60
90
+ Thread.current[:request_str] = "#{address}: #{method} #{path}"
91
+ @request_threads.push(Thread.current)
92
+ set_request_list_title(Thread.current)
93
+ end
94
+
95
+ # Returns current title
96
+ def title
97
+ @title
98
+ end
99
+
100
+ # Sets process title.
101
+ def title=(title)
102
+ @title = title
103
+ update_process_title
104
+ end
105
+
106
+ # Updates the process title.
107
+ def update_process_title
108
+ title = "#{@prefix} ["
109
+ title << (@port ? "#{@port}" : "?")
110
+ title << (revision ? "/r#{revision}" : "")
111
+ title << "/#{@queue_length}"
112
+ title << "/#{@max_queue_length}"
113
+ title << "/#{@request_count}"
114
+ title << "]: #{@title}"
115
+ $0 = title
116
+ end
117
+
118
+ end
119
+
120
+ # Handler which sets process title before request.
121
+ class ProctitleHandler < HttpHandler
122
+ def initialize(titler)
123
+ @titler = titler
124
+ end
125
+
126
+ def process(request, response)
127
+ @titler.set_handling(request)
128
+ end
129
+ end
130
+
131
+ class HttpServer
132
+
133
+ def run_with_proctitle(*args)
134
+ @titler = Proctitler.new(self.port, File.basename($0))
135
+ @titler.set_idle
136
+ trap("CONT") {@titler.reset}
137
+ run_without_proctitle
138
+ end
139
+ alias_method :run_without_proctitle, :run
140
+ alias_method :run, :run_with_proctitle
141
+
142
+ def process_client_with_proctitle(client)
143
+ unless @handler
144
+ @handler = ProctitleHandler.new(@titler)
145
+ register("/", @handler, true)
146
+ end
147
+ @titler.request do
148
+ @titler.set_processing(client)
149
+ return process_client_without_proctitle(client)
150
+ end
151
+ end
152
+ alias_method :process_client_without_proctitle, :process_client
153
+ alias_method :process_client, :process_client_with_proctitle
154
+
155
+ end
156
+
157
+ end
@@ -0,0 +1 @@
1
+ require 'mongrel_proctitle'
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jaswope-mongrel_proctitle
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.4.1.4
5
+ platform: ruby
6
+ authors:
7
+ - Jon Swope
8
+ - Arya Asemanfar
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-05-16 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: mongrel
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "1.1"
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: gem_plugin
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 0.2.3
35
+ version:
36
+ description: The mongrel_proctitle Gem
37
+ email: jaswope@gmail.com
38
+ executables:
39
+ - mongrel_top
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - README
44
+ files:
45
+ - LICENSE
46
+ - README
47
+ - Rakefile
48
+ - bin/mongrel_top
49
+ - lib/mongrel_proctitle.rb
50
+ - lib/mongrel_proctitle/init.rb
51
+ has_rdoc: true
52
+ homepage: http://github.com/jaswope/mongrel_proctitle
53
+ licenses:
54
+ post_install_message:
55
+ rdoc_options: []
56
+
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ requirements: []
72
+
73
+ rubyforge_project:
74
+ rubygems_version: 1.3.5
75
+ signing_key:
76
+ specification_version: 2
77
+ summary: The mongrel_proctitle Gem
78
+ test_files: []
79
+