rack-reqorder 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 980b4a8e4de9b3696b27754a43753a7ee813b0e2
4
- data.tar.gz: fcbfdaa4bf6ed3fb96923dd41b610642231275a7
3
+ metadata.gz: 92a69c99b0738479b0b998e1a7f7c5d3f3051f46
4
+ data.tar.gz: 7e032e5347593d459db3e183dd1b1cb653d91b7e
5
5
  SHA512:
6
- metadata.gz: 0ba82134c8dfec0aaf62df4df6e2b3562db24624cf4f1e1a27c0d5c6dac7b7351aa824b5678b57f6f207df2deaeb8b924a754c8f730e88f81c7322a0cc165ad3
7
- data.tar.gz: 64e885c60ed26a5951bf50102034a4c73701a104f6da0e80525900bd8e38192ee76def5fd0163b2b13213c39d591088d205ec88952542708f8f6e788e239a7b4
6
+ metadata.gz: 0b80ff10e5dfb1ff79ae7f5233b495f62f2e63374528e31742614e4b1f34b2501c4a44399c8d7655e0e65cc9b2efa845040b2f302c49d2a621290328b0889a08
7
+ data.tar.gz: f732af69470fb3123ada1da63fb932d68863832c53901fbe2ef98441a3d36256bb90bf49a20ff7fa60c0b00772665ee9ffc3ef993c33bb1fb967a3ff59cce71d
data/Gemfile CHANGED
@@ -1,8 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'mongoid_hash_query', path: '../mongoid_hash_query'
4
- gem 'pry'
5
-
6
3
  # Specify your gem's dependencies in rack-reqorder.gemspec
7
4
  gemspec
8
5
 
data/README.md CHANGED
@@ -27,7 +27,13 @@ Or install it yourself as:
27
27
  $ gem install rack-reqorder
28
28
 
29
29
  ## Usage
30
- Just add it on the middleware pipeline and initialize it.
30
+ You first need to initialize mongoid/mongodb by running:
31
+
32
+ ```bash
33
+ bundle exec rails g mongoid:config
34
+ ```
35
+
36
+ Then just add it on the middleware pipeline and initialize it.
31
37
 
32
38
  For instance, in Rails, in an initializer add:
33
39
 
@@ -51,6 +57,8 @@ end
51
57
  Please note that you can configure origins and resource depending on how you
52
58
  mount the rack-monitor engine and where you deploy your front-end.
53
59
 
60
+ For viewing your statistics please check [rack-reqorder-monitor](https://github.com/kollegorna/rack-reqorder-monitor)
61
+
54
62
  ## Development
55
63
 
56
64
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -3,9 +3,14 @@ require 'active_support/inflector'
3
3
  require 'mongoid'
4
4
  require 'kaminari'
5
5
  require 'kaminari/models/mongoid_extension'
6
+ require 'rack/reqorder/route_recognizers'
6
7
 
7
8
  module Rack
8
9
  module Reqorder
10
+ extend Rack::Reqorder::GrapeRecognizer
11
+ extend Rack::Reqorder::SinatraRecognizer
12
+ extend Rack::Reqorder::RailsRecognizer
13
+
9
14
  class << self
10
15
  attr_accessor :configuration
11
16
  end
@@ -24,24 +29,9 @@ module Rack
24
29
  )
25
30
  end
26
31
 
27
- def self.paths
28
- return @paths unless @paths.blank?
29
- @paths = {}
30
- Rails.application.routes.routes.routes.each do |route|
31
- @paths[route.defaults] = route.path.spec.left.to_s
32
- end
33
-
34
- return @paths
35
- end
36
-
37
- def self.recognise_path(path_uri, options = {})
38
- res = Rack::Reqorder.paths[Rails.application.routes.recognize_path(path_uri, options)
39
- .select{|key, value| [:action, :controller].include?(key)}
40
- ]
41
- end
42
-
43
32
  class Configuration
44
- attr_accessor :mongoid_yml, :environment
33
+ attr_accessor :mongoid_yml, :environment, :auth_email, :auth_password,
34
+ :no_auth
45
35
 
46
36
  def validate!
47
37
  if mongoid_yml.blank?
@@ -52,6 +42,10 @@ module Rack
52
42
  puts 'rack-reqorder: No environment found, assuming development environment'
53
43
  self.environment = :development
54
44
  end
45
+
46
+ self.auth_email = 'admin@example.com' if auth_email.blank?
47
+ self.auth_password = 'password' if auth_password.blank?
48
+ self.no_auth = false if self.no_auth.blank?
55
49
  end
56
50
  end
57
51
  end
@@ -79,3 +73,4 @@ require 'rack/reqorder/logger'
79
73
  require 'rack/reqorder/monitor'
80
74
 
81
75
  load 'rack/reqorder/tasks/routes.rake'
76
+ load 'rack/reqorder/tasks/test_database.rake'
@@ -7,23 +7,24 @@ module Rack::Reqorder
7
7
  end
8
8
 
9
9
  def call(environment)
10
- #http_request = save_http_request(environment)
10
+ rack_request = Rack::Request.new(environment.clone)
11
11
 
12
12
  start = Time.now.to_f
13
13
  begin
14
14
  status, headers, body = @app.call(environment)
15
+ response = Rack::Response.new(body, status, headers)
15
16
  rescue => exception
16
- log_exception(exception, environment)
17
+ response = log_exception(exception, environment)
17
18
  raise exception
19
+ ensure
20
+ response_time = Time.now.to_f - start
21
+
22
+ save_statistics(
23
+ rack_request: rack_request,
24
+ rack_response: response,
25
+ response_time: response_time
26
+ )
18
27
  end
19
- response_time = Time.now.to_f - start
20
-
21
- #save_http_response(body, status, headers, http_request)
22
- save_statistics(
23
- rack_request: Rack::Request.new(environment),
24
- rack_response: Rack::Response.new(body, status, headers),
25
- response_time: response_time
26
- )
27
28
 
28
29
  return [status, headers, body]
29
30
  end
@@ -42,15 +43,27 @@ module Rack::Reqorder
42
43
  ]
43
44
  end
44
45
 
46
+ def route_template(request_path:, request_method:)
47
+ Rack::Reqorder.recognize_path(request_path, {method: request_method})
48
+ end
49
+
45
50
  def save_statistics(rack_request:, rack_response:, response_time:)
46
51
  route_path = RoutePath.find_or_create_by({
47
- route: Rack::Reqorder.recognise_path(rack_request.path),
52
+ route: route_template({
53
+ #response_status: rack_response.status,
54
+ request_path: rack_request.path,
55
+ request_method: rack_request.request_method
56
+ }),
48
57
  http_method: rack_request.request_method
49
58
  })
50
59
 
51
- [:all.to_s, DateTime.now.hour.to_s].each do |key|
60
+ [:all.to_s, DateTime.now.utc.hour.to_s].each do |key|
52
61
  statistic = route_path.send("statistic_#{key}".to_sym)
53
62
 
63
+ if key != :all && statistic && statistic.created_at.to_date < DateTime.now.utc.to_date
64
+ statistic = route_path.send("create_statistic_#{key}")
65
+ end
66
+
54
67
  if statistic.nil?
55
68
  statistic = route_path.send("create_statistic_#{key}")
56
69
  end
@@ -79,7 +92,7 @@ module Rack::Reqorder
79
92
  request = Rack::Request.new(environment)
80
93
 
81
94
  route_path = RoutePath.find_or_create_by({
82
- route: Rack::Reqorder.recognise_path(request.path),
95
+ route: Rack::Reqorder.recognize_path(request.path),
83
96
  http_method: request.request_method
84
97
  })
85
98
 
@@ -128,11 +141,12 @@ module Rack::Reqorder
128
141
  path, line, _ = exception.backtrace.first.split(':')
129
142
  end
130
143
 
131
-
132
144
  app_fault = AppFault.find_or_create_by(
133
145
  e_class: exception.class,
134
146
  line: line.to_i,
135
- filepath: path[1..-1]
147
+ filepath: path[1..-1],
148
+ route_path: http_request.route_path,
149
+ environment: app_environment
136
150
  )
137
151
 
138
152
  AppException.create(
@@ -147,7 +161,7 @@ module Rack::Reqorder
147
161
  http_request: http_request
148
162
  )
149
163
 
150
- HttpResponse.create(
164
+ return HttpResponse.create(
151
165
  status: 500,
152
166
  http_request: http_request
153
167
  )
@@ -165,5 +179,13 @@ module Rack::Reqorder
165
179
  end
166
180
  end
167
181
  end
182
+
183
+ def app_environment
184
+ if Module.const_defined?(:Rails)
185
+ return Rails.env
186
+ else
187
+ return ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'unknown'
188
+ end
189
+ end
168
190
  end
169
191
  end
@@ -8,8 +8,13 @@ module Rack::Reqorder::Models
8
8
  field :line, type: Integer
9
9
  field :filepath, type: String
10
10
 
11
+ field :resolved, type: Boolean, default: false
12
+
13
+ field :environment, type: String
14
+
11
15
  field :app_exceptions_count, type: Integer, default: 0
12
16
 
17
+ belongs_to :route_path, dependent: :nullify
13
18
  has_many :app_exceptions, dependent: :destroy
14
19
 
15
20
  def update_count!
@@ -9,32 +9,12 @@ module Rack::Reqorder::Models
9
9
 
10
10
  has_many :http_requests, dependent: :destroy
11
11
 
12
- embeds_one :statistic_0, class_name: 'Rack::Reqorder::Models::Statistic'
13
- embeds_one :statistic_1, class_name: 'Rack::Reqorder::Models::Statistic'
14
- embeds_one :statistic_2, class_name: 'Rack::Reqorder::Models::Statistic'
15
- embeds_one :statistic_3, class_name: 'Rack::Reqorder::Models::Statistic'
16
- embeds_one :statistic_4, class_name: 'Rack::Reqorder::Models::Statistic'
17
- embeds_one :statistic_5, class_name: 'Rack::Reqorder::Models::Statistic'
18
- embeds_one :statistic_6, class_name: 'Rack::Reqorder::Models::Statistic'
19
- embeds_one :statistic_7, class_name: 'Rack::Reqorder::Models::Statistic'
20
- embeds_one :statistic_8, class_name: 'Rack::Reqorder::Models::Statistic'
21
- embeds_one :statistic_9, class_name: 'Rack::Reqorder::Models::Statistic'
22
- embeds_one :statistic_10, class_name: 'Rack::Reqorder::Models::Statistic'
23
- embeds_one :statistic_11, class_name: 'Rack::Reqorder::Models::Statistic'
24
- embeds_one :statistic_12, class_name: 'Rack::Reqorder::Models::Statistic'
25
- embeds_one :statistic_13, class_name: 'Rack::Reqorder::Models::Statistic'
26
- embeds_one :statistic_14, class_name: 'Rack::Reqorder::Models::Statistic'
27
- embeds_one :statistic_15, class_name: 'Rack::Reqorder::Models::Statistic'
28
- embeds_one :statistic_16, class_name: 'Rack::Reqorder::Models::Statistic'
29
- embeds_one :statistic_17, class_name: 'Rack::Reqorder::Models::Statistic'
30
- embeds_one :statistic_18, class_name: 'Rack::Reqorder::Models::Statistic'
31
- embeds_one :statistic_19, class_name: 'Rack::Reqorder::Models::Statistic'
32
- embeds_one :statistic_20, class_name: 'Rack::Reqorder::Models::Statistic'
33
- embeds_one :statistic_21, class_name: 'Rack::Reqorder::Models::Statistic'
34
- embeds_one :statistic_22, class_name: 'Rack::Reqorder::Models::Statistic'
35
- embeds_one :statistic_23, class_name: 'Rack::Reqorder::Models::Statistic'
36
- embeds_one :statistic_24, class_name: 'Rack::Reqorder::Models::Statistic'
37
-
38
12
  embeds_one :statistic_all, class_name: 'Rack::Reqorder::Models::Statistic'
13
+
14
+ 0.upto(23) do |i|
15
+ embeds_one "statistic_#{i}", class_name: 'Rack::Reqorder::Models::Statistic'
16
+ end
17
+
18
+ has_one :app_fault, dependent: :destroy
39
19
  end
40
20
  end
@@ -20,7 +20,11 @@ module Rack::Reqorder::Models
20
20
  field :xhr_count, type: Integer, default: 0
21
21
  field :ssl_count, type: Integer, default: 0
22
22
 
23
- embedded_in :route_path
23
+ embedded_in :route_path, inverse_of: :statistic_all
24
+
25
+ 0.upto(23) do |i|
26
+ embedded_in :route_path, inverse_of: "statistic_#{i}"
27
+ end
24
28
 
25
29
  def recalculate_average!(response_time)
26
30
  self.avg_response_time = (
@@ -1,5 +1,6 @@
1
1
  require 'grape'
2
2
  require 'grape-entity'
3
+ require 'rack/reqorder/monitor/helpers'
3
4
  require 'rack/reqorder/monitor/entities'
4
5
  require 'mongoid_hash_query'
5
6
  require 'pry'
@@ -10,20 +11,32 @@ module Rack::Reqorder
10
11
  end
11
12
 
12
13
  module Rack::Reqorder::Monitor
14
+
13
15
  class Api < Grape::API
14
16
  include Rack::Reqorder::Models
15
17
  include Rack::Reqorder::Monitor::Entities
16
18
 
17
19
  helpers do
18
20
  include MongoidHashQuery
21
+ include Rack::Reqorder::Monitor::Helpers
19
22
  end
20
23
 
21
24
  version 'v1', using: :path, vendor: 'foobar'
22
25
  format :json
23
26
  prefix :api
24
27
 
28
+ =begin
29
+ rescue_from Grape::Exceptions::ValidationErrors do |e|
30
+ error!({errors: e.send(:full_messages)}, 422)
31
+ end
32
+ =end
33
+
25
34
  #collection routes
26
35
  resource :route_paths do
36
+ before do
37
+ authorize_user!(headers) unless Rack::Reqorder.configuration.no_auth
38
+ end
39
+
27
40
  get do
28
41
  route_paths = apply_filters(RoutePath.all, params)
29
42
 
@@ -46,8 +59,23 @@ module Rack::Reqorder::Monitor
46
59
  end
47
60
  end
48
61
 
62
+ #collection routes
63
+ resource :route_path_24_statistics do
64
+ get do
65
+ route_paths = RoutePath.all
66
+
67
+ route_paths = apply_filters(route_paths, params)
68
+
69
+ present(route_paths, with: RoutePath24StatisticsEntity)
70
+ end
71
+ end
72
+
49
73
  #collection routes
50
74
  resource :requests do
75
+ before do
76
+ authorize_user!(headers) unless Rack::Reqorder.configuration.no_auth
77
+ end
78
+
51
79
  get do
52
80
  requests = apply_filters(HttpRequest.all, params)
53
81
 
@@ -72,6 +100,10 @@ module Rack::Reqorder::Monitor
72
100
 
73
101
  #collection routes
74
102
  resource :responses do
103
+ before do
104
+ authorize_user!(headers) unless Rack::Reqorder.configuration.no_auth
105
+ end
106
+
75
107
  get do
76
108
  responses = HttpResponse.all
77
109
 
@@ -98,9 +130,15 @@ module Rack::Reqorder::Monitor
98
130
 
99
131
  #collection routes
100
132
  resource :faults do
133
+ before do
134
+ authorize_user!(headers) unless Rack::Reqorder.configuration.no_auth
135
+ end
136
+
101
137
  get do
102
138
  faults = AppFault.all
103
139
 
140
+ environments = faults.group_by(&:environment).keys
141
+
104
142
  faults = apply_filters(faults, params)
105
143
 
106
144
  meta_aggregations = aggregations(faults, params)
@@ -110,7 +148,7 @@ module Rack::Reqorder::Monitor
110
148
  present_with_meta(
111
149
  faults,
112
150
  present(faults, with: FaultEntity),
113
- meta_aggregations
151
+ meta_aggregations.merge(environments: environments)
114
152
  )
115
153
  end
116
154
 
@@ -119,11 +157,28 @@ module Rack::Reqorder::Monitor
119
157
  get do
120
158
  present(AppFault.find(params[:id]), with: FaultEntity)
121
159
  end
160
+
161
+ params do
162
+ requires :fault, type: Hash do
163
+ optional :resolved, type: Boolean
164
+ end
165
+ end
166
+ put do
167
+ fault = AppFault.find(params[:id])
168
+ fault.resolved = declared(params)[:fault][:resolved]
169
+ fault.save!
170
+
171
+ present(fault, with: FaultEntity)
172
+ end
122
173
  end
123
174
  end
124
175
 
125
176
  #collection routes
126
177
  resource :exceptions do
178
+ before do
179
+ authorize_user!(headers) unless Rack::Reqorder.configuration.no_auth
180
+ end
181
+
127
182
  get do
128
183
  exceptions = AppException.all
129
184
 
@@ -148,24 +203,39 @@ module Rack::Reqorder::Monitor
148
203
  end
149
204
  end
150
205
 
206
+
207
+ params do
208
+ requires :user, type: Hash do
209
+ requires :email, type: String
210
+ requires :password, type: String
211
+ end
212
+ end
213
+ resource :sessions do
214
+ post do
215
+ authenticate_user!(declared(params))
216
+
217
+ present(Object.new, with: SessionEntity)
218
+ end
219
+ end
220
+
151
221
  helpers do
152
222
  def present_with_meta(object, hash, extra_meta)
153
223
  hash[:meta] = {
154
- currentPage: object.current_page,
155
- nextPage: object.next_page,
156
- prevPage: object.prev_page,
157
- totalPages: object.total_pages,
158
- totalCount: object.total_count
224
+ current_page: object.current_page,
225
+ next_page: object.next_page,
226
+ prev_page: object.prev_page,
227
+ total_pages: object.total_pages,
228
+ total_count: object.total_count
159
229
  }.merge(extra_meta)
160
230
 
161
231
  return hash
162
232
  end
163
233
 
164
234
  def paginate(object, params)
165
- return object.
166
- page(params[:page] || 1).
167
- per(params[:per_page] || 30).
168
- skip(params[:skip] || 0)
235
+ object = object.page(params[:page] || 1).per(params[:per_page] || 30)
236
+ object = object.skip(params[:skip]) if params[:skip]
237
+
238
+ return object
169
239
  end
170
240
  end
171
241
 
@@ -38,9 +38,11 @@ module Rack::Reqorder::Monitor
38
38
  expose :http_method
39
39
  expose :statistic_all, using: StatisticEntity
40
40
 
41
+ =begin
41
42
  1.upto(24) do |num|
42
43
  expose "statistic_#{num}", using: StatisticEntity
43
44
  end
45
+ =end
44
46
 
45
47
  with_options(format_with: :iso_timestamp) do
46
48
  expose :created_at
@@ -48,6 +50,55 @@ module Rack::Reqorder::Monitor
48
50
  end
49
51
  end
50
52
 
53
+ class RoutePath24StatisticsEntity < Grape::Entity
54
+ root :route_path_25_statistics
55
+ present_collection true
56
+
57
+ exposures = proc{|aggrs, field|
58
+ aggrs.each do |aggr|
59
+ expose aggr do |route_path, options|
60
+ today_array = []
61
+ yesterday_array = []
62
+
63
+ now = DateTime.now.utc.hour
64
+
65
+ 0.upto(now) do |i|
66
+ today_array.push(
67
+ route_path[:items].where(
68
+ "statistic_#{i}.created_at".to_sym.gte => DateTime.now.utc.to_date
69
+ ).send(aggr,("statistic_#{i}.#{field}"))
70
+ )
71
+ end
72
+
73
+ if now <23
74
+ (now+1).upto(23) do |i|
75
+ yesterday_array.push(
76
+ route_path[:items].where(
77
+ "statistic_#{i}.created_at".to_sym.gte => (DateTime.now.utc.to_date - 1)
78
+ ).send(aggr,("statistic_#{i}.#{field}"))
79
+ )
80
+ end
81
+ end
82
+
83
+ [yesterday_array,today_array].flatten
84
+ end
85
+ end
86
+ }
87
+
88
+ [:http_requests_count, :statuses_2xx, :statuses_3xx, :statuses_4xx,
89
+ :statuses_401, :statuses_404, :statuses_422, :statuses_5xx,
90
+ :xhr_count, :ssl_count
91
+ ].each do |field|
92
+ expose field do
93
+ exposures.call([:sum], field)
94
+ end
95
+ end
96
+
97
+ expose :avg_response_time do
98
+ exposures.call([:avg], :avg_response_time)
99
+ end
100
+ end
101
+
51
102
  class RequestEntity < BaseEntity
52
103
  root :requests, :request
53
104
 
@@ -100,15 +151,21 @@ module Rack::Reqorder::Monitor
100
151
  expose :e_class
101
152
  expose :line
102
153
  expose :filepath
154
+ expose :resolved
103
155
  expose :app_exceptions_count, as: :exceptions_count
156
+ expose :environment
104
157
  expose :message do |fault, options|
105
- fault.app_exceptions.try(:first).try(:message)
158
+ fault.app_exceptions.try(:last).try(:message)
106
159
  end
107
160
 
108
161
  expose :app_exception_ids, as: :exception_ids do |fault, options|
109
162
  fault.app_exception_ids.map(&:to_s).first(100)
110
163
  end
111
164
 
165
+ with_options(format_with: :association_id) do
166
+ expose :route_path, as: :route_path_id
167
+ end
168
+
112
169
  with_options(format_with: :iso_timestamp) do
113
170
  expose :created_at
114
171
  expose :updated_at
@@ -136,5 +193,23 @@ module Rack::Reqorder::Monitor
136
193
  end
137
194
 
138
195
  end
196
+
197
+ class SessionEntity < Grape::Entity
198
+ expose :id do |status, options|
199
+ 1
200
+ end
201
+
202
+ expose :email do |status, options|
203
+ Rack::Reqorder.configuration.auth_email
204
+ end
205
+
206
+ expose :token do |status, options|
207
+ #need user object...
208
+ Digest::MD5.hexdigest(
209
+ Rack::Reqorder.configuration.auth_email +
210
+ Rack::Reqorder.configuration.auth_password
211
+ )
212
+ end
213
+ end
139
214
  end
140
215
  end
@@ -0,0 +1,92 @@
1
+ module Rack::Reqorder::Monitor
2
+ module Helpers
3
+ def authorize_user!(headers)
4
+ authorize_user(headers) ? true : error!('403 Forbidden', 403)
5
+ end
6
+
7
+ def authenticate_user!(params)
8
+ authenticate_user(params) ? true : error!('401 Unauthorized', 401)
9
+ end
10
+
11
+ private
12
+ #monkeypatch these 2 methods if you want to provide custom authentication/authorization
13
+ def authorize_user(headers)
14
+ token, options = AuthorizationHeader.token_and_options(headers)
15
+
16
+ user_email = options.blank?? nil : options[:email]
17
+
18
+ correct_email = user_email == Rack::Reqorder.configuration.auth_email
19
+ correct_token = token == user_email_password_md5
20
+
21
+ return (correct_email && correct_token) ? true : false
22
+ end
23
+
24
+
25
+ def authenticate_user(params)
26
+ email = params.user.email
27
+ password = params.user.password
28
+
29
+ correct_email = email == Rack::Reqorder.configuration.auth_email
30
+ correct_password = password == Rack::Reqorder.configuration.auth_password
31
+
32
+ return (correct_email && correct_password)? true : false
33
+ end
34
+
35
+ def user_email_password_md5(user: nil)
36
+ #if user.nil?
37
+ Digest::MD5.hexdigest(
38
+ Rack::Reqorder.configuration.auth_email +
39
+ Rack::Reqorder.configuration.auth_password
40
+ )
41
+ #else
42
+ #end
43
+ end
44
+ #taken from rails ActionController::HttpAuthentication::Token ^_^
45
+ class AuthorizationHeader
46
+ class << self
47
+ TOKEN_KEY = 'token='
48
+ TOKEN_REGEX = /^(Token|Bearer) /
49
+ AUTHN_PAIR_DELIMITERS = /(?:,|;|\t+)/
50
+
51
+ def token_and_options(headers)
52
+ authorization_request = headers['Authorization']
53
+
54
+ if authorization_request[TOKEN_REGEX]
55
+ params = token_params_from authorization_request
56
+ [params.shift[1], Hash[params].with_indifferent_access]
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def token_params_from(auth)
63
+ rewrite_param_values params_array_from raw_params auth
64
+ end
65
+
66
+ # Takes raw_params and turns it into an array of parameters
67
+ def params_array_from(raw_params)
68
+ raw_params.map { |param| param.split %r/=(.+)?/ }
69
+ end
70
+
71
+ # This removes the <tt>"</tt> characters wrapping the value.
72
+ def rewrite_param_values(array_params)
73
+ array_params.each { |param| (param[1] || "").gsub! %r/^"|"$/, '' }
74
+ end
75
+
76
+ # This method takes an authorization body and splits up the key-value
77
+ # pairs by the standardized <tt>:</tt>, <tt>;</tt>, or <tt>\t</tt>
78
+ # delimiters defined in +AUTHN_PAIR_DELIMITERS+.
79
+ def raw_params(auth)
80
+ _raw_params = auth.sub(TOKEN_REGEX, '').split(/\s*#{AUTHN_PAIR_DELIMITERS}\s*/)
81
+
82
+ if !(_raw_params.first =~ %r{\A#{TOKEN_KEY}})
83
+ _raw_params[0] = "#{TOKEN_KEY}#{_raw_params.first}"
84
+ end
85
+
86
+ _raw_params
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+
@@ -0,0 +1,156 @@
1
+ module Rack
2
+ module Reqorder
3
+ module RailsRecognizer
4
+ def prefixes
5
+ return @prefixes unless @prefixes.blank?
6
+
7
+ @prefixes = {} #{'/mount_prefix' => {search_method: xxx_recognize_path, rack_app: xxx}}
8
+ Rails.application.routes.routes.routes.select{|r| r.defaults.blank?}.each do |route|
9
+ __superclass = route.app.try(:superclass) || route.app.try(:app).try(:superclass)
10
+
11
+ next unless __superclass
12
+
13
+ case __superclass.to_s
14
+ when Sinatra::Base.to_s
15
+ @prefixes[route.path.spec.try(:left).to_s + route.path.spec.try(:right).to_s] = {
16
+ search_method: :sinatra_recognize_path,
17
+ rack_app: route.app.try(:superclass).nil? ? route.app.app : route.app
18
+ }
19
+ when Rails::Engine.to_s
20
+ @prefixes[route.path.spec.try(:left).to_s + route.path.spec.try(:right).to_s] = {
21
+ search_method: :rails_recognize_path,
22
+ rack_app: route.app.try(:superclass).nil? ? route.app.app : route.app
23
+ }
24
+ when Grape::API.to_s
25
+ @prefixes[route.path.spec.try(:left).to_s + route.path.spec.try(:right).to_s] = {
26
+ search_method: :grape_recognize_path,
27
+ rack_app: route.app.try(:superclass).nil? ? route.app.app : route.app
28
+ }
29
+ end
30
+ end
31
+
32
+ return @prefixes
33
+ end
34
+
35
+ def rails_paths(rails_app)
36
+ paths = {}
37
+ rails_app.routes.routes.routes.reverse.each do |route|
38
+ paths[route.defaults] = route.path.spec.to_s.gsub('(.:format)', '')
39
+ end
40
+
41
+ return paths
42
+ end
43
+
44
+ def recognize_unknown_path
45
+ prefixes.each do |prefix, engine|
46
+ if path_uri.start_with?(prefix)
47
+ return prefix
48
+ end
49
+ end
50
+
51
+ return ''
52
+ end
53
+
54
+ def recognize_path(path_uri, options = {})
55
+ prefixes.each do |prefix, engine|
56
+ if path_uri.start_with?(prefix)
57
+ return prefix + self.send(engine[:search_method].to_sym, {
58
+ path_uri: path_uri.gsub(prefix, ''),
59
+ rack_app: engine[:rack_app],
60
+ options: options
61
+ })
62
+ end
63
+ end
64
+
65
+ begin
66
+ return rails_recognize_path(
67
+ path_uri: path_uri,
68
+ rack_app: Rails.application,
69
+ options: options
70
+ )
71
+ rescue ActionController::RoutingError
72
+ return "/#{path_uri.split('/')[1]}"
73
+ end
74
+ end
75
+
76
+ #rack_app is basically a rails app here but we keep it for the sake of the interface
77
+ def rails_recognize_path(path_uri:, rack_app:, options: {})
78
+ memoized_var = "@#{rack_app.class.to_s.split('::').join('_').downcase}".to_sym
79
+
80
+ if self.instance_variable_get(memoized_var).nil?
81
+ self.instance_variable_set(memoized_var, rails_paths(rack_app))
82
+ end
83
+
84
+ Rack::Reqorder.instance_variable_get(memoized_var)[
85
+ rack_app.routes.recognize_path(path_uri, options)
86
+ .select{|key, value| [:action, :controller].include?(key)}
87
+ ]
88
+ end
89
+ end
90
+
91
+ module GrapeRecognizer
92
+ def recognize_path(path_uri, options = {})
93
+ raise 'not implemented yet'
94
+ end
95
+
96
+ def grape_recognize_path(path_uri:, rack_app:, options: {})
97
+ path_uri = '/' if path_uri.blank?
98
+
99
+ rack_app.routes.each do |route|
100
+ route_options = route.instance_variable_get(:@options)
101
+ if route_options[:method] == options[:method] && route_options[:compiled] =~ path_uri
102
+ if route_options[:method] == "OPTIONS"
103
+ return route_options[:path].
104
+ gsub('(.json)', '')
105
+ else
106
+ return route_options[:path].
107
+ gsub(':version', route_options[:version]).
108
+ gsub('(.json)', '')
109
+ end
110
+ end
111
+ end
112
+
113
+ #assets in grape? well you never know..
114
+ if path_uri.end_with?('.js')
115
+ return '/js_asset'
116
+ elsif path_uri.end_with?('.css')
117
+ return '/css_asset'
118
+ elsif path_uri.end_with?('.png', 'jpg')
119
+ return '/css_asset'
120
+ else
121
+ return '/unknown' #path_uri
122
+ end
123
+ end
124
+ end
125
+
126
+ module SinatraRecognizer
127
+ def recognize_path(path_uri, options = {})
128
+ raise 'not implemented yet'
129
+ end
130
+
131
+ def sinatra_recognize_path(path_uri:, rack_app:, options: {})
132
+ path_uri = '/' if path_uri.blank?
133
+
134
+ rack_app.routes[options[:method].to_s.upcase].each do |r|
135
+ if r.first =~ path_uri
136
+ return r.first.to_s.
137
+ gsub('([^\\/?#]+)', ":#{r[1].first}").
138
+ gsub('\\z)','').gsub('(?-mix:\\A', '').
139
+ gsub('\\','')
140
+ end
141
+ end
142
+
143
+ if path_uri.end_with?('.js')
144
+ return '/js_asset'
145
+ elsif path_uri.end_with?('.css')
146
+ return '/css_asset'
147
+ elsif path_uri.end_with?('.png', 'jpg')
148
+ return '/css_asset'
149
+ else
150
+ return '/unknown' #path_uri
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+
@@ -1,5 +1,5 @@
1
1
  if respond_to?(:namespace, true)
2
- namespace 'rack-monitor' do
2
+ namespace 'rack-reqorder' do
3
3
  desc 'rack-monitor API routes'
4
4
  task :routes => :environment do
5
5
  Rack::Reqorder::Monitor::Api.routes.each do |route|
@@ -0,0 +1,29 @@
1
+ if respond_to?(:namespace, true)
2
+ namespace 'rack-reqorder' do
3
+ desc 'rack-monitor API routes'
4
+ task :test_database => :environment do
5
+ env = ENV["RACK_ENV"] || ENV["RAILS_ENV"] || Rails.env
6
+ return 'Available only under development env' unless env == 'development'
7
+
8
+ require_relative '../../../../spec/rack/factories/statistics.rb'
9
+ require_relative '../../../../spec/rack/factories/route_paths.rb'
10
+ require_relative '../../../../spec/rack/factories/app_faults.rb'
11
+
12
+ 10.times { FactoryGirl.create(:route_path) }
13
+
14
+ FactoryGirl.create(
15
+ :route_path,
16
+ route: '/rack-reqorder/api/v1/route_path_24_statistics',
17
+ http_method: 'GET'
18
+ )
19
+
20
+ FactoryGirl.create(
21
+ :route_path,
22
+ route: '/rack-reqorder/api/v1/route_paths',
23
+ http_method: 'GET'
24
+ )
25
+
26
+ 40.times { FactoryGirl.create(:app_fault) }
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  module Reqorder
3
- VERSION = "0.3.0"
3
+ VERSION = "0.4.0"
4
4
  end
5
5
  end
@@ -6,12 +6,12 @@ require 'rack/reqorder/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "rack-reqorder"
8
8
  spec.version = Rack::Reqorder::VERSION
9
- spec.authors = ["Filippos Vasilakis"]
10
- spec.email = ["vasilakisfil@gmail.com"]
9
+ spec.authors = ["Filippos Vasilakis", "Kollegorna"]
10
+ spec.email = ["vasilakisfil@gmail.com", "admin@kollegorna.se"]
11
11
 
12
12
  spec.summary = %q{Request recorder and analyzer for rack apps}
13
13
  spec.description = %q{Request recorder and analyzer for rack apps}
14
- spec.homepage = ""
14
+ spec.homepage = "https://github.com/kollegorna/rack-reqorder"
15
15
  spec.license = "MIT"
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
@@ -20,8 +20,12 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.8"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "pry"
24
+ spec.add_development_dependency "factory_girl", "~> 4.0"
25
+ spec.add_development_dependency "rspec"
26
+ spec.add_development_dependency "faker"
23
27
  spec.add_dependency "mongoid", "~> 4.0.0"
24
- spec.add_dependency "activesupport", "~> 4.1.6"
28
+ spec.add_dependency "activesupport", ">4.0.0"
25
29
  spec.add_dependency "grape"
26
30
  spec.add_dependency "grape-entity"
27
31
  spec.add_dependency "kaminari"
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-reqorder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Filippos Vasilakis
8
+ - Kollegorna
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2015-07-27 00:00:00.000000000 Z
12
+ date: 2015-10-12 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: bundler
@@ -38,6 +39,62 @@ dependencies:
38
39
  - - "~>"
39
40
  - !ruby/object:Gem::Version
40
41
  version: '10.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: pry
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: factory_girl
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '4.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '4.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: faker
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
41
98
  - !ruby/object:Gem::Dependency
42
99
  name: mongoid
43
100
  requirement: !ruby/object:Gem::Requirement
@@ -56,16 +113,16 @@ dependencies:
56
113
  name: activesupport
57
114
  requirement: !ruby/object:Gem::Requirement
58
115
  requirements:
59
- - - "~>"
116
+ - - ">"
60
117
  - !ruby/object:Gem::Version
61
- version: 4.1.6
118
+ version: 4.0.0
62
119
  type: :runtime
63
120
  prerelease: false
64
121
  version_requirements: !ruby/object:Gem::Requirement
65
122
  requirements:
66
- - - "~>"
123
+ - - ">"
67
124
  - !ruby/object:Gem::Version
68
- version: 4.1.6
125
+ version: 4.0.0
69
126
  - !ruby/object:Gem::Dependency
70
127
  name: grape
71
128
  requirement: !ruby/object:Gem::Requirement
@@ -139,6 +196,7 @@ dependencies:
139
196
  description: Request recorder and analyzer for rack apps
140
197
  email:
141
198
  - vasilakisfil@gmail.com
199
+ - admin@kollegorna.se
142
200
  executables: []
143
201
  extensions: []
144
202
  extra_rdoc_files: []
@@ -164,11 +222,14 @@ files:
164
222
  - lib/rack/reqorder/models/statistic.rb
165
223
  - lib/rack/reqorder/monitor.rb
166
224
  - lib/rack/reqorder/monitor/entities.rb
225
+ - lib/rack/reqorder/monitor/helpers.rb
226
+ - lib/rack/reqorder/route_recognizers.rb
167
227
  - lib/rack/reqorder/services/backtrace_cleaner.rb
168
228
  - lib/rack/reqorder/tasks/routes.rake
229
+ - lib/rack/reqorder/tasks/test_database.rake
169
230
  - lib/rack/reqorder/version.rb
170
231
  - rack-reqorder.gemspec
171
- homepage: ''
232
+ homepage: https://github.com/kollegorna/rack-reqorder
172
233
  licenses:
173
234
  - MIT
174
235
  metadata: {}
@@ -188,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
188
249
  version: '0'
189
250
  requirements: []
190
251
  rubyforge_project:
191
- rubygems_version: 2.4.5
252
+ rubygems_version: 2.4.8
192
253
  signing_key:
193
254
  specification_version: 4
194
255
  summary: Request recorder and analyzer for rack apps