racknga 0.9.3 → 0.9.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.
- checksums.yaml +7 -0
- data/Gemfile +3 -12
- data/README.textile +9 -8
- data/Rakefile +19 -272
- data/doc/text/news.textile +8 -0
- data/lib/racknga/access_log_parser.rb +1 -1
- data/lib/racknga/api-keys.rb +40 -0
- data/lib/racknga/cache_database.rb +2 -2
- data/lib/racknga/exception_mail_notifier.rb +5 -5
- data/lib/racknga/log_database.rb +1 -1
- data/lib/racknga/log_entry.rb +1 -1
- data/lib/racknga/middleware/auth/api-key.rb +95 -0
- data/lib/racknga/middleware/cache.rb +20 -6
- data/lib/racknga/middleware/deflater.rb +1 -1
- data/lib/racknga/middleware/exception_notifier.rb +1 -1
- data/lib/racknga/middleware/instance_name.rb +65 -12
- data/lib/racknga/middleware/jsonp.rb +24 -5
- data/lib/racknga/middleware/log.rb +1 -1
- data/lib/racknga/middleware/nginx_raw_uri.rb +1 -1
- data/lib/racknga/middleware/range.rb +1 -1
- data/lib/racknga/reverse_line_reader.rb +1 -1
- data/lib/racknga/utils.rb +1 -1
- data/lib/racknga/version.rb +2 -2
- data/lib/racknga.rb +2 -1
- data/munin/plugins/passenger_application_ +61 -47
- data/munin/plugins/passenger_status +64 -33
- data/test/racknga-test-utils.rb +2 -1
- data/test/run-test.rb +1 -3
- data/test/test-access-log-parser.rb +1 -1
- data/test/test-api-keys.rb +80 -0
- data/test/test-middleware-auth-api-key.rb +144 -0
- data/test/test-middleware-cache.rb +1 -1
- data/test/test-middleware-instance-name.rb +32 -10
- data/test/test-middleware-jsonp.rb +14 -2
- data/test/test-middleware-nginx-raw-uri.rb +1 -1
- data/test/test-middleware-range.rb +1 -1
- metadata +156 -156
- data/lib/racknga/will_paginate.rb +0 -48
@@ -14,10 +14,11 @@
|
|
14
14
|
#
|
15
15
|
# You should have received a copy of the GNU Lesser General Public
|
16
16
|
# License along with this library; if not, write to the Free Software
|
17
|
-
# Foundation, Inc.,
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
|
19
19
|
require 'digest'
|
20
20
|
require 'yaml'
|
21
|
+
require 'zlib'
|
21
22
|
require 'racknga/cache_database'
|
22
23
|
|
23
24
|
module Racknga
|
@@ -168,13 +169,15 @@ module Racknga
|
|
168
169
|
now = Time.now
|
169
170
|
headers = Rack::Utils::HeaderHash.new(headers)
|
170
171
|
headers["Last-Modified"] ||= now.httpdate
|
171
|
-
|
172
|
+
encoded_body = ''.force_encoding("ASCII-8BIT")
|
173
|
+
deflater = ::Zlib::Deflate.new
|
172
174
|
body.each do |data|
|
173
|
-
|
175
|
+
encoded_body << deflater.deflate(data)
|
174
176
|
end
|
177
|
+
body.close if body.respond_to?(:close)
|
178
|
+
encoded_body << deflater.finish
|
175
179
|
headers = headers.to_hash
|
176
180
|
encoded_headers = headers.to_yaml
|
177
|
-
encoded_body = stringified_body.force_encoding("ASCII-8BIT")
|
178
181
|
cache[key] = {
|
179
182
|
:status => status,
|
180
183
|
:headers => encoded_headers,
|
@@ -183,7 +186,7 @@ module Racknga
|
|
183
186
|
:age => age,
|
184
187
|
:created_at => now,
|
185
188
|
}
|
186
|
-
body =
|
189
|
+
body = Inflater.new(encoded_body)
|
187
190
|
log("store", request)
|
188
191
|
[status, headers, body]
|
189
192
|
end
|
@@ -199,7 +202,7 @@ module Racknga
|
|
199
202
|
end
|
200
203
|
|
201
204
|
log("hit", request)
|
202
|
-
[status, YAML.load(headers),
|
205
|
+
[status, YAML.load(headers), Inflater.new(body)]
|
203
206
|
end
|
204
207
|
|
205
208
|
def compute_checksum(status, encoded_headers, encoded_body)
|
@@ -227,6 +230,17 @@ module Racknga
|
|
227
230
|
runtime = Time.now - start_time
|
228
231
|
logger.log("cache-#{tag}", request.fullpath, :runtime => runtime)
|
229
232
|
end
|
233
|
+
|
234
|
+
# @private
|
235
|
+
class Inflater
|
236
|
+
def initialize(deflated_string)
|
237
|
+
@deflated_string = deflated_string
|
238
|
+
end
|
239
|
+
|
240
|
+
def each
|
241
|
+
yield ::Zlib::Inflate.inflate(@deflated_string)
|
242
|
+
end
|
243
|
+
end
|
230
244
|
end
|
231
245
|
end
|
232
246
|
end
|
@@ -14,7 +14,7 @@
|
|
14
14
|
#
|
15
15
|
# You should have received a copy of the GNU Lesser General Public
|
16
16
|
# License along with this library; if not, write to the Free Software
|
17
|
-
# Foundation, Inc.,
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
|
19
19
|
module Racknga
|
20
20
|
module Middleware
|
@@ -14,7 +14,7 @@
|
|
14
14
|
#
|
15
15
|
# You should have received a copy of the GNU Lesser General Public
|
16
16
|
# License along with this library; if not, write to the Free Software
|
17
|
-
# Foundation, Inc.,
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
|
19
19
|
require 'racknga/exception_mail_notifier'
|
20
20
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
#
|
3
3
|
# Copyright (C) 2011 Ryo Onodera <onodera@clear-code.com>
|
4
|
+
# Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com>
|
4
5
|
#
|
5
6
|
# This library is free software; you can redistribute it and/or
|
6
7
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -14,7 +15,7 @@
|
|
14
15
|
#
|
15
16
|
# You should have received a copy of the GNU Lesser General Public
|
16
17
|
# License along with this library; if not, write to the Free Software
|
17
|
-
# Foundation, Inc.,
|
18
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
19
|
|
19
20
|
module Racknga
|
20
21
|
module Middleware
|
@@ -23,12 +24,18 @@ module Racknga
|
|
23
24
|
# server when your Rack applications are deployed behind
|
24
25
|
# load balancers.
|
25
26
|
#
|
26
|
-
#
|
27
|
+
# @example A simple usage
|
27
28
|
# require "racknga"
|
28
29
|
# use Racknga::Middleware::InstanceName
|
29
30
|
# run YourApplication
|
30
31
|
class InstanceName
|
31
32
|
attr_reader :header
|
33
|
+
# @param [application] application rack application.
|
34
|
+
# @param [Hash] options options to create header.
|
35
|
+
# @option options [String] :header_name ("Responsed-By") header name.
|
36
|
+
# @option options [String] :application_name (application.class.name)
|
37
|
+
# application name.
|
38
|
+
# @option options [Integer] :version application version.
|
32
39
|
def initialize(application, options={})
|
33
40
|
@application = application
|
34
41
|
@options = options
|
@@ -57,7 +64,14 @@ module Racknga
|
|
57
64
|
end
|
58
65
|
|
59
66
|
def revision
|
60
|
-
|
67
|
+
case using_scm_name
|
68
|
+
when :git
|
69
|
+
`git describe --abbrev=7 HEAD`.strip
|
70
|
+
when :subversion
|
71
|
+
`LANG=C svn info | grep Revision`.strip
|
72
|
+
else
|
73
|
+
nil
|
74
|
+
end
|
61
75
|
end
|
62
76
|
|
63
77
|
def server
|
@@ -68,17 +82,15 @@ module Racknga
|
|
68
82
|
`id --user --name`.strip
|
69
83
|
end
|
70
84
|
|
71
|
-
CURRENT_BRANCH_MARKER = /\A\* /
|
72
85
|
def branch
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
86
|
+
case using_scm_name
|
87
|
+
when :git
|
88
|
+
git_branch_name
|
89
|
+
when :subversion
|
90
|
+
subversion_branch_name
|
91
|
+
else
|
92
|
+
nil
|
80
93
|
end
|
81
|
-
current_branch
|
82
94
|
end
|
83
95
|
|
84
96
|
def ruby
|
@@ -159,6 +171,47 @@ module Racknga
|
|
159
171
|
nil
|
160
172
|
end
|
161
173
|
end
|
174
|
+
|
175
|
+
SVN_URL_KEY = /\AURL:.*/
|
176
|
+
SVN_REPOSITORY_ROOT_KEY = /\ARepository Root:.*/
|
177
|
+
SVN_KEY = /\A.*:/
|
178
|
+
SVN_BRANCHES_NAME = /\A\/branches\//
|
179
|
+
def subversion_branch_name
|
180
|
+
url = ""
|
181
|
+
repository_root = ""
|
182
|
+
|
183
|
+
`LANG=C svn info`.each_line do |line|
|
184
|
+
case line
|
185
|
+
when SVN_URL_KEY
|
186
|
+
url = line.sub(SVN_KEY, "").strip
|
187
|
+
when SVN_REPOSITORY_ROOT_KEY
|
188
|
+
repository_root = line.sub(SVN_KEY, "").strip
|
189
|
+
end
|
190
|
+
end
|
191
|
+
base_path = url.sub(/#{Regexp.escape(repository_root)}/, "")
|
192
|
+
base_path.sub(SVN_BRANCHES_NAME, "")
|
193
|
+
end
|
194
|
+
|
195
|
+
GIT_CURRENT_BRANCH_MARKER = /\A\* /
|
196
|
+
def git_branch_name
|
197
|
+
`git branch -a`.each_line do |line|
|
198
|
+
case line
|
199
|
+
when GIT_CURRENT_BRANCH_MARKER
|
200
|
+
return line.sub(GIT_CURRENT_BRANCH_MARKER, "").strip
|
201
|
+
end
|
202
|
+
end
|
203
|
+
nil
|
204
|
+
end
|
205
|
+
|
206
|
+
def using_scm_name
|
207
|
+
if File.exist?(".git")
|
208
|
+
:git
|
209
|
+
elsif File.exist?(".svn")
|
210
|
+
:subversion
|
211
|
+
else
|
212
|
+
nil
|
213
|
+
end
|
214
|
+
end
|
162
215
|
end
|
163
216
|
end
|
164
217
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
#
|
3
|
-
# Copyright (C) 2010 Kouhei Sutou <kou@clear-code.com>
|
3
|
+
# Copyright (C) 2010-2012 Kouhei Sutou <kou@clear-code.com>
|
4
4
|
#
|
5
5
|
# This library is free software; you can redistribute it and/or
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -14,7 +14,7 @@
|
|
14
14
|
#
|
15
15
|
# You should have received a copy of the GNU Lesser General Public
|
16
16
|
# License along with this library; if not, write to the Free Software
|
17
|
-
# Foundation, Inc.,
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
|
19
19
|
module Racknga
|
20
20
|
module Middleware
|
@@ -91,7 +91,7 @@ module Racknga
|
|
91
91
|
header_hash = Rack::Utils::HeaderHash.new(headers)
|
92
92
|
return [status, headers, body] unless json_response?(header_hash)
|
93
93
|
body = Writer.new(callback, body)
|
94
|
-
|
94
|
+
update_header_hash(header_hash, body)
|
95
95
|
[status, header_hash, body]
|
96
96
|
end
|
97
97
|
|
@@ -122,6 +122,11 @@ module Racknga
|
|
122
122
|
media_type == "text/javascript"
|
123
123
|
end
|
124
124
|
|
125
|
+
def update_header_hash(header_hash, body)
|
126
|
+
update_content_type(header_hash)
|
127
|
+
update_content_length(header_hash, body)
|
128
|
+
end
|
129
|
+
|
125
130
|
def update_content_type(header_hash)
|
126
131
|
content_type = header_hash["Content-Type"]
|
127
132
|
media_type, parameters = content_type.split(/\s*;\s*/, 2)
|
@@ -132,17 +137,31 @@ module Racknga
|
|
132
137
|
header_hash["Content-Type"] = updated_content_type
|
133
138
|
end
|
134
139
|
|
140
|
+
def update_content_length(header_hash, body)
|
141
|
+
return unless header_hash["Content-Length"]
|
142
|
+
|
143
|
+
content_length = header_hash["Content-Length"].to_i
|
144
|
+
updated_content_length = content_length + body.additional_content_length
|
145
|
+
header_hash["Content-Length"] = updated_content_length.to_s
|
146
|
+
end
|
147
|
+
|
135
148
|
# @private
|
136
149
|
class Writer
|
137
150
|
def initialize(callback, body)
|
138
151
|
@callback = callback
|
139
152
|
@body = body
|
153
|
+
@header = "#{@callback}("
|
154
|
+
@footer = ");"
|
140
155
|
end
|
141
156
|
|
142
157
|
def each(&block)
|
143
|
-
block.call(
|
158
|
+
block.call(@header)
|
144
159
|
@body.each(&block)
|
145
|
-
block.call(
|
160
|
+
block.call(@footer)
|
161
|
+
end
|
162
|
+
|
163
|
+
def additional_content_length
|
164
|
+
@header.bytesize + @footer.bytesize
|
146
165
|
end
|
147
166
|
end
|
148
167
|
end
|
@@ -14,7 +14,7 @@
|
|
14
14
|
#
|
15
15
|
# You should have received a copy of the GNU Lesser General Public
|
16
16
|
# License along with this library; if not, write to the Free Software
|
17
|
-
# Foundation, Inc.,
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
|
19
19
|
require 'racknga/log_database'
|
20
20
|
|
@@ -14,7 +14,7 @@
|
|
14
14
|
#
|
15
15
|
# You should have received a copy of the GNU Lesser General Public
|
16
16
|
# License along with this library; if not, write to the Free Software
|
17
|
-
# Foundation, Inc.,
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
|
19
19
|
module Racknga
|
20
20
|
module Middleware
|
@@ -14,7 +14,7 @@
|
|
14
14
|
#
|
15
15
|
# You should have received a copy of the GNU Lesser General Public
|
16
16
|
# License along with this library; if not, write to the Free Software
|
17
|
-
# Foundation, Inc.,
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
|
19
19
|
require 'time'
|
20
20
|
|
@@ -14,7 +14,7 @@
|
|
14
14
|
#
|
15
15
|
# You should have received a copy of the GNU Lesser General Public
|
16
16
|
# License along with this library; if not, write to the Free Software
|
17
|
-
# Foundation, Inc.,
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
|
19
19
|
module Racknga
|
20
20
|
class ReverseLineReader
|
data/lib/racknga/utils.rb
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
#
|
15
15
|
# You should have received a copy of the GNU Lesser General Public
|
16
16
|
# License along with this library; if not, write to the Free Software
|
17
|
-
# Foundation, Inc.,
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
|
19
19
|
module Racknga
|
20
20
|
module Utils
|
data/lib/racknga/version.rb
CHANGED
@@ -14,8 +14,8 @@
|
|
14
14
|
#
|
15
15
|
# You should have received a copy of the GNU Lesser General Public
|
16
16
|
# License along with this library; if not, write to the Free Software
|
17
|
-
# Foundation, Inc.,
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
|
19
19
|
module Racknga
|
20
|
-
VERSION = '0.9.
|
20
|
+
VERSION = '0.9.4'
|
21
21
|
end
|
data/lib/racknga.rb
CHANGED
@@ -14,13 +14,14 @@
|
|
14
14
|
#
|
15
15
|
# You should have received a copy of the GNU Lesser General Public
|
16
16
|
# License along with this library; if not, write to the Free Software
|
17
|
-
# Foundation, Inc.,
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
|
19
19
|
require 'rack'
|
20
20
|
|
21
21
|
require 'racknga/version'
|
22
22
|
require 'racknga/utils'
|
23
23
|
require "racknga/access_log_parser"
|
24
|
+
require 'racknga/api-keys'
|
24
25
|
require 'racknga/middleware/deflater'
|
25
26
|
require 'racknga/middleware/exception_notifier'
|
26
27
|
require 'racknga/middleware/jsonp'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
#
|
3
|
-
# Copyright (C) 2010 Kouhei Sutou <kou@clear-code.com>
|
3
|
+
# Copyright (C) 2010-2013 Kouhei Sutou <kou@clear-code.com>
|
4
4
|
#
|
5
5
|
# This program is free software: you can redistribute it and/or modify
|
6
6
|
# it under the terms of the GNU General Public License as published by
|
@@ -23,16 +23,11 @@ require 'rubygems'
|
|
23
23
|
|
24
24
|
mode = ARGV[0]
|
25
25
|
|
26
|
-
def passenger_status_path(gem_path)
|
27
|
-
File.join(gem_path, "bin", "passenger-status")
|
28
|
-
end
|
29
|
-
|
30
26
|
@label = ENV["label"]
|
31
27
|
@pid_file = ENV["pid_file"]
|
32
28
|
@ruby = ENV["ruby"] || Gem.ruby
|
33
|
-
|
34
|
-
|
35
|
-
end
|
29
|
+
passenger_spec = Gem::Specification.find_by_name("passenger")
|
30
|
+
@passenger_status = passenger_spec.bin_file("passenger-status")
|
36
31
|
|
37
32
|
if @label
|
38
33
|
parameter_prefix = /\Apassenger_(?:#{@label}_)?application_/
|
@@ -40,7 +35,7 @@ else
|
|
40
35
|
parameter_prefix = /\Apassenger_application_/
|
41
36
|
end
|
42
37
|
parameter = File.basename($0).gsub(parameter_prefix, '')
|
43
|
-
if /_(
|
38
|
+
if /_(\S+)\z/ =~ parameter
|
44
39
|
@application = $PREMATCH
|
45
40
|
@type = $1
|
46
41
|
@application = nil if @application and @application.empty?
|
@@ -57,28 +52,25 @@ def passenger_status
|
|
57
52
|
else
|
58
53
|
pid = nil
|
59
54
|
end
|
60
|
-
result = `#{@ruby} #{
|
55
|
+
result = `#{@ruby} #{@passenger_status} #{pid}`
|
61
56
|
[$?.success?, result]
|
62
57
|
end
|
63
58
|
|
64
|
-
def
|
65
|
-
|
66
|
-
if /\A(?:(?:(\d+)h\s+)?(\d+)m\s+)?(\d+)s\z/ =~
|
59
|
+
def parse_time(time)
|
60
|
+
time_in_minutes = 0
|
61
|
+
if /\A(?:(?:(\d+)h\s+)?(\d+)m\s+)?(\d+)s\z/ =~ time
|
67
62
|
hours = $1.to_i
|
68
63
|
minutes = $2.to_i
|
69
64
|
seconds = $3.to_i
|
70
|
-
|
65
|
+
time_in_minutes = minutes + hours * 60
|
71
66
|
end
|
72
|
-
|
67
|
+
time_in_minutes
|
73
68
|
end
|
74
69
|
|
75
70
|
def extract_application_name(path)
|
76
71
|
components = path.split(/\//)
|
77
|
-
|
78
|
-
|
79
|
-
components.pop
|
80
|
-
end
|
81
|
-
components.pop
|
72
|
+
application_name, tag = components.last.split(/#/)
|
73
|
+
application_name
|
82
74
|
end
|
83
75
|
|
84
76
|
def parse_result(result)
|
@@ -86,34 +78,47 @@ def parse_result(result)
|
|
86
78
|
section = nil
|
87
79
|
application_name = nil
|
88
80
|
result.each_line do |line|
|
89
|
-
case
|
90
|
-
when
|
91
|
-
|
92
|
-
|
93
|
-
path = $1
|
94
|
-
application_name = extract_application_name(path)
|
95
|
-
sections[section] << [application_name, []]
|
96
|
-
when /\A\s+\*\s+
|
97
|
-
PID:\s+(\d+)\s+
|
98
|
-
Sessions:\s+(\d+)\s+
|
99
|
-
Processed:\s+(\d+)\s+
|
100
|
-
Uptime:\s+(.+)\z/x
|
101
|
-
pid = $1.to_i
|
102
|
-
sessions = $2.to_i
|
103
|
-
processed = $3.to_i
|
104
|
-
uptime = parse_uptime($4)
|
105
|
-
_application_name, processes = sections[section].last
|
106
|
-
processes << {
|
107
|
-
:pid => pid,
|
108
|
-
:sessions => sessions,
|
109
|
-
:processed => processed,
|
110
|
-
:uptime => uptime
|
111
|
-
}
|
112
|
-
end
|
81
|
+
case line
|
82
|
+
when /-+\s+(.+)\s+-+/
|
83
|
+
section = $1
|
84
|
+
sections[section] = []
|
113
85
|
else
|
114
|
-
|
115
|
-
|
116
|
-
|
86
|
+
case section
|
87
|
+
when "Application groups"
|
88
|
+
case line.chomp
|
89
|
+
when /\A(\/.+):\s*\z/
|
90
|
+
path = $1
|
91
|
+
application_name = extract_application_name(path)
|
92
|
+
sections[section] << [application_name, []]
|
93
|
+
when /\A\s+\*\s+
|
94
|
+
PID:\s+(\d+)\s+
|
95
|
+
Sessions:\s+(\d+)\s+
|
96
|
+
Processed:\s+(\d+)\s+
|
97
|
+
Uptime:\s+(.+)\z/x
|
98
|
+
pid = $1.to_i
|
99
|
+
sessions = $2.to_i
|
100
|
+
processed = $3.to_i
|
101
|
+
uptime = parse_time($4)
|
102
|
+
_application_name, processes = sections[section].last
|
103
|
+
processes << {
|
104
|
+
:pid => pid,
|
105
|
+
:sessions => sessions,
|
106
|
+
:processed => processed,
|
107
|
+
:uptime => uptime
|
108
|
+
}
|
109
|
+
when /\A\s+
|
110
|
+
CPU:\s+(\d+)%\s+
|
111
|
+
Memory\s*:\s+(\d+)M\s+
|
112
|
+
Last\sused:\s+(.+)(?:\s+ago)\z/x
|
113
|
+
cpu = $1.to_i
|
114
|
+
memory = $2.to_i * 1024 * 1024
|
115
|
+
last_used = parse_time($3)
|
116
|
+
_application_name, processes = sections[section].last
|
117
|
+
process = processes.last
|
118
|
+
process[:cpu] = cpu
|
119
|
+
process[:memory] = memory
|
120
|
+
process[:last_used] = last_used
|
121
|
+
end
|
117
122
|
end
|
118
123
|
end
|
119
124
|
end
|
@@ -138,6 +143,12 @@ def vlabel
|
|
138
143
|
"number of processed sessions"
|
139
144
|
when "uptime"
|
140
145
|
"uptime by minutes"
|
146
|
+
when "cpu"
|
147
|
+
"CPU usage in percent"
|
148
|
+
when "memory"
|
149
|
+
"memory usage"
|
150
|
+
when "last_used"
|
151
|
+
"last used by minutes"
|
141
152
|
else
|
142
153
|
"unknown"
|
143
154
|
end
|
@@ -219,6 +230,9 @@ when "suggest"
|
|
219
230
|
puts "#{application}_sessions"
|
220
231
|
puts "#{application}_processed"
|
221
232
|
puts "#{application}_uptime"
|
233
|
+
puts "#{application}_cpu"
|
234
|
+
puts "#{application}_memory"
|
235
|
+
puts "#{application}_last_used"
|
222
236
|
end
|
223
237
|
exit(true)
|
224
238
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
#
|
3
|
-
# Copyright (C) 2010 Kouhei Sutou <kou@clear-code.com>
|
3
|
+
# Copyright (C) 2010-2013 Kouhei Sutou <kou@clear-code.com>
|
4
4
|
#
|
5
5
|
# This program is free software: you can redistribute it and/or modify
|
6
6
|
# it under the terms of the GNU General Public License as published by
|
@@ -22,16 +22,11 @@ require 'rubygems'
|
|
22
22
|
|
23
23
|
mode = ARGV[0]
|
24
24
|
|
25
|
-
def passenger_status_path(gem_path)
|
26
|
-
File.join(gem_path, "bin", "passenger-status")
|
27
|
-
end
|
28
|
-
|
29
25
|
@label = ENV["label"]
|
30
26
|
@pid_file = ENV["pid_file"]
|
31
27
|
@ruby = ENV["ruby"] || Gem.ruby
|
32
|
-
|
33
|
-
|
34
|
-
end
|
28
|
+
passenger_spec = Gem::Specification.find_by_name("passenger")
|
29
|
+
@passenger_status = passenger_spec.bin_file("passenger-status")
|
35
30
|
|
36
31
|
def passenger_status
|
37
32
|
if @pid_file
|
@@ -42,32 +37,60 @@ def passenger_status
|
|
42
37
|
else
|
43
38
|
pid = nil
|
44
39
|
end
|
45
|
-
result = `#{@ruby} #{
|
40
|
+
result = `#{@ruby} #{@passenger_status} #{pid}`
|
46
41
|
[$?.success?, result]
|
47
42
|
end
|
48
43
|
|
44
|
+
def label_to_key(label)
|
45
|
+
label.downcase.gsub(/[ -]+/, "_")
|
46
|
+
end
|
47
|
+
|
48
|
+
def extract_application_name(path)
|
49
|
+
components = path.split(/\//)
|
50
|
+
application_name, tag = components.last.split(/#/)
|
51
|
+
application_name
|
52
|
+
end
|
53
|
+
|
49
54
|
def parse_result(result)
|
50
55
|
sections = {}
|
51
56
|
section = nil
|
52
57
|
result.each_line do |line|
|
53
|
-
case
|
54
|
-
when
|
55
|
-
|
56
|
-
|
57
|
-
key = $1
|
58
|
-
value = $2.to_i
|
59
|
-
sections[section] << {:key => key, :label => key, :value => value}
|
60
|
-
when /\A(Waiting on global queue):\s*(\d+)\z/
|
61
|
-
label = $1
|
62
|
-
value = $2.to_i
|
63
|
-
sections[section] << {:key => "global_queue",
|
64
|
-
:label => label,
|
65
|
-
:value => value}
|
66
|
-
end
|
58
|
+
case line
|
59
|
+
when /-+\s+(.+)\s+-+/
|
60
|
+
section = $1
|
61
|
+
sections[section] = []
|
67
62
|
else
|
68
|
-
|
69
|
-
|
70
|
-
|
63
|
+
case section
|
64
|
+
when "General information"
|
65
|
+
case line.chomp
|
66
|
+
when /\A(.+):\s*(\d+)\z/
|
67
|
+
label = $1.strip
|
68
|
+
value = $2.to_i
|
69
|
+
key = label_to_key(label)
|
70
|
+
sections[section] << {
|
71
|
+
:key => key,
|
72
|
+
:label => label,
|
73
|
+
:value => value,
|
74
|
+
}
|
75
|
+
end
|
76
|
+
when "Application groups"
|
77
|
+
case line.chomp
|
78
|
+
when /\A(\/.+):\s*\z/
|
79
|
+
path = $1
|
80
|
+
application_name = extract_application_name(path)
|
81
|
+
sections[section] << [application_name, []]
|
82
|
+
when /\A\s+(.+):\s*(\d+)\z/
|
83
|
+
label = $1.strip
|
84
|
+
value = $2.to_i
|
85
|
+
_application_name, attributes = sections[section].last
|
86
|
+
key = "#{_application_name}_#{label_to_key(label)}"
|
87
|
+
label = "#{label}: #{_application_name}"
|
88
|
+
attributes << {
|
89
|
+
:key => key,
|
90
|
+
:label => label,
|
91
|
+
:value => value,
|
92
|
+
}
|
93
|
+
end
|
71
94
|
end
|
72
95
|
end
|
73
96
|
end
|
@@ -95,12 +118,16 @@ graph_vlabel number of processes
|
|
95
118
|
|
96
119
|
EOC
|
97
120
|
have_stack_base = false
|
98
|
-
sections["General information"]
|
99
|
-
|
121
|
+
attributes = sections["General information"]
|
122
|
+
sections["Application groups"].each do |_, application_attributes|
|
123
|
+
attributes += application_attributes
|
124
|
+
end
|
125
|
+
attributes.each do |attribute|
|
126
|
+
key = attribute[:key]
|
100
127
|
next if key == "count"
|
101
|
-
puts("#{key}.label #{
|
128
|
+
puts("#{key}.label #{attribute[:label]}")
|
102
129
|
case key
|
103
|
-
when
|
130
|
+
when /max/, /queue/
|
104
131
|
draw = "LINE2"
|
105
132
|
else
|
106
133
|
if have_stack_base
|
@@ -110,7 +137,7 @@ EOC
|
|
110
137
|
have_stack_base = true
|
111
138
|
end
|
112
139
|
end
|
113
|
-
puts("#{
|
140
|
+
puts("#{attribute[:key]}.draw #{draw}")
|
114
141
|
end
|
115
142
|
end
|
116
143
|
|
@@ -119,8 +146,12 @@ def report
|
|
119
146
|
exit(false) unless success
|
120
147
|
|
121
148
|
sections = parse_result(result)
|
122
|
-
sections["General information"]
|
123
|
-
|
149
|
+
attributes = sections["General information"]
|
150
|
+
sections["Application groups"].each do |_, application_attributes|
|
151
|
+
attributes += application_attributes
|
152
|
+
end
|
153
|
+
attributes.each do |attribute|
|
154
|
+
puts("#{attribute[:key]}.value #{attribute[:value]}")
|
124
155
|
end
|
125
156
|
end
|
126
157
|
|