racknga 0.9.2 → 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 +20 -0
- data/lib/racknga/access_log_parser.rb +147 -0
- data/lib/racknga/api-keys.rb +40 -0
- data/lib/racknga/cache_database.rb +15 -5
- data/lib/racknga/exception_mail_notifier.rb +6 -6
- data/lib/racknga/log_database.rb +2 -1
- data/lib/racknga/log_entry.rb +85 -0
- data/lib/racknga/middleware/auth/api-key.rb +95 -0
- data/lib/racknga/middleware/cache.rb +22 -8
- data/lib/racknga/middleware/deflater.rb +13 -3
- data/lib/racknga/middleware/exception_notifier.rb +1 -2
- data/lib/racknga/middleware/instance_name.rb +92 -9
- data/lib/racknga/middleware/jsonp.rb +25 -5
- data/lib/racknga/middleware/log.rb +8 -3
- data/lib/racknga/middleware/nginx_raw_uri.rb +65 -0
- 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 +4 -2
- 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-nginx-log-parser.rb → test-access-log-parser.rb} +115 -26
- 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 +50 -16
- data/test/test-middleware-jsonp.rb +14 -2
- data/test/test-middleware-nginx-raw-uri.rb +70 -0
- data/test/test-middleware-range.rb +1 -1
- metadata +159 -155
- data/lib/racknga/nginx_access_log_parser.rb +0 -139
- data/lib/racknga/will_paginate.rb +0 -48
@@ -0,0 +1,65 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2011 Ryo Onodera <onodera@clear-code.com>
|
4
|
+
#
|
5
|
+
# This library is free software; you can redistribute it and/or
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
7
|
+
# License as published by the Free Software Foundation; either
|
8
|
+
# version 2.1 of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This library is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
# Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with this library; if not, write to the Free Software
|
17
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
|
+
|
19
|
+
module Racknga
|
20
|
+
module Middleware
|
21
|
+
# NOTE:
|
22
|
+
# This is a middleware that restores the unprocessed URI client requests
|
23
|
+
# as is. Usually, nginx-passenger stack unescapes percent encoding in URI
|
24
|
+
# and resolve relative paths (ie "." and "..").
|
25
|
+
# Most of time, processed URI isn't program. However, if you want to
|
26
|
+
# distinguish %2F (ie "/") from "/", it is.
|
27
|
+
#
|
28
|
+
# Passenger 3.x or later is required.
|
29
|
+
#
|
30
|
+
# Use this with following nginx configuration:
|
31
|
+
#
|
32
|
+
# ... {
|
33
|
+
# ...
|
34
|
+
# passenger_set_cgi_param HTTP_X_RAW_REQUEST_URI $request_uri;
|
35
|
+
# }
|
36
|
+
#
|
37
|
+
# Usage:
|
38
|
+
# require "racknga"
|
39
|
+
# use Racknga::Middleware::NginxRawURI
|
40
|
+
# run YourApplication
|
41
|
+
class NginxRawURI
|
42
|
+
RAW_REQUEST_URI_HEADER_NAME = "HTTP_X_RAW_REQUEST_URI"
|
43
|
+
def initialize(application)
|
44
|
+
@application = application
|
45
|
+
end
|
46
|
+
|
47
|
+
# For Rack.
|
48
|
+
def call(environment)
|
49
|
+
raw_uri = environment[RAW_REQUEST_URI_HEADER_NAME]
|
50
|
+
|
51
|
+
if raw_uri
|
52
|
+
restore_raw_uri(environment, raw_uri)
|
53
|
+
end
|
54
|
+
|
55
|
+
@application.call(environment)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def restore_raw_uri(environment, raw_uri)
|
60
|
+
environment["PATH_INFO"] = raw_uri.split("?").first
|
61
|
+
environment["REQUEST_URI"] = raw_uri
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
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 '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,15 +14,17 @@
|
|
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
|
-
require "racknga/
|
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'
|
27
28
|
require 'racknga/middleware/range'
|
28
29
|
require "racknga/middleware/instance_name"
|
30
|
+
require "racknga/middleware/nginx_raw_uri"
|
@@ -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
|
|
data/test/racknga-test-utils.rb
CHANGED
@@ -12,12 +12,13 @@
|
|
12
12
|
#
|
13
13
|
# You should have received a copy of the GNU Lesser General Public
|
14
14
|
# License along with this library; if not, write to the Free Software
|
15
|
-
# Foundation, Inc.,
|
15
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
16
16
|
|
17
17
|
require "test/unit/capybara"
|
18
18
|
require 'json'
|
19
19
|
|
20
20
|
require 'racknga'
|
21
|
+
require 'racknga/middleware/auth/api-key'
|
21
22
|
require 'racknga/middleware/cache'
|
22
23
|
require 'racknga/middleware/instance_name'
|
23
24
|
|
data/test/run-test.rb
CHANGED
@@ -14,12 +14,10 @@
|
|
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
|
$VERBOSE = true
|
20
20
|
|
21
|
-
$KCODE = "u" if RUBY_VERSION < "1.9"
|
22
|
-
|
23
21
|
require 'pathname'
|
24
22
|
|
25
23
|
base_dir = Pathname(__FILE__).dirname.parent.expand_path
|