RailsRemoteControl 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -0
- data/LICENSE.txt +27 -0
- data/Manifest.txt +21 -0
- data/README.txt +38 -0
- data/Rakefile +23 -0
- data/bin/rails_remote_control +6 -0
- data/lib/rails_remote_control.rb +64 -0
- data/lib/rails_remote_control/http_server.rb +68 -0
- data/lib/rails_remote_control/process.rb +59 -0
- data/lib/rails_remote_control/remote.rb +38 -0
- data/lib/rails_remote_control/remote/server.rb +16 -0
- data/lib/rails_remote_control/server.rb +117 -0
- data/lib/rails_remote_control/servlet.rb +207 -0
- data/test/test_rails_remote_control.rb +0 -0
- data/test/test_rails_remote_control_http_server.rb +16 -0
- data/test/test_rails_remote_control_process.rb +93 -0
- data/test/test_rails_remote_control_remote.rb +42 -0
- data/test/test_rails_remote_control_remote_server.rb +17 -0
- data/test/test_rails_remote_control_server.rb +80 -0
- data/test/test_rails_remote_control_servlet.rb +230 -0
- data/test/util.rb +39 -0
- metadata +107 -0
data/History.txt
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Copyright 2006 Eric Hodel, The Robot Co-op. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
4
|
+
modification, are permitted provided that the following conditions
|
5
|
+
are met:
|
6
|
+
|
7
|
+
1. Redistributions of source code must retain the above copyright
|
8
|
+
notice, this list of conditions and the following disclaimer.
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright
|
10
|
+
notice, this list of conditions and the following disclaimer in the
|
11
|
+
documentation and/or other materials provided with the distribution.
|
12
|
+
3. Neither the names of the authors nor the names of their contributors
|
13
|
+
may be used to endorse or promote products derived from this software
|
14
|
+
without specific prior written permission.
|
15
|
+
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
|
17
|
+
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
19
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
|
20
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
21
|
+
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
22
|
+
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
23
|
+
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
24
|
+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
25
|
+
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
26
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
|
data/Manifest.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
History.txt
|
2
|
+
LICENSE.txt
|
3
|
+
Manifest.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile
|
6
|
+
bin/rails_remote_control
|
7
|
+
lib/rails_remote_control.rb
|
8
|
+
lib/rails_remote_control/http_server.rb
|
9
|
+
lib/rails_remote_control/process.rb
|
10
|
+
lib/rails_remote_control/remote.rb
|
11
|
+
lib/rails_remote_control/remote/server.rb
|
12
|
+
lib/rails_remote_control/server.rb
|
13
|
+
lib/rails_remote_control/servlet.rb
|
14
|
+
test/test_rails_remote_control.rb
|
15
|
+
test/test_rails_remote_control_http_server.rb
|
16
|
+
test/test_rails_remote_control_process.rb
|
17
|
+
test/test_rails_remote_control_remote.rb
|
18
|
+
test/test_rails_remote_control_remote_server.rb
|
19
|
+
test/test_rails_remote_control_server.rb
|
20
|
+
test/test_rails_remote_control_servlet.rb
|
21
|
+
test/util.rb
|
data/README.txt
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
RailsRemoteControl by Eric Hodel <drbrain@segment7.net>
|
2
|
+
|
3
|
+
http://seattlerb.rubyforge.org/RailsRemoteControl
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Rails Remote Control allows you to attach to running Rails processes
|
8
|
+
using DRb and change the log level without restarts. Also, view
|
9
|
+
actions handled per process.
|
10
|
+
|
11
|
+
== FEATURES/PROBLEMS:
|
12
|
+
|
13
|
+
* Monitor processes
|
14
|
+
* Control process log level without restarts
|
15
|
+
* Logs actions handled and count per process
|
16
|
+
|
17
|
+
== SYNOPSYS:
|
18
|
+
|
19
|
+
See RailsRemoteControl:
|
20
|
+
|
21
|
+
ri RailsRemoteControl
|
22
|
+
|
23
|
+
== REQUIREMENTS:
|
24
|
+
|
25
|
+
* A Rails project
|
26
|
+
* DRb connectivity
|
27
|
+
* RingyDingy (gem)
|
28
|
+
|
29
|
+
== INSTALL:
|
30
|
+
|
31
|
+
First install the gem:
|
32
|
+
|
33
|
+
$ sudo gem install RailsRemoteControl
|
34
|
+
|
35
|
+
Then read and follow the RailsRemoteControl installation instructions:
|
36
|
+
|
37
|
+
$ ri RailsRemoteControl
|
38
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
|
6
|
+
$:.unshift 'lib'
|
7
|
+
require 'rails_remote_control'
|
8
|
+
|
9
|
+
hoe = Hoe.new('RailsRemoteControl', RailsRemoteControl::VERSION) do |p|
|
10
|
+
p.summary = 'Alter Rails log levels and monitor processes without restarts'
|
11
|
+
p.description = File.read('README.txt').scan(/== DESCRIPTION:(.*?)==/m).first.first.strip
|
12
|
+
p.author = 'Eric Hodel'
|
13
|
+
p.email = 'drbrain@segment7.net'
|
14
|
+
p.rubyforge_name = 'seattlerb'
|
15
|
+
p.url = 'http://seattlerb.rubyforge.org/RailsRemoteControl'
|
16
|
+
p.changes = File.read('History.txt').scan(/\A(=.*?)(=|\Z)/m).first.first
|
17
|
+
|
18
|
+
p.extra_deps << ['RingyDingy', '>= 1.2.0']
|
19
|
+
p.extra_deps << ['ZenTest', '>= 3.4.2']
|
20
|
+
p.extra_deps << ['actionpack', '>= 1.12.5']
|
21
|
+
end
|
22
|
+
|
23
|
+
# vim: syntax=Ruby
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
##
|
4
|
+
# RailsRemoteControl allows you to monitor individual Rails processes and
|
5
|
+
# adjust the log level of a process for debugging purposes. (For example, to
|
6
|
+
# turn on partial rendering times for a single process.)
|
7
|
+
#
|
8
|
+
# = Installation
|
9
|
+
#
|
10
|
+
# First, start a RailsRemoteControl::Server when your Rails process starts up
|
11
|
+
# by adding these two lines to config/environment.rb:
|
12
|
+
#
|
13
|
+
# require 'rails_remote_control/server'
|
14
|
+
# RailsRemoteControl::Server.run 'my_rails_app'
|
15
|
+
#
|
16
|
+
# Next, add <tt>include RailsRemoteControl::Process</tt> in Application
|
17
|
+
# controller:
|
18
|
+
#
|
19
|
+
# require 'rails_remote_control/process'
|
20
|
+
#
|
21
|
+
# class ApplicationController < ActionController::Base
|
22
|
+
#
|
23
|
+
# include RailsRemoteControl::Process
|
24
|
+
#
|
25
|
+
# # ...
|
26
|
+
#
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# = Usage
|
30
|
+
#
|
31
|
+
# Then start up a RingServer where you want to monitor and control your remote
|
32
|
+
# processes:
|
33
|
+
#
|
34
|
+
# $ ring_server -d
|
35
|
+
#
|
36
|
+
# You can start the RingServer up before or after the Rails app. The rails
|
37
|
+
# processes will automatically connect soon after it starts.
|
38
|
+
#
|
39
|
+
# Then start up the RailsRemoteControl::HTTPServer so you can control your
|
40
|
+
# processes:
|
41
|
+
#
|
42
|
+
# $ rails_remote_control -d
|
43
|
+
#
|
44
|
+
# Then connect with your web browser to port 8000 on that machine.
|
45
|
+
#
|
46
|
+
# = It Doesn't Work
|
47
|
+
#
|
48
|
+
# * Do you have forward and reverse DNS set up for all your machines?
|
49
|
+
# $ host `hostname`
|
50
|
+
# ziz.jijo.segment7.net has address 10.101.28.1
|
51
|
+
# $ host 10.101.28.1
|
52
|
+
# 1.28.101.10.in-addr.arpa domain name pointer ziz.jijo.segment7.net.
|
53
|
+
# Both forward and reverse addresses need to match here.
|
54
|
+
# * Have you disabled IPv6 or set up RDNS for your IPv6 hosts?
|
55
|
+
|
56
|
+
module RailsRemoteControl
|
57
|
+
|
58
|
+
##
|
59
|
+
# The version of RailsRemoteControl you have installed.
|
60
|
+
|
61
|
+
VERSION = '1.0.0'
|
62
|
+
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rails_remote_control'
|
2
|
+
require 'rails_remote_control/servlet'
|
3
|
+
require 'webrick/httpserver'
|
4
|
+
|
5
|
+
##
|
6
|
+
# RailsRemoteControl HTTP server.
|
7
|
+
#
|
8
|
+
# This provides the console for monitoring and modifying your Rails processes.
|
9
|
+
# By default it runs on port 8000.
|
10
|
+
|
11
|
+
class RailsRemoteControl::HTTPServer < WEBrick::HTTPServer
|
12
|
+
|
13
|
+
@server = nil
|
14
|
+
|
15
|
+
##
|
16
|
+
# Processes ARGV style +args+ into an options Hash.
|
17
|
+
|
18
|
+
def self.process_args(args)
|
19
|
+
options = {}
|
20
|
+
options[:Daemon] = false
|
21
|
+
options[:Port] = 8000
|
22
|
+
|
23
|
+
opts = OptionParser.new do |opts|
|
24
|
+
opts.banner = "Usage: #{name} [options]"
|
25
|
+
opts.on("-p", "--port=PORT",
|
26
|
+
"RailsRemoteControl HTTP Server Port", Integer) do |port|
|
27
|
+
options[:Port] = port
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on("-d", "--daemon",
|
31
|
+
"Run as a daemon process") do |daemon|
|
32
|
+
options[:Daemon] = true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.parse! args
|
37
|
+
|
38
|
+
return options
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Start and run a RailsRemoteControl HTTP server, depending upon +args+.
|
43
|
+
|
44
|
+
def self.run(args = ARGV)
|
45
|
+
options = process_args args
|
46
|
+
|
47
|
+
if options[:Daemon] then
|
48
|
+
WEBrick::Daemon.start
|
49
|
+
end
|
50
|
+
|
51
|
+
@server = new :Port => options[:Port]
|
52
|
+
@server.mount '/', RailsRemoteControl::Servlet
|
53
|
+
|
54
|
+
trap 'INT' do stop end
|
55
|
+
trap 'KILL' do stop end
|
56
|
+
|
57
|
+
@server.start
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Stop the RailsRemoteControl HTTP server.
|
62
|
+
|
63
|
+
def self.stop
|
64
|
+
@server.stop
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rails_remote_control'
|
2
|
+
|
3
|
+
##
|
4
|
+
# RailsRemoteControl::Process records statistics of a running Rails process.
|
5
|
+
#
|
6
|
+
# Include it in your ApplicationController to record these statistics:
|
7
|
+
#
|
8
|
+
# require 'rails_remote_control/process'
|
9
|
+
#
|
10
|
+
# class ApplicationController < ActionController::Base
|
11
|
+
#
|
12
|
+
# include RailsRemoteControl::Process
|
13
|
+
#
|
14
|
+
# end
|
15
|
+
|
16
|
+
module RailsRemoteControl::Process
|
17
|
+
|
18
|
+
@requests_attempted = 0
|
19
|
+
@requests_handled = 0
|
20
|
+
|
21
|
+
@requests = Hash.new { |h,full_action_name| h[full_action_name] = 0 }
|
22
|
+
|
23
|
+
class << self
|
24
|
+
|
25
|
+
##
|
26
|
+
# Hash mapping action names to times handled.
|
27
|
+
|
28
|
+
attr_reader :requests
|
29
|
+
|
30
|
+
##
|
31
|
+
# Requests attempted
|
32
|
+
|
33
|
+
attr_accessor :requests_attempted
|
34
|
+
|
35
|
+
##
|
36
|
+
# Requests successfully handled
|
37
|
+
|
38
|
+
attr_accessor :requests_handled
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# ActionController::Base#process wrapper that records statistics for actions
|
44
|
+
# handled by this Rails process.
|
45
|
+
|
46
|
+
def process(req, res)
|
47
|
+
RailsRemoteControl::Process.requests_attempted += 1
|
48
|
+
|
49
|
+
result = super
|
50
|
+
|
51
|
+
RailsRemoteControl::Process.requests_handled += 1
|
52
|
+
full_action_name = "#{self.class.name}##{action_name}"
|
53
|
+
RailsRemoteControl::Process.requests[full_action_name] += 1
|
54
|
+
|
55
|
+
return result
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rails_remote_control'
|
2
|
+
require 'ringy_dingy/ring_server'
|
3
|
+
require 'rails_remote_control/server'
|
4
|
+
|
5
|
+
##
|
6
|
+
# RailsRemoteControl process locater.
|
7
|
+
|
8
|
+
class RailsRemoteControl::Remote
|
9
|
+
|
10
|
+
##
|
11
|
+
# Remote server struct
|
12
|
+
|
13
|
+
Server = Struct.new :host, :pid, :remote_server
|
14
|
+
|
15
|
+
##
|
16
|
+
# Looks for services on the RingServer and returns an Array of discovered
|
17
|
+
# Rails processes.
|
18
|
+
|
19
|
+
def services
|
20
|
+
services = RingyDingy::RingServer.list_services
|
21
|
+
return [] if services.empty?
|
22
|
+
|
23
|
+
services = RingyDingy::RingServer.list_services.values.first.uniq
|
24
|
+
|
25
|
+
rrc_servers = services.select do |_, klass,|
|
26
|
+
klass == RailsRemoteControl::Server::RINGY_DINGY_SERVICE
|
27
|
+
end
|
28
|
+
|
29
|
+
rrc_servers.map do |_, _, server, name|
|
30
|
+
host, pid, = name.split '_', 3
|
31
|
+
Server.new host, pid.to_i, server
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
require 'rails_remote_control/remote/server'
|
38
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails_remote_control/remote'
|
2
|
+
|
3
|
+
##
|
4
|
+
# RailsRemoteControl remote server convenience wrapper.
|
5
|
+
|
6
|
+
class RailsRemoteControl::Remote::Server
|
7
|
+
|
8
|
+
##
|
9
|
+
# Dispatch other messages to the remote server.
|
10
|
+
|
11
|
+
def method_missing(*args, &block)
|
12
|
+
remote_server.send(*args, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'English'
|
2
|
+
require 'logger'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'ringy_dingy'
|
5
|
+
require 'rails_remote_control'
|
6
|
+
require 'rails_remote_control/process'
|
7
|
+
|
8
|
+
##
|
9
|
+
# RailsRemoteControl server process. Run this from config/environment.rb to
|
10
|
+
# allow RailsRemoteControl::Remote to find the Rails processes you are
|
11
|
+
# running.
|
12
|
+
#
|
13
|
+
# = Example
|
14
|
+
#
|
15
|
+
# Add the following lines to config/environment.rb for your application:
|
16
|
+
#
|
17
|
+
# require 'rails_remote_control/server'
|
18
|
+
# RailsRemoteControl::Server.run 'my_rails_app'
|
19
|
+
|
20
|
+
class RailsRemoteControl::Server
|
21
|
+
|
22
|
+
##
|
23
|
+
# Service name for RingyDingy
|
24
|
+
|
25
|
+
RINGY_DINGY_SERVICE = name.delete(':').intern
|
26
|
+
|
27
|
+
##
|
28
|
+
# Run as +name+.
|
29
|
+
|
30
|
+
def self.run(name = nil)
|
31
|
+
new(name).run
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Creates a new RailsRemoteControl server as +name+.
|
36
|
+
#
|
37
|
+
# Use +name+ to disambiguate multiple Rails applications.
|
38
|
+
|
39
|
+
def initialize(name)
|
40
|
+
@name = name
|
41
|
+
@ringy_dingy = RingyDingy.new self, RINGY_DINGY_SERVICE, name
|
42
|
+
@pid = $PID
|
43
|
+
@host = Socket.gethostname
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Start running
|
48
|
+
|
49
|
+
def run
|
50
|
+
@ringy_dingy.run
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Returns the current log level of the default logger for this Rails
|
55
|
+
# process.
|
56
|
+
|
57
|
+
def log_level
|
58
|
+
RAILS_DEFAULT_LOGGER.level
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# Sets the current log level of the default logger for this Rails process to
|
63
|
+
# +level+.
|
64
|
+
|
65
|
+
def log_level=(level)
|
66
|
+
RAILS_DEFAULT_LOGGER.level = level
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# A Hash mapping action names to number of requests handled.
|
71
|
+
#
|
72
|
+
# See RailsRemoteControl::Process#requests.
|
73
|
+
|
74
|
+
def requests
|
75
|
+
RailsRemoteControl::Process.requests
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Number of requests attempted by this Rails process.
|
80
|
+
|
81
|
+
def requests_attempted
|
82
|
+
RailsRemoteControl::Process.requests_attempted
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Number of requests handled by this Rails process. (If this number is
|
87
|
+
# different from #requests_attempted something bad happened, check your
|
88
|
+
# logs.)
|
89
|
+
|
90
|
+
def requests_handled
|
91
|
+
RailsRemoteControl::Process.requests_handled
|
92
|
+
end
|
93
|
+
|
94
|
+
def ==(other) # :nodoc:
|
95
|
+
self.class === other and other.name == self.name and
|
96
|
+
other.host == self.host and other.pid == self.pid
|
97
|
+
end
|
98
|
+
|
99
|
+
protected
|
100
|
+
|
101
|
+
##
|
102
|
+
# Name of this Rails process.
|
103
|
+
|
104
|
+
attr_reader :name
|
105
|
+
|
106
|
+
##
|
107
|
+
# Host this Rails process is running on.
|
108
|
+
|
109
|
+
attr_reader :host
|
110
|
+
|
111
|
+
##
|
112
|
+
# Process id for this Rails process.
|
113
|
+
|
114
|
+
attr_reader :pid
|
115
|
+
|
116
|
+
end
|
117
|
+
|
@@ -0,0 +1,207 @@
|
|
1
|
+
$TESTING = false unless defined? $TESTING
|
2
|
+
|
3
|
+
require 'webrick/httpservlet/abstract'
|
4
|
+
require 'webrick/httpstatus'
|
5
|
+
require 'rails_remote_control'
|
6
|
+
require 'rails_remote_control/remote'
|
7
|
+
require 'logger'
|
8
|
+
|
9
|
+
##
|
10
|
+
# RailsRemoteControl WEBrick servlet for process monitoring and control.
|
11
|
+
|
12
|
+
class RailsRemoteControl::Servlet < WEBrick::HTTPServlet::AbstractServlet
|
13
|
+
|
14
|
+
logger_levels = Logger::Severity.constants.map do |c|
|
15
|
+
[Logger::Severity.const_get(c), c]
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# Map Logger's log levels to friendly names
|
20
|
+
|
21
|
+
LOGGER_LEVELS = logger_levels.sort_by { |l,n| l }
|
22
|
+
|
23
|
+
@services = nil
|
24
|
+
@services_thread = nil
|
25
|
+
|
26
|
+
##
|
27
|
+
# Accessor for services cache
|
28
|
+
|
29
|
+
def self.services
|
30
|
+
@services
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Fetching a list of services will block for five seconds, so do that in a
|
35
|
+
# separate thread and cache the results. This method is called at require
|
36
|
+
# time.
|
37
|
+
|
38
|
+
def self.start_services_thread
|
39
|
+
@services_thread = Thread.start do
|
40
|
+
remote = RailsRemoteControl::Remote.new
|
41
|
+
|
42
|
+
loop do
|
43
|
+
@services = remote.services
|
44
|
+
sleep 10
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
sleep 0.1 while @services.nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
start_services_thread unless $TESTING
|
52
|
+
|
53
|
+
def do_GET(req, res) # :nodoc:
|
54
|
+
case req.request_uri.request_uri
|
55
|
+
when '/' then
|
56
|
+
res.body = list
|
57
|
+
when %r%\A/server/([^/]+)/(\d+)\Z%
|
58
|
+
res.body = server $1, $2.to_i
|
59
|
+
else
|
60
|
+
super
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def do_POST(req, res) # :nodoc:
|
65
|
+
case req.request_uri.request_uri
|
66
|
+
when %r%\A/server/([^/]+)/(\d+)/log_level\Z%
|
67
|
+
host, pid = $1, $2.to_i
|
68
|
+
req.body =~ /log_level=(\d+)/
|
69
|
+
level = Integer($1) rescue nil
|
70
|
+
res.body = set_log_level host, pid, level
|
71
|
+
else
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Displays a list of rails processes available for remote control.
|
78
|
+
|
79
|
+
def list
|
80
|
+
out = "<title>No Processes</title>\n"
|
81
|
+
out << "<h1>No Processes</h1>\n"
|
82
|
+
out << "<p>Did you start ring_server?"
|
83
|
+
out << "<p>Did you start rails_remote_control?\n"
|
84
|
+
out << "<p>Did you set up your Rails application for monitoring?\n"
|
85
|
+
return out if services.nil?
|
86
|
+
|
87
|
+
out = []
|
88
|
+
out << "<title>Active Processes</title>"
|
89
|
+
out << "<h1>Active Processes</h1>"
|
90
|
+
out << nil
|
91
|
+
out << '<table>'
|
92
|
+
out << '<tr><th colspan=2> <th colspan=2>Requests<th> '
|
93
|
+
out << '<tr><th>Host<th>Process<th>Attempted<th>Handled<th>Log Level'
|
94
|
+
|
95
|
+
services.each do |server|
|
96
|
+
row = server_row server
|
97
|
+
out << row if row
|
98
|
+
end
|
99
|
+
|
100
|
+
out << '</table>' << nil
|
101
|
+
|
102
|
+
out.join "\n"
|
103
|
+
end
|
104
|
+
|
105
|
+
##
|
106
|
+
# Displays information about process +pid+ on +host+.
|
107
|
+
|
108
|
+
def server(host, pid)
|
109
|
+
server = get_server host, pid
|
110
|
+
|
111
|
+
out = []
|
112
|
+
out << "<title>#{host} pid #{pid}</title>"
|
113
|
+
out << "<h1>#{host} pid #{pid}</h1>"
|
114
|
+
out << nil
|
115
|
+
|
116
|
+
out << '<a href="/">Active Processes</a>'
|
117
|
+
out << nil
|
118
|
+
|
119
|
+
out << '<table>'
|
120
|
+
out << "<tr><th>Log Level<td>#{server.log_level}"
|
121
|
+
out << "<tr><th>Requests Attempted<td>#{server.requests_attempted}"
|
122
|
+
out << "<tr><th>Requests Handled<td>#{server.requests_handled}"
|
123
|
+
out << '</table>' << nil
|
124
|
+
|
125
|
+
out << "<form method=\"post\" action=\"/server/#{host}/#{pid}/log_level\">"
|
126
|
+
out << '<div>'
|
127
|
+
out << '<label for="log_level">Change Log Level</label>'
|
128
|
+
out << '<select id="log_level" name="log_level">'
|
129
|
+
|
130
|
+
LOGGER_LEVELS.each do |level, name|
|
131
|
+
selected = server.log_level == level ? ' selected' : nil
|
132
|
+
out << "<option#{selected} value=\"#{level}\">#{name}</option>"
|
133
|
+
end
|
134
|
+
|
135
|
+
out << '</select>'
|
136
|
+
out << '<input type="submit" value="Change">'
|
137
|
+
out << '</div>' << '</form>' << nil
|
138
|
+
|
139
|
+
unless server.requests.empty? then
|
140
|
+
out << '<table>'
|
141
|
+
out << "<tr><th>Action<th>Requests Handled"
|
142
|
+
server.requests.sort_by { |a,c| -c }.each do |action, count|
|
143
|
+
out << "<tr><td>#{action}<td>#{count}"
|
144
|
+
end
|
145
|
+
out << '</table>' << nil
|
146
|
+
end
|
147
|
+
|
148
|
+
out.join "\n"
|
149
|
+
rescue DRb::DRbConnError
|
150
|
+
raise WEBrick::HTTPStatus::NotFound, "#{host}:#{pid} is no longer reachable"
|
151
|
+
rescue NoMethodError
|
152
|
+
raise WEBrick::HTTPStatus::NotFound, "#{host}:#{pid} has gone away"
|
153
|
+
end
|
154
|
+
|
155
|
+
def service(req, res) # :nodoc:
|
156
|
+
@req = req
|
157
|
+
@res = res
|
158
|
+
@res.content_type = 'text/html'
|
159
|
+
super
|
160
|
+
end
|
161
|
+
|
162
|
+
##
|
163
|
+
# Services accessor
|
164
|
+
|
165
|
+
def services
|
166
|
+
self.class.services
|
167
|
+
end
|
168
|
+
|
169
|
+
##
|
170
|
+
# Construct a table row with information on +server+.
|
171
|
+
|
172
|
+
def server_row(server)
|
173
|
+
tr = []
|
174
|
+
tr << "<td>#{server.host}"
|
175
|
+
tr << "<td><a href=\"/server/#{server.host}/#{server.pid}\">#{server.pid}</a>"
|
176
|
+
tr << "<td>#{server.requests_attempted}"
|
177
|
+
tr << "<td>#{server.requests_handled}"
|
178
|
+
tr << "<td>#{server.log_level}"
|
179
|
+
|
180
|
+
"<tr>#{tr.join}"
|
181
|
+
|
182
|
+
rescue DRb::DRbConnError
|
183
|
+
nil
|
184
|
+
end
|
185
|
+
|
186
|
+
##
|
187
|
+
# Sets the log level for process +pid+ on +host+ to +level+.
|
188
|
+
|
189
|
+
def set_log_level(host, pid, level)
|
190
|
+
server = get_server host, pid
|
191
|
+
server.log_level = level
|
192
|
+
@res.set_redirect WEBrick::HTTPStatus::SeeOther, "/server/#{host}/#{pid}"
|
193
|
+
rescue DRb::DRbConnError
|
194
|
+
raise WEBrick::HTTPStatus::NotFound, "#{host}:#{pid} is no longer reachable"
|
195
|
+
rescue NoMethodError
|
196
|
+
raise WEBrick::HTTPStatus::NotFound, "#{host}:#{pid} has gone away"
|
197
|
+
end
|
198
|
+
|
199
|
+
##
|
200
|
+
# Retrieves the server for process +pid+ on +host+.
|
201
|
+
|
202
|
+
def get_server(host, pid)
|
203
|
+
services.find { |s| s.host == host and s.pid == pid }
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
$TESTING = true
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rails_remote_control/http_server'
|
5
|
+
|
6
|
+
class TestRailsRemoteControlHTTPServer < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_self_process_args
|
9
|
+
options = RailsRemoteControl::HTTPServer.process_args %w[-d -p 80]
|
10
|
+
|
11
|
+
expected = { :Daemon => true, :Port => 80 }
|
12
|
+
assert_equal expected, options
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
module ActionController; end
|
4
|
+
class ActionController::Base
|
5
|
+
|
6
|
+
attr_reader :action_name
|
7
|
+
|
8
|
+
def self.process(req, res)
|
9
|
+
new.process req, res
|
10
|
+
end
|
11
|
+
|
12
|
+
def process(req, res)
|
13
|
+
params = req.parameters
|
14
|
+
@action_name = params['action']
|
15
|
+
end
|
16
|
+
|
17
|
+
def controller_class_name
|
18
|
+
self.class.name.split('::').last
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'rails_remote_control/process'
|
24
|
+
|
25
|
+
class ApplicationController < ActionController::Base
|
26
|
+
include RailsRemoteControl::Process
|
27
|
+
end
|
28
|
+
|
29
|
+
class MyController < ApplicationController
|
30
|
+
|
31
|
+
def index
|
32
|
+
end
|
33
|
+
|
34
|
+
def show
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
module Nested; end
|
40
|
+
class Nested::MyController < ApplicationController
|
41
|
+
|
42
|
+
def index
|
43
|
+
end
|
44
|
+
|
45
|
+
def show
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
module RailsRemoteControl
|
51
|
+
def Process.reset
|
52
|
+
@requests_handled = 0
|
53
|
+
@requests_attempted = 0
|
54
|
+
@requests.clear
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class TestRailsRemoteControlProcess < Test::Unit::TestCase
|
59
|
+
|
60
|
+
RRCP = RailsRemoteControl::Process
|
61
|
+
|
62
|
+
FakeRequest = Struct.new :parameters
|
63
|
+
|
64
|
+
def setup
|
65
|
+
@request = FakeRequest.new
|
66
|
+
@request.parameters = { 'action' => 'index' }
|
67
|
+
end
|
68
|
+
|
69
|
+
def teardown
|
70
|
+
RRCP.reset
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_process
|
74
|
+
MyController.new.process @request, nil
|
75
|
+
|
76
|
+
assert_equal 1, RRCP.requests_handled
|
77
|
+
assert_equal 1, RRCP.requests_attempted
|
78
|
+
|
79
|
+
expected = { 'MyController#index' => 1 }
|
80
|
+
assert_equal expected, RRCP.requests
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_process_nested
|
84
|
+
Nested::MyController.new.process @request, nil
|
85
|
+
|
86
|
+
assert_equal 1, RRCP.requests_handled
|
87
|
+
|
88
|
+
expected = { 'Nested::MyController#index' => 1 }
|
89
|
+
assert_equal expected, RRCP.requests
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
$TESTING = true
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rails_remote_control/remote'
|
5
|
+
require 'test/util'
|
6
|
+
|
7
|
+
class TestRailsRemoteControlRemote < Test::Unit::TestCase
|
8
|
+
|
9
|
+
RRCR = RailsRemoteControl::Remote
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@remote = RRCR.new
|
13
|
+
RingyDingy::RingServer.default = RingyDingy::RingServer::DEFAULT
|
14
|
+
end
|
15
|
+
|
16
|
+
def teardown
|
17
|
+
RingyDingy::RingServer.default = RingyDingy::RingServer::DEFAULT
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_services
|
21
|
+
RingyDingy::RingServer.default = RingyDingy::RingServer::DEFAULT
|
22
|
+
|
23
|
+
expected = [
|
24
|
+
RRCR::Server.new('cutie', 1000,
|
25
|
+
RailsRemoteControl::Server.new('43places')),
|
26
|
+
RRCR::Server.new('cutie', 1001,
|
27
|
+
RailsRemoteControl::Server.new('43places')),
|
28
|
+
RRCR::Server.new('hal', 61000,
|
29
|
+
RailsRemoteControl::Server.new('43things')),
|
30
|
+
]
|
31
|
+
|
32
|
+
assert_equal expected, @remote.services
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_services_no_services
|
36
|
+
RingyDingy::RingServer.default = {}
|
37
|
+
|
38
|
+
assert_equal [], @remote.services
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rails_remote_control/server'
|
3
|
+
require 'rails_remote_control/remote/server'
|
4
|
+
|
5
|
+
class TestRailsRemoteControlRemoteServer < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@server = RailsRemoteControl::Server.new 'name'
|
9
|
+
@remote_server = RailsRemoteControl::Remote::Server.new 'localhost', $$, @server
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_method_missing
|
13
|
+
assert_equal 0, @remote_server.requests_handled
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'test/zentest_assertions'
|
4
|
+
require 'test/util'
|
5
|
+
|
6
|
+
require 'rails_remote_control/server'
|
7
|
+
|
8
|
+
class RailsRemoteControl::Server
|
9
|
+
attr_reader :ringy_dingy
|
10
|
+
public :host, :name, :pid
|
11
|
+
end
|
12
|
+
|
13
|
+
class TestRailsRemoteControlServer < Test::Unit::TestCase
|
14
|
+
|
15
|
+
RRCS = RailsRemoteControl::Server
|
16
|
+
|
17
|
+
def setup
|
18
|
+
@name = 'RailsRemoteControl::Server test'
|
19
|
+
@server = RRCS.new @name
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_equal
|
23
|
+
server = RRCS.new @name
|
24
|
+
|
25
|
+
assert_equal server, @server
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_host
|
29
|
+
assert_equal Socket.gethostname, @server.host
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_initialize
|
33
|
+
deny_nil @server.ringy_dingy
|
34
|
+
assert_equal "#{Socket.gethostname.downcase}_#{$PID}_#{@name}",
|
35
|
+
@server.ringy_dingy.identifier
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_log_level
|
39
|
+
assert_equal Logger::DEBUG, @server.log_level
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_log_level_equals
|
43
|
+
level = @server.log_level
|
44
|
+
@server.log_level = Logger::FATAL
|
45
|
+
assert_equal Logger::FATAL, @server.log_level
|
46
|
+
assert_equal Logger::FATAL, RAILS_DEFAULT_LOGGER.level
|
47
|
+
ensure
|
48
|
+
@server.log_level = level
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_name
|
52
|
+
assert_equal @name, @server.name
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_pid
|
56
|
+
assert_equal $$, @server.pid
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_requests
|
60
|
+
assert_equal Hash.new, @server.requests
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_requests_attempted
|
64
|
+
assert_equal 0, @server.requests_attempted
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_requests_handled
|
68
|
+
assert_equal 0, @server.requests_handled
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_run
|
72
|
+
assert_nil @server.ringy_dingy.thread
|
73
|
+
@server.run
|
74
|
+
deny_nil @server.ringy_dingy.thread
|
75
|
+
end
|
76
|
+
|
77
|
+
alias deny_nil assert_not_nil # HACK ZenTest 3.4.2
|
78
|
+
|
79
|
+
end
|
80
|
+
|
@@ -0,0 +1,230 @@
|
|
1
|
+
$TESTING = true
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'stringio'
|
5
|
+
require 'test/util'
|
6
|
+
|
7
|
+
require 'rails_remote_control/servlet'
|
8
|
+
|
9
|
+
require 'webrick/httprequest'
|
10
|
+
require 'webrick/httpresponse'
|
11
|
+
|
12
|
+
class FakeWEBrickServer
|
13
|
+
def [](arg); end
|
14
|
+
end
|
15
|
+
|
16
|
+
class RailsRemoteControl::Servlet
|
17
|
+
def self.services=(services)
|
18
|
+
@services = services
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class TestRailsRemoteControlServlet < Test::Unit::TestCase
|
23
|
+
|
24
|
+
RRCRS = RailsRemoteControl::Remote::Server
|
25
|
+
RRCS = RailsRemoteControl::Servlet
|
26
|
+
|
27
|
+
def setup
|
28
|
+
@server = RailsRemoteControl::Server.new 'name'
|
29
|
+
@dead_server = RailsRemoteControl::Server.new 'name'
|
30
|
+
def @dead_server.requests_attempted() raise DRb::DRbConnError; end
|
31
|
+
RRCS.services = [
|
32
|
+
RRCRS.new('cutie', 1000, @server),
|
33
|
+
RRCRS.new('cutie', 1001, @server),
|
34
|
+
RRCRS.new('hal', 61000, @server),
|
35
|
+
RRCRS.new('hal', 61001, @dead_server),
|
36
|
+
]
|
37
|
+
|
38
|
+
@http_server = FakeWEBrickServer.new
|
39
|
+
@servlet = RRCS.new @http_server
|
40
|
+
@config = { :Logger => nil, :HTTPVersion => '1.0' }
|
41
|
+
end
|
42
|
+
|
43
|
+
def teardown
|
44
|
+
RailsRemoteControl::Server.new(nil).requests.clear
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_do_GET_list
|
48
|
+
req = WEBrick::HTTPRequest.new @config
|
49
|
+
req.parse StringIO.new("GET / HTTP/1.0\r\n\r\n")
|
50
|
+
res = WEBrick::HTTPResponse.new @config
|
51
|
+
|
52
|
+
def @servlet.list
|
53
|
+
return 'list'
|
54
|
+
end
|
55
|
+
|
56
|
+
@servlet.service req, res
|
57
|
+
|
58
|
+
assert_equal 'list', res.body
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_do_GET_server
|
62
|
+
req = WEBrick::HTTPRequest.new @config
|
63
|
+
req.parse StringIO.new("GET /server/cutie/1000 HTTP/1.0\r\n\r\n")
|
64
|
+
res = WEBrick::HTTPResponse.new @config
|
65
|
+
|
66
|
+
def @servlet.server(host, pid)
|
67
|
+
return "server #{host} #{pid}"
|
68
|
+
end
|
69
|
+
|
70
|
+
@servlet.service req, res
|
71
|
+
|
72
|
+
assert_equal 'server cutie 1000', res.body
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_do_GET_server_with_dot
|
76
|
+
req = WEBrick::HTTPRequest.new @config
|
77
|
+
req.parse StringIO.new("GET /server/kaa.local/1000 HTTP/1.0\r\n\r\n")
|
78
|
+
res = WEBrick::HTTPResponse.new @config
|
79
|
+
|
80
|
+
def @servlet.server(host, pid)
|
81
|
+
return "server %p %p" % [host, pid]
|
82
|
+
end
|
83
|
+
|
84
|
+
@servlet.service req, res
|
85
|
+
|
86
|
+
assert_equal 'server "kaa.local" 1000', res.body
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_do_POST_server_log_level
|
90
|
+
req = WEBrick::HTTPRequest.new @config
|
91
|
+
req.parse StringIO.new("POST /server/cutie/1000/log_level HTTP/1.0\r\nContent-Length: 11\r\n\r\nlog_level=5")
|
92
|
+
res = WEBrick::HTTPResponse.new @config
|
93
|
+
|
94
|
+
def @servlet.set_log_level(host, pid, level)
|
95
|
+
return "server #{host} #{pid} #{level}"
|
96
|
+
end
|
97
|
+
|
98
|
+
@servlet.service req, res
|
99
|
+
|
100
|
+
assert_equal 'server cutie 1000 5', res.body
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_list
|
104
|
+
expected = <<-EOF
|
105
|
+
<title>Active Processes</title>
|
106
|
+
<h1>Active Processes</h1>
|
107
|
+
|
108
|
+
<table>
|
109
|
+
<tr><th colspan=2> <th colspan=2>Requests<th>
|
110
|
+
<tr><th>Host<th>Process<th>Attempted<th>Handled<th>Log Level
|
111
|
+
<tr><td>cutie<td><a href="/server/cutie/1000">1000</a><td>0<td>0<td>0
|
112
|
+
<tr><td>cutie<td><a href="/server/cutie/1001">1001</a><td>0<td>0<td>0
|
113
|
+
<tr><td>hal<td><a href="/server/hal/61000">61000</a><td>0<td>0<td>0
|
114
|
+
</table>
|
115
|
+
EOF
|
116
|
+
|
117
|
+
assert_equal expected, @servlet.list
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_server
|
121
|
+
server = RailsRemoteControl::Server.new 'name'
|
122
|
+
server.requests['RouteController#index'] = 2
|
123
|
+
server.requests['RouteController#route_markers'] = 1
|
124
|
+
RRCS.services = [RRCRS.new('cutie', 1000, server)]
|
125
|
+
|
126
|
+
expected = <<-EOF
|
127
|
+
<title>cutie pid 1000</title>
|
128
|
+
<h1>cutie pid 1000</h1>
|
129
|
+
|
130
|
+
<a href="/">Active Processes</a>
|
131
|
+
|
132
|
+
<table>
|
133
|
+
<tr><th>Log Level<td>0
|
134
|
+
<tr><th>Requests Attempted<td>0
|
135
|
+
<tr><th>Requests Handled<td>0
|
136
|
+
</table>
|
137
|
+
|
138
|
+
<form method="post" action="/server/cutie/1000/log_level">
|
139
|
+
<div>
|
140
|
+
<label for="log_level">Change Log Level</label>
|
141
|
+
<select id="log_level" name="log_level">
|
142
|
+
<option selected value="0">DEBUG</option>
|
143
|
+
<option value="1">INFO</option>
|
144
|
+
<option value="2">WARN</option>
|
145
|
+
<option value="3">ERROR</option>
|
146
|
+
<option value="4">FATAL</option>
|
147
|
+
<option value="5">UNKNOWN</option>
|
148
|
+
</select>
|
149
|
+
<input type="submit" value="Change">
|
150
|
+
</div>
|
151
|
+
</form>
|
152
|
+
|
153
|
+
<table>
|
154
|
+
<tr><th>Action<th>Requests Handled
|
155
|
+
<tr><td>RouteController#index<td>2
|
156
|
+
<tr><td>RouteController#route_markers<td>1
|
157
|
+
</table>
|
158
|
+
EOF
|
159
|
+
|
160
|
+
assert_equal expected, @servlet.server('cutie', 1000)
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_server_dead
|
164
|
+
e = assert_raise WEBrick::HTTPStatus::NotFound do
|
165
|
+
@servlet.server 'hal', 61001
|
166
|
+
end
|
167
|
+
|
168
|
+
assert_equal 'hal:61001 is no longer reachable', e.message
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_server_gone
|
172
|
+
util_test_gone :server
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_server_no_requests
|
176
|
+
expected = <<-EOF
|
177
|
+
<title>cutie pid 1001</title>
|
178
|
+
<h1>cutie pid 1001</h1>
|
179
|
+
|
180
|
+
<a href="/">Active Processes</a>
|
181
|
+
|
182
|
+
<table>
|
183
|
+
<tr><th>Log Level<td>0
|
184
|
+
<tr><th>Requests Attempted<td>0
|
185
|
+
<tr><th>Requests Handled<td>0
|
186
|
+
</table>
|
187
|
+
|
188
|
+
<form method="post" action="/server/cutie/1001/log_level">
|
189
|
+
<div>
|
190
|
+
<label for="log_level">Change Log Level</label>
|
191
|
+
<select id="log_level" name="log_level">
|
192
|
+
<option selected value="0">DEBUG</option>
|
193
|
+
<option value="1">INFO</option>
|
194
|
+
<option value="2">WARN</option>
|
195
|
+
<option value="3">ERROR</option>
|
196
|
+
<option value="4">FATAL</option>
|
197
|
+
<option value="5">UNKNOWN</option>
|
198
|
+
</select>
|
199
|
+
<input type="submit" value="Change">
|
200
|
+
</div>
|
201
|
+
</form>
|
202
|
+
EOF
|
203
|
+
|
204
|
+
assert_equal expected, @servlet.server('cutie', 1001)
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_set_log_level
|
208
|
+
@servlet.instance_variable_set :@res, WEBrick::HTTPResponse.new(@config)
|
209
|
+
|
210
|
+
assert_raise WEBrick::HTTPStatus::SeeOther do
|
211
|
+
@servlet.set_log_level 'cutie', 1000, 5
|
212
|
+
end
|
213
|
+
|
214
|
+
assert_equal 5, @server.log_level
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_set_log_level_no_server
|
218
|
+
util_test_gone :set_log_level, 5
|
219
|
+
end
|
220
|
+
|
221
|
+
def util_test_gone(action, *args)
|
222
|
+
e = assert_raise WEBrick::HTTPStatus::NotFound do
|
223
|
+
@servlet.send(action, 'none', 0, *args)
|
224
|
+
end
|
225
|
+
|
226
|
+
assert_equal 'none:0 has gone away', e.message
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
data/test/util.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'test/zentest_assertions'
|
4
|
+
require 'ringy_dingy/ring_server'
|
5
|
+
require 'rails_remote_control/server'
|
6
|
+
|
7
|
+
RAILS_DEFAULT_LOGGER = Logger.new '/dev/null'
|
8
|
+
|
9
|
+
class RingyDingy::RingServer
|
10
|
+
|
11
|
+
@s1 = RailsRemoteControl::Server.new '43places'
|
12
|
+
@s2 = RailsRemoteControl::Server.new '43places'
|
13
|
+
@s3 = RailsRemoteControl::Server.new '43things'
|
14
|
+
|
15
|
+
DEFAULT = {
|
16
|
+
'druby://localhost:10000' => [
|
17
|
+
[:name, RailsRemoteControl::Server::RINGY_DINGY_SERVICE, @s1,
|
18
|
+
'cutie_1000_43places'],
|
19
|
+
[:name, RailsRemoteControl::Server::RINGY_DINGY_SERVICE, @s2,
|
20
|
+
'cutie_1001_43places'],
|
21
|
+
[:name, RailsRemoteControl::Server::RINGY_DINGY_SERVICE, @s3,
|
22
|
+
'hal_61000_43places'],
|
23
|
+
]
|
24
|
+
}
|
25
|
+
|
26
|
+
def self.default=(default)
|
27
|
+
@default = default
|
28
|
+
end
|
29
|
+
|
30
|
+
class << self
|
31
|
+
remove_method :list_services
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.list_services
|
35
|
+
@default
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0.8
|
3
|
+
specification_version: 1
|
4
|
+
name: RailsRemoteControl
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.0.0
|
7
|
+
date: 2007-01-02 00:00:00 -08:00
|
8
|
+
summary: Alter Rails log levels and monitor processes without restarts
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: drbrain@segment7.net
|
12
|
+
homepage: http://seattlerb.rubyforge.org/RailsRemoteControl
|
13
|
+
rubyforge_project: seattlerb
|
14
|
+
description: Rails Remote Control allows you to attach to running Rails processes using DRb and change the log level without restarts. Also, view actions handled per process.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Eric Hodel
|
31
|
+
files:
|
32
|
+
- History.txt
|
33
|
+
- LICENSE.txt
|
34
|
+
- Manifest.txt
|
35
|
+
- README.txt
|
36
|
+
- Rakefile
|
37
|
+
- bin/rails_remote_control
|
38
|
+
- lib/rails_remote_control.rb
|
39
|
+
- lib/rails_remote_control/http_server.rb
|
40
|
+
- lib/rails_remote_control/process.rb
|
41
|
+
- lib/rails_remote_control/remote.rb
|
42
|
+
- lib/rails_remote_control/remote/server.rb
|
43
|
+
- lib/rails_remote_control/server.rb
|
44
|
+
- lib/rails_remote_control/servlet.rb
|
45
|
+
- test/test_rails_remote_control.rb
|
46
|
+
- test/test_rails_remote_control_http_server.rb
|
47
|
+
- test/test_rails_remote_control_process.rb
|
48
|
+
- test/test_rails_remote_control_remote.rb
|
49
|
+
- test/test_rails_remote_control_remote_server.rb
|
50
|
+
- test/test_rails_remote_control_server.rb
|
51
|
+
- test/test_rails_remote_control_servlet.rb
|
52
|
+
- test/util.rb
|
53
|
+
test_files:
|
54
|
+
- test/test_rails_remote_control.rb
|
55
|
+
- test/test_rails_remote_control_http_server.rb
|
56
|
+
- test/test_rails_remote_control_process.rb
|
57
|
+
- test/test_rails_remote_control_remote.rb
|
58
|
+
- test/test_rails_remote_control_remote_server.rb
|
59
|
+
- test/test_rails_remote_control_server.rb
|
60
|
+
- test/test_rails_remote_control_servlet.rb
|
61
|
+
rdoc_options: []
|
62
|
+
|
63
|
+
extra_rdoc_files: []
|
64
|
+
|
65
|
+
executables:
|
66
|
+
- rails_remote_control
|
67
|
+
extensions: []
|
68
|
+
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
dependencies:
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: hoe
|
74
|
+
version_requirement:
|
75
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 1.1.6
|
80
|
+
version:
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: RingyDingy
|
83
|
+
version_requirement:
|
84
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 1.2.0
|
89
|
+
version:
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
name: ZenTest
|
92
|
+
version_requirement:
|
93
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 3.4.2
|
98
|
+
version:
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
name: actionpack
|
101
|
+
version_requirement:
|
102
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 1.12.5
|
107
|
+
version:
|