rack-perf 1.1.4 → 1.1.6
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 +4 -4
- data/.ruby-version +1 -0
- data/lib/rack/perf.rb +122 -76
- data/lib/rack/perf/version.rb +1 -1
- data/rack-perf.gemspec +4 -1
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba1100cc8d2413f4109571da408bb679394c0589
|
4
|
+
data.tar.gz: f2490f2d5558f27cb0812cd5693253b6311f9436
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 473136b6aee9a9e22af50ca0a03c96fbe1fd7ac359e7bfe81a3740e22cc583991868793ad2b5a7deef6a39df8ede0ddfd6c12b3bb46f5a8836b9f37b7a6ed9e6
|
7
|
+
data.tar.gz: ba208d0283d5d15aebf9947064012b69b225c6a66e0e669b5f391e1676a27ded4d292d7e2f2057c14a5ed874ccdd4114b9a5fac9546bccf8e9c9bc7a14488500
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.4
|
data/lib/rack/perf.rb
CHANGED
@@ -1,125 +1,171 @@
|
|
1
1
|
module Rack
|
2
2
|
class Perf
|
3
3
|
require_relative "perf/version"
|
4
|
-
require
|
4
|
+
require "unirest"
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
HIDDEN_READABLE_FIELDS = [
|
7
|
+
:starttime, :endtime, :api_key,
|
8
|
+
:debug, :stack, :env
|
9
|
+
]
|
8
10
|
|
9
|
-
attr_reader
|
10
|
-
private
|
11
|
-
|
12
|
-
attr_reader :api_key
|
13
|
-
private :api_key
|
14
|
-
|
15
|
-
attr_reader :debug
|
16
|
-
private :debug
|
11
|
+
attr_reader *HIDDEN_READABLE_FIELDS
|
12
|
+
private *HIDDEN_READABLE_FIELDS
|
17
13
|
|
18
14
|
def initialize(stack, api_key, debug = false)
|
19
|
-
@stack
|
15
|
+
@stack = stack
|
20
16
|
@api_key = api_key
|
21
|
-
@debug
|
17
|
+
@debug = debug
|
22
18
|
end
|
23
19
|
|
24
20
|
def call(env)
|
25
21
|
@env = env
|
26
22
|
|
27
23
|
# log the current time now before the request starts
|
28
|
-
|
24
|
+
performance_tracker = PerformanceTracker.new
|
25
|
+
performance_tracker.start
|
29
26
|
|
30
27
|
# run the current request
|
31
28
|
request = Rack::Request.new(env)
|
32
29
|
status, headers, body = stack.call(env)
|
33
30
|
|
34
31
|
# log the end time of the request
|
35
|
-
|
32
|
+
performance_tracker.end
|
36
33
|
|
37
|
-
#
|
38
|
-
|
39
|
-
ip_addr = request.ip
|
40
|
-
ip_addr = env["HTTP_X_FORWARDED_FOR"] if env["HTTP_X_FORWARDED_FOR"]
|
41
|
-
normalized_uri = get_normalized_path(request)
|
34
|
+
# normalize url
|
35
|
+
normalized_path = NormalizePath.new(request)
|
42
36
|
|
43
37
|
# send it up as long as we don't get nil, this helps
|
44
38
|
# in cases when we intercept asset urls that don't
|
45
39
|
# really matter
|
46
|
-
if
|
47
|
-
send_data
|
40
|
+
if normalized_path.path?
|
41
|
+
send_data = SendDataToPerf.new
|
42
|
+
send_data.api_key = @api_key
|
43
|
+
send_data.ip_addr = DetermineIPAddress.new(request).ip_address
|
44
|
+
send_data.request_method = request.request_method
|
45
|
+
send_data.request_url = request.url
|
46
|
+
send_data.normalized_uri = normalized_path.path
|
47
|
+
send_data.status_code = status
|
48
|
+
send_data.time_in_millis = performance_tracker.time
|
49
|
+
send_data.perform!
|
48
50
|
end
|
49
51
|
|
50
52
|
# send back intended data
|
51
53
|
[status, headers, body]
|
52
54
|
end
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
'time_in_millis' => time_in_millis
|
69
|
-
}
|
70
|
-
|
71
|
-
Unirest.post "https://data.perf.sh/ingest", headers:head, parameters:[params].to_json { |response|
|
72
|
-
# TODO: handle the incoming response
|
73
|
-
}
|
74
|
-
end
|
56
|
+
private
|
57
|
+
|
58
|
+
class NormalizePath < Struct.new(:request)
|
59
|
+
def path?
|
60
|
+
path != nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def path
|
64
|
+
normalize_path
|
65
|
+
rescue ActionController::RoutingError
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
75
70
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
path = request.path
|
71
|
+
def route
|
72
|
+
Rails.application.routes.recognize_path(request.path, method: request.request_method)
|
73
|
+
end
|
80
74
|
|
81
|
-
|
82
|
-
route = Rails.application.routes.recognize_path path, method: request.request_method
|
75
|
+
def params
|
83
76
|
params = {}
|
84
|
-
route.each{ |param, value|
|
85
|
-
if not ["controller", "action"].include?(param.to_s)
|
86
|
-
params[param.to_s] = value
|
87
|
-
end
|
88
|
-
}
|
89
77
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
78
|
+
route
|
79
|
+
.reject { |param, value| ["controller", "action"].include?(param.to_s) }
|
80
|
+
.each { |param, value| params[param.to_s] = value }
|
81
|
+
end
|
82
|
+
|
83
|
+
def normalize_path
|
84
|
+
path_split = request.path.split(/\//)
|
85
|
+
format = params["format"].to_s
|
86
|
+
|
87
|
+
normalized_path = path_split.map do |path_part|
|
88
|
+
params.each do |param, path_value|
|
89
|
+
part_equals_value = path_part == path_value
|
90
|
+
part_equals_value_with_format = format && path_part == ("%s.%s" % [path_value, format])
|
96
91
|
|
97
|
-
if
|
98
|
-
path_part = "
|
92
|
+
if part_equals_value || part_equals_value_with_format
|
93
|
+
path_part = ":%s" % param.to_s
|
99
94
|
end
|
100
|
-
|
95
|
+
end
|
101
96
|
|
102
|
-
|
103
|
-
|
97
|
+
path_part
|
98
|
+
end
|
104
99
|
|
105
|
-
|
106
|
-
rescue ActionController::RoutingError
|
107
|
-
return nil
|
100
|
+
normalized_path.join("/")
|
108
101
|
end
|
109
102
|
end
|
110
103
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
104
|
+
class DetermineIPAddress < Struct.new(:request)
|
105
|
+
def ip_address
|
106
|
+
forwarded_ip ? forwarded_ip : default_ip
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def default_ip
|
112
|
+
request.ip
|
113
|
+
end
|
114
|
+
|
115
|
+
def forwarded_ip
|
116
|
+
request.env["HTTP_X_FORWARDED_FOR"]
|
117
|
+
end
|
115
118
|
end
|
116
119
|
|
117
|
-
|
118
|
-
|
120
|
+
class PerformanceTracker
|
121
|
+
def start
|
122
|
+
@starttime = Time.now
|
123
|
+
end
|
124
|
+
|
125
|
+
def end
|
126
|
+
@endtime = Time.now
|
127
|
+
end
|
128
|
+
|
129
|
+
def time
|
130
|
+
((endtime-starttime) * 1000).round
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
attr_accessor :starttime, :endtime
|
119
136
|
end
|
120
137
|
|
121
|
-
|
122
|
-
|
138
|
+
# this method sends up the single timing request up to Perf
|
139
|
+
# TODO: queue this up in a batch
|
140
|
+
class SendDataToPerf < Struct.new(:api_key, :ip_addr, :request_method, :request_url, :normalized_uri, :status_code, :time_in_millis)
|
141
|
+
DESTINATION_URL = "https://data.perf.sh/ingest"
|
142
|
+
|
143
|
+
def perform!
|
144
|
+
Unirest.post(DESTINATION_URL, headers: headers, parameters: params_json)
|
145
|
+
end
|
146
|
+
|
147
|
+
private
|
148
|
+
|
149
|
+
def headers
|
150
|
+
{ "Content-Type" => "application/json",
|
151
|
+
"X-Perf-Public-API-Key" => api_key }
|
152
|
+
end
|
153
|
+
|
154
|
+
def params
|
155
|
+
{ "ip_addr" => ip_addr,
|
156
|
+
"request_method" => request_method,
|
157
|
+
"request_url" => request_url,
|
158
|
+
"normalized_uri" => normalized_uri,
|
159
|
+
"status_code" => status_code,
|
160
|
+
"time_in_millis" => time_in_millis }
|
161
|
+
end
|
162
|
+
|
163
|
+
def params_json
|
164
|
+
[params].to_json do
|
165
|
+
# TODO: handle the incoming response
|
166
|
+
end
|
167
|
+
end
|
123
168
|
end
|
169
|
+
|
124
170
|
end
|
125
171
|
end
|
data/lib/rack/perf/version.rb
CHANGED
data/rack-perf.gemspec
CHANGED
@@ -12,6 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.summary = %q{Perf middleware}
|
13
13
|
spec.description = %q{Rack middleware that records endpoint timing and status codes to Perf}
|
14
14
|
spec.homepage = "https://github.com/perflabs/rack-perf"
|
15
|
+
spec.license = "GPL-3.0"
|
15
16
|
|
16
17
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
18
|
f.match(%r{^(test|spec|features)/})
|
@@ -20,7 +21,9 @@ Gem::Specification.new do |spec|
|
|
20
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
22
|
spec.require_paths = ["lib"]
|
22
23
|
|
23
|
-
spec.
|
24
|
+
spec.required_ruby_version = '>= 2.0'
|
25
|
+
|
26
|
+
spec.add_dependency "unirest-2x", "~> 1.1"
|
24
27
|
spec.add_development_dependency "bundler", "~> 1.13"
|
25
28
|
spec.add_development_dependency "rake", "~> 10.0"
|
26
29
|
end
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-perf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steven Lu
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: unirest
|
14
|
+
name: unirest-2x
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
@@ -60,6 +60,7 @@ extensions: []
|
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
62
|
- ".gitignore"
|
63
|
+
- ".ruby-version"
|
63
64
|
- Gemfile
|
64
65
|
- LICENSE.md
|
65
66
|
- README.md
|
@@ -71,7 +72,8 @@ files:
|
|
71
72
|
- lib/rack/perf/version.rb
|
72
73
|
- rack-perf.gemspec
|
73
74
|
homepage: https://github.com/perflabs/rack-perf
|
74
|
-
licenses:
|
75
|
+
licenses:
|
76
|
+
- GPL-3.0
|
75
77
|
metadata: {}
|
76
78
|
post_install_message:
|
77
79
|
rdoc_options: []
|
@@ -81,7 +83,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
81
83
|
requirements:
|
82
84
|
- - ">="
|
83
85
|
- !ruby/object:Gem::Version
|
84
|
-
version: '0'
|
86
|
+
version: '2.0'
|
85
87
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
88
|
requirements:
|
87
89
|
- - ">="
|