rack-reqorder 0.3.0 → 0.4.0

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 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