meta_request 0.7.3 → 0.7.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +79 -79
- data/lib/meta_request/app_notifications.rb +88 -88
- data/lib/meta_request/app_request.rb +20 -20
- data/lib/meta_request/config.rb +22 -22
- data/lib/meta_request/event.rb +78 -78
- data/lib/meta_request/log_interceptor.rb +47 -47
- data/lib/meta_request/middlewares/app_request_handler.rb +33 -33
- data/lib/meta_request/middlewares/headers.rb +38 -38
- data/lib/meta_request/middlewares/meta_request_handler.rb +27 -27
- data/lib/meta_request/middlewares.rb +9 -9
- data/lib/meta_request/railtie.rb +27 -27
- data/lib/meta_request/storage.rb +45 -45
- data/lib/meta_request/utils.rb +28 -28
- data/lib/meta_request/version.rb +5 -5
- data/lib/meta_request.rb +29 -29
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e49088dd0f59edb460bd290208da99950c27d80b53a89ec118eff7e92456081
|
4
|
+
data.tar.gz: 176cf5c3b6acc39a80c962e3e1bc6d2d2a7bbce8c492bd5055bcb18d592fc1a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c91cd99b7cbf908d8aa04fd2781296be408921eb4ea1b4504fa10a586fa216f55f68798bd2f6304ab0e5be3a1300c00347adcc3add55ffb15285298b2db3e5f
|
7
|
+
data.tar.gz: 6ef328ed871cc4705fece9ffc7ab0642a8763b40d24848ecedc9e7754a5636164484be069d6655596a1be7be2a8b94fab28fab5916645a577bdb148ca736df0a
|
data/README.md
CHANGED
@@ -1,79 +1,79 @@
|
|
1
|
-
# MetaRequest
|
2
|
-
|
3
|
-
Supporting gem for [Rails Panel (Google Chrome extension for Rails development)](https://github.com/dejan/rails_panel).
|
4
|
-
|
5
|
-
## Installation
|
6
|
-
|
7
|
-
Add meta_request gem to development group in Gemfile:
|
8
|
-
|
9
|
-
```ruby
|
10
|
-
group :development do
|
11
|
-
gem 'meta_request'
|
12
|
-
end
|
13
|
-
```
|
14
|
-
|
15
|
-
## Usage
|
16
|
-
|
17
|
-
See [Rails Panel extension](https://github.com/dejan/rails_panel).
|
18
|
-
|
19
|
-
## Compatibility Warnings
|
20
|
-
|
21
|
-
If you're using [LiveReload](http://livereload.com/) or
|
22
|
-
[Rack::LiveReload](https://github.com/johnbintz/rack-livereload) make sure to
|
23
|
-
exclude watching your tmp/ folder because meta_request writes a lot of data there
|
24
|
-
and your browser will refresh like a madman.
|
25
|
-
|
26
|
-
## Configuration
|
27
|
-
|
28
|
-
Gem can be configured using block:
|
29
|
-
|
30
|
-
```ruby
|
31
|
-
MetaRequest.configure do |config|
|
32
|
-
config.storage_pool_size = 30
|
33
|
-
end
|
34
|
-
```
|
35
|
-
|
36
|
-
List of available attributes and defaults can be found in [lib/meta_request/config.rb](lib/meta_request/config.rb).
|
37
|
-
|
38
|
-
## Docker
|
39
|
-
|
40
|
-
Apps runing in Docker container will have filepaths of the container so links to editor would not work. To fix this, you need to propagate working directory through enviroment variable `SOURCE_PATH`. With docker-compose it can be done like this:
|
41
|
-
|
42
|
-
```yaml
|
43
|
-
services:
|
44
|
-
app:
|
45
|
-
environment:
|
46
|
-
- SOURCE_PATH=$PWD
|
47
|
-
# ...
|
48
|
-
```
|
49
|
-
|
50
|
-
## Development
|
51
|
-
|
52
|
-
Run all tests:
|
53
|
-
|
54
|
-
docker-compose up
|
55
|
-
|
56
|
-
## Licence
|
57
|
-
|
58
|
-
Copyright (c) 2012 Dejan Simic
|
59
|
-
|
60
|
-
MIT License
|
61
|
-
|
62
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
63
|
-
a copy of this software and associated documentation files (the
|
64
|
-
"Software"), to deal in the Software without restriction, including
|
65
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
66
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
67
|
-
permit persons to whom the Software is furnished to do so, subject to
|
68
|
-
the following conditions:
|
69
|
-
|
70
|
-
The above copyright notice and this permission notice shall be
|
71
|
-
included in all copies or substantial portions of the Software.
|
72
|
-
|
73
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
74
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
75
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
76
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
77
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
78
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
79
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1
|
+
# MetaRequest
|
2
|
+
|
3
|
+
Supporting gem for [Rails Panel (Google Chrome extension for Rails development)](https://github.com/dejan/rails_panel).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add meta_request gem to development group in Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
group :development do
|
11
|
+
gem 'meta_request'
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
See [Rails Panel extension](https://github.com/dejan/rails_panel).
|
18
|
+
|
19
|
+
## Compatibility Warnings
|
20
|
+
|
21
|
+
If you're using [LiveReload](http://livereload.com/) or
|
22
|
+
[Rack::LiveReload](https://github.com/johnbintz/rack-livereload) make sure to
|
23
|
+
exclude watching your tmp/ folder because meta_request writes a lot of data there
|
24
|
+
and your browser will refresh like a madman.
|
25
|
+
|
26
|
+
## Configuration
|
27
|
+
|
28
|
+
Gem can be configured using block:
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
MetaRequest.configure do |config|
|
32
|
+
config.storage_pool_size = 30
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
36
|
+
List of available attributes and defaults can be found in [lib/meta_request/config.rb](lib/meta_request/config.rb).
|
37
|
+
|
38
|
+
## Docker
|
39
|
+
|
40
|
+
Apps runing in Docker container will have filepaths of the container so links to editor would not work. To fix this, you need to propagate working directory through enviroment variable `SOURCE_PATH`. With docker-compose it can be done like this:
|
41
|
+
|
42
|
+
```yaml
|
43
|
+
services:
|
44
|
+
app:
|
45
|
+
environment:
|
46
|
+
- SOURCE_PATH=$PWD
|
47
|
+
# ...
|
48
|
+
```
|
49
|
+
|
50
|
+
## Development
|
51
|
+
|
52
|
+
Run all tests:
|
53
|
+
|
54
|
+
docker-compose up
|
55
|
+
|
56
|
+
## Licence
|
57
|
+
|
58
|
+
Copyright (c) 2012 Dejan Simic
|
59
|
+
|
60
|
+
MIT License
|
61
|
+
|
62
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
63
|
+
a copy of this software and associated documentation files (the
|
64
|
+
"Software"), to deal in the Software without restriction, including
|
65
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
66
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
67
|
+
permit persons to whom the Software is furnished to do so, subject to
|
68
|
+
the following conditions:
|
69
|
+
|
70
|
+
The above copyright notice and this permission notice shall be
|
71
|
+
included in all copies or substantial portions of the Software.
|
72
|
+
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
74
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
75
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
76
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
77
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
78
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
79
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -1,88 +1,88 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MetaRequest
|
4
|
-
class AppNotifications
|
5
|
-
# these are the specific keys in the cache payload that we display in the
|
6
|
-
# panel view
|
7
|
-
CACHE_KEY_COLUMNS = %i[key hit options type].freeze
|
8
|
-
|
9
|
-
# define this here so we can pass it in to all of our cache subscribe calls
|
10
|
-
CACHE_BLOCK = proc { |*args|
|
11
|
-
name, start, ending, transaction_id, payload = args
|
12
|
-
|
13
|
-
# from http://edgeguides.rubyonrails.org/active_support_instrumentation.html#cache-fetch-hit-active-support
|
14
|
-
#
|
15
|
-
# :super_operation :fetch is added when a read is used with #fetch
|
16
|
-
#
|
17
|
-
# so if :super_operation is present, we'll use it for the type. otherwise
|
18
|
-
# strip (say) 'cache_delete.active_support' down to 'delete'
|
19
|
-
payload[:type] = payload.delete(:super_operation) || name.sub(/cache_(.*?)\..*$/, '\1')
|
20
|
-
|
21
|
-
# anything that isn't in CACHE_KEY_COLUMNS gets shoved into :options
|
22
|
-
# instead
|
23
|
-
payload[:options] = {}
|
24
|
-
payload.keys.each do |k|
|
25
|
-
payload[:options][k] = payload.delete(k) unless k.in? CACHE_KEY_COLUMNS
|
26
|
-
end
|
27
|
-
|
28
|
-
callsite = Utils.dev_callsite(caller)
|
29
|
-
payload.merge!(callsite) if callsite
|
30
|
-
|
31
|
-
Event.new(name, start, ending, transaction_id, payload)
|
32
|
-
}
|
33
|
-
|
34
|
-
# sql processing block - used for sql.active_record and sql.sequel
|
35
|
-
|
36
|
-
# HACK: we hardcode the event name to 'sql.active_record' so that the ui will
|
37
|
-
# display sequel events without modification. otherwise the ui would need to
|
38
|
-
# be modified to support a sequel tab (or to change the display name on the
|
39
|
-
# active_record tab when necessary - which maybe makes more sense?)
|
40
|
-
SQL_EVENT_NAME = 'sql.active_record'
|
41
|
-
|
42
|
-
SQL_BLOCK = proc { |*args|
|
43
|
-
_name, start, ending, transaction_id, payload = args
|
44
|
-
callsite = Utils.dev_callsite(caller)
|
45
|
-
payload.merge!(callsite) if callsite
|
46
|
-
|
47
|
-
Event.new(SQL_EVENT_NAME, start, ending, transaction_id, payload)
|
48
|
-
}
|
49
|
-
|
50
|
-
VIEW_BLOCK = proc { |*args|
|
51
|
-
name, start, ending, transaction_id, payload = args
|
52
|
-
payload[:identifier] = MetaRequest::Utils.sub_source_path(payload[:identifier])
|
53
|
-
|
54
|
-
Event.new(name, start, ending, transaction_id, payload)
|
55
|
-
}
|
56
|
-
|
57
|
-
# Subscribe to all events relevant to RailsPanel
|
58
|
-
#
|
59
|
-
def self.subscribe
|
60
|
-
new
|
61
|
-
.subscribe('meta_request.log')
|
62
|
-
.subscribe('sql.active_record', &SQL_BLOCK)
|
63
|
-
.subscribe('sql.sequel', &SQL_BLOCK)
|
64
|
-
.subscribe('render_partial.action_view', &VIEW_BLOCK)
|
65
|
-
.subscribe('render_template.action_view', &VIEW_BLOCK)
|
66
|
-
.subscribe('process_action.action_controller.exception')
|
67
|
-
.subscribe('process_action.action_controller') do |*args|
|
68
|
-
name, start, ending, transaction_id, payload = args
|
69
|
-
payload[:status] = '500' if payload[:exception]
|
70
|
-
Event.new(name, start, ending, transaction_id, payload)
|
71
|
-
end
|
72
|
-
.subscribe('cache_read.active_support', &CACHE_BLOCK)
|
73
|
-
.subscribe('cache_generate.active_support', &CACHE_BLOCK)
|
74
|
-
.subscribe('cache_fetch_hit.active_support', &CACHE_BLOCK)
|
75
|
-
.subscribe('cache_write.active_support', &CACHE_BLOCK)
|
76
|
-
.subscribe('cache_delete.active_support', &CACHE_BLOCK)
|
77
|
-
.subscribe('cache_exist?.active_support', &CACHE_BLOCK)
|
78
|
-
end
|
79
|
-
|
80
|
-
def subscribe(event_name)
|
81
|
-
ActiveSupport::Notifications.subscribe(event_name) do |*args|
|
82
|
-
event = block_given? ? yield(*args) : Event.new(*args)
|
83
|
-
AppRequest.current.events << event if AppRequest.current
|
84
|
-
end
|
85
|
-
self
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaRequest
|
4
|
+
class AppNotifications
|
5
|
+
# these are the specific keys in the cache payload that we display in the
|
6
|
+
# panel view
|
7
|
+
CACHE_KEY_COLUMNS = %i[key hit options type].freeze
|
8
|
+
|
9
|
+
# define this here so we can pass it in to all of our cache subscribe calls
|
10
|
+
CACHE_BLOCK = proc { |*args|
|
11
|
+
name, start, ending, transaction_id, payload = args
|
12
|
+
|
13
|
+
# from http://edgeguides.rubyonrails.org/active_support_instrumentation.html#cache-fetch-hit-active-support
|
14
|
+
#
|
15
|
+
# :super_operation :fetch is added when a read is used with #fetch
|
16
|
+
#
|
17
|
+
# so if :super_operation is present, we'll use it for the type. otherwise
|
18
|
+
# strip (say) 'cache_delete.active_support' down to 'delete'
|
19
|
+
payload[:type] = payload.delete(:super_operation) || name.sub(/cache_(.*?)\..*$/, '\1')
|
20
|
+
|
21
|
+
# anything that isn't in CACHE_KEY_COLUMNS gets shoved into :options
|
22
|
+
# instead
|
23
|
+
payload[:options] = {}
|
24
|
+
payload.keys.each do |k|
|
25
|
+
payload[:options][k] = payload.delete(k) unless k.in? CACHE_KEY_COLUMNS
|
26
|
+
end
|
27
|
+
|
28
|
+
callsite = Utils.dev_callsite(caller)
|
29
|
+
payload.merge!(callsite) if callsite
|
30
|
+
|
31
|
+
Event.new(name, start, ending, transaction_id, payload)
|
32
|
+
}
|
33
|
+
|
34
|
+
# sql processing block - used for sql.active_record and sql.sequel
|
35
|
+
|
36
|
+
# HACK: we hardcode the event name to 'sql.active_record' so that the ui will
|
37
|
+
# display sequel events without modification. otherwise the ui would need to
|
38
|
+
# be modified to support a sequel tab (or to change the display name on the
|
39
|
+
# active_record tab when necessary - which maybe makes more sense?)
|
40
|
+
SQL_EVENT_NAME = 'sql.active_record'
|
41
|
+
|
42
|
+
SQL_BLOCK = proc { |*args|
|
43
|
+
_name, start, ending, transaction_id, payload = args
|
44
|
+
callsite = Utils.dev_callsite(caller)
|
45
|
+
payload.merge!(callsite) if callsite
|
46
|
+
|
47
|
+
Event.new(SQL_EVENT_NAME, start, ending, transaction_id, payload)
|
48
|
+
}
|
49
|
+
|
50
|
+
VIEW_BLOCK = proc { |*args|
|
51
|
+
name, start, ending, transaction_id, payload = args
|
52
|
+
payload[:identifier] = MetaRequest::Utils.sub_source_path(payload[:identifier])
|
53
|
+
|
54
|
+
Event.new(name, start, ending, transaction_id, payload)
|
55
|
+
}
|
56
|
+
|
57
|
+
# Subscribe to all events relevant to RailsPanel
|
58
|
+
#
|
59
|
+
def self.subscribe
|
60
|
+
new
|
61
|
+
.subscribe('meta_request.log')
|
62
|
+
.subscribe('sql.active_record', &SQL_BLOCK)
|
63
|
+
.subscribe('sql.sequel', &SQL_BLOCK)
|
64
|
+
.subscribe('render_partial.action_view', &VIEW_BLOCK)
|
65
|
+
.subscribe('render_template.action_view', &VIEW_BLOCK)
|
66
|
+
.subscribe('process_action.action_controller.exception')
|
67
|
+
.subscribe('process_action.action_controller') do |*args|
|
68
|
+
name, start, ending, transaction_id, payload = args
|
69
|
+
payload[:status] = '500' if payload[:exception]
|
70
|
+
Event.new(name, start, ending, transaction_id, payload)
|
71
|
+
end
|
72
|
+
.subscribe('cache_read.active_support', &CACHE_BLOCK)
|
73
|
+
.subscribe('cache_generate.active_support', &CACHE_BLOCK)
|
74
|
+
.subscribe('cache_fetch_hit.active_support', &CACHE_BLOCK)
|
75
|
+
.subscribe('cache_write.active_support', &CACHE_BLOCK)
|
76
|
+
.subscribe('cache_delete.active_support', &CACHE_BLOCK)
|
77
|
+
.subscribe('cache_exist?.active_support', &CACHE_BLOCK)
|
78
|
+
end
|
79
|
+
|
80
|
+
def subscribe(event_name)
|
81
|
+
ActiveSupport::Notifications.subscribe(event_name) do |*args|
|
82
|
+
event = block_given? ? yield(*args) : Event.new(*args)
|
83
|
+
AppRequest.current.events << event if AppRequest.current
|
84
|
+
end
|
85
|
+
self
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -1,20 +1,20 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MetaRequest
|
4
|
-
class AppRequest
|
5
|
-
attr_reader :id, :events
|
6
|
-
|
7
|
-
def initialize(id)
|
8
|
-
@id = id
|
9
|
-
@events = []
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.current
|
13
|
-
Thread.current[:meta_request_id]
|
14
|
-
end
|
15
|
-
|
16
|
-
def current!
|
17
|
-
Thread.current[:meta_request_id] = self
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaRequest
|
4
|
+
class AppRequest
|
5
|
+
attr_reader :id, :events
|
6
|
+
|
7
|
+
def initialize(id)
|
8
|
+
@id = id
|
9
|
+
@events = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.current
|
13
|
+
Thread.current[:meta_request_id]
|
14
|
+
end
|
15
|
+
|
16
|
+
def current!
|
17
|
+
Thread.current[:meta_request_id] = self
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/meta_request/config.rb
CHANGED
@@ -1,22 +1,22 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MetaRequest
|
4
|
-
class Config
|
5
|
-
attr_writer :logger, :storage_pool_size, :source_path
|
6
|
-
|
7
|
-
# logger used for reporting gem's fatal errors
|
8
|
-
def logger
|
9
|
-
@logger ||= Logger.new(File.join(Rails.root, 'log', 'meta_request.log'))
|
10
|
-
end
|
11
|
-
|
12
|
-
# Number of files kept in storage.
|
13
|
-
# Increase when using an application loading many simultaneous requests.
|
14
|
-
def storage_pool_size
|
15
|
-
@storage_pool_size ||= 20
|
16
|
-
end
|
17
|
-
|
18
|
-
def source_path
|
19
|
-
@source_path ||= ENV['SOURCE_PATH'] || Rails.root.to_s
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaRequest
|
4
|
+
class Config
|
5
|
+
attr_writer :logger, :storage_pool_size, :source_path
|
6
|
+
|
7
|
+
# logger used for reporting gem's fatal errors
|
8
|
+
def logger
|
9
|
+
@logger ||= Logger.new(File.join(Rails.root, 'log', 'meta_request.log'))
|
10
|
+
end
|
11
|
+
|
12
|
+
# Number of files kept in storage.
|
13
|
+
# Increase when using an application loading many simultaneous requests.
|
14
|
+
def storage_pool_size
|
15
|
+
@storage_pool_size ||= 20
|
16
|
+
end
|
17
|
+
|
18
|
+
def source_path
|
19
|
+
@source_path ||= ENV['SOURCE_PATH'] || Rails.root.to_s
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/meta_request/event.rb
CHANGED
@@ -1,78 +1,78 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support'
|
4
|
-
require 'active_support/json'
|
5
|
-
require 'active_support/core_ext'
|
6
|
-
|
7
|
-
module MetaRequest
|
8
|
-
# Subclass of ActiveSupport Event that is JSON encodable
|
9
|
-
#
|
10
|
-
class Event < ActiveSupport::Notifications::Event
|
11
|
-
NOT_JSON_ENCODABLE = 'Not JSON Encodable'
|
12
|
-
|
13
|
-
attr_reader :duration
|
14
|
-
|
15
|
-
def initialize(name, start, ending, transaction_id, payload)
|
16
|
-
super(name, start, ending, transaction_id, json_encodable(payload))
|
17
|
-
@duration = 1000.0 * (ending - start)
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.events_for_exception(exception_wrapper)
|
21
|
-
if defined?(ActionDispatch::ExceptionWrapper)
|
22
|
-
exception = exception_wrapper.exception
|
23
|
-
trace = exception_wrapper.application_trace
|
24
|
-
trace = exception_wrapper.framework_trace if trace.empty?
|
25
|
-
else
|
26
|
-
exception = exception_wrapper
|
27
|
-
trace = exception.backtrace
|
28
|
-
end
|
29
|
-
trace.unshift "#{exception.class} (#{exception.message})"
|
30
|
-
trace.map do |call|
|
31
|
-
Event.new('process_action.action_controller.exception', 0, 0, nil, call: call)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def json_encodable(payload)
|
38
|
-
return {} unless payload.is_a?(Hash)
|
39
|
-
|
40
|
-
transform_hash(payload, deep: true) do |hash, key, value|
|
41
|
-
if value.class.to_s == 'ActionDispatch::Http::Headers'
|
42
|
-
value = value.to_h.select { |k, _| k.upcase == k }
|
43
|
-
elsif not_encodable?(value)
|
44
|
-
value = NOT_JSON_ENCODABLE
|
45
|
-
end
|
46
|
-
|
47
|
-
begin
|
48
|
-
value.to_json(methods: [:duration])
|
49
|
-
new_value = value
|
50
|
-
rescue StandardError
|
51
|
-
new_value = NOT_JSON_ENCODABLE
|
52
|
-
end
|
53
|
-
hash[key] = new_value
|
54
|
-
end.with_indifferent_access
|
55
|
-
end
|
56
|
-
|
57
|
-
def not_encodable?(value)
|
58
|
-
(defined?(ActiveRecord) && value.is_a?(ActiveRecord::ConnectionAdapters::AbstractAdapter)) ||
|
59
|
-
(defined?(ActionDispatch) &&
|
60
|
-
(value.is_a?(ActionDispatch::Request) || value.is_a?(ActionDispatch::Response)))
|
61
|
-
end
|
62
|
-
|
63
|
-
# https://gist.github.com/dbenhur/1070399
|
64
|
-
def transform_hash(original, options = {}, &block)
|
65
|
-
options[:safe_descent] ||= {}
|
66
|
-
new_hash = {}
|
67
|
-
options[:safe_descent][original.object_id] = new_hash
|
68
|
-
original.each_with_object(new_hash) do |(key, value), result|
|
69
|
-
if options[:deep] && Hash === value
|
70
|
-
value = options[:safe_descent].fetch(value.object_id) do
|
71
|
-
transform_hash(value, options, &block)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
block.call(result, key, value)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support'
|
4
|
+
require 'active_support/json'
|
5
|
+
require 'active_support/core_ext'
|
6
|
+
|
7
|
+
module MetaRequest
|
8
|
+
# Subclass of ActiveSupport Event that is JSON encodable
|
9
|
+
#
|
10
|
+
class Event < ActiveSupport::Notifications::Event
|
11
|
+
NOT_JSON_ENCODABLE = 'Not JSON Encodable'
|
12
|
+
|
13
|
+
attr_reader :duration
|
14
|
+
|
15
|
+
def initialize(name, start, ending, transaction_id, payload)
|
16
|
+
super(name, start, ending, transaction_id, json_encodable(payload))
|
17
|
+
@duration = 1000.0 * (ending - start)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.events_for_exception(exception_wrapper)
|
21
|
+
if defined?(ActionDispatch::ExceptionWrapper)
|
22
|
+
exception = exception_wrapper.exception
|
23
|
+
trace = exception_wrapper.application_trace
|
24
|
+
trace = exception_wrapper.framework_trace if trace.empty?
|
25
|
+
else
|
26
|
+
exception = exception_wrapper
|
27
|
+
trace = exception.backtrace
|
28
|
+
end
|
29
|
+
trace.unshift "#{exception.class} (#{exception.message})"
|
30
|
+
trace.map do |call|
|
31
|
+
Event.new('process_action.action_controller.exception', 0, 0, nil, call: call)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def json_encodable(payload)
|
38
|
+
return {} unless payload.is_a?(Hash)
|
39
|
+
|
40
|
+
transform_hash(payload, deep: true) do |hash, key, value|
|
41
|
+
if value.class.to_s == 'ActionDispatch::Http::Headers'
|
42
|
+
value = value.to_h.select { |k, _| k.upcase == k }
|
43
|
+
elsif not_encodable?(value)
|
44
|
+
value = NOT_JSON_ENCODABLE
|
45
|
+
end
|
46
|
+
|
47
|
+
begin
|
48
|
+
value.to_json(methods: [:duration])
|
49
|
+
new_value = value
|
50
|
+
rescue StandardError
|
51
|
+
new_value = NOT_JSON_ENCODABLE
|
52
|
+
end
|
53
|
+
hash[key] = new_value
|
54
|
+
end.with_indifferent_access
|
55
|
+
end
|
56
|
+
|
57
|
+
def not_encodable?(value)
|
58
|
+
(defined?(ActiveRecord) && value.is_a?(ActiveRecord::ConnectionAdapters::AbstractAdapter)) ||
|
59
|
+
(defined?(ActionDispatch) &&
|
60
|
+
(value.is_a?(ActionDispatch::Request) || value.is_a?(ActionDispatch::Response)))
|
61
|
+
end
|
62
|
+
|
63
|
+
# https://gist.github.com/dbenhur/1070399
|
64
|
+
def transform_hash(original, options = {}, &block)
|
65
|
+
options[:safe_descent] ||= {}
|
66
|
+
new_hash = {}
|
67
|
+
options[:safe_descent][original.object_id] = new_hash
|
68
|
+
original.each_with_object(new_hash) do |(key, value), result|
|
69
|
+
if options[:deep] && Hash === value
|
70
|
+
value = options[:safe_descent].fetch(value.object_id) do
|
71
|
+
transform_hash(value, options, &block)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
block.call(result, key, value)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -1,47 +1,47 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MetaRequest
|
4
|
-
module LogInterceptor
|
5
|
-
def debug(message = nil, *args)
|
6
|
-
push_event(:debug, message)
|
7
|
-
super
|
8
|
-
end
|
9
|
-
|
10
|
-
def info(message = nil, *args)
|
11
|
-
push_event(:info, message)
|
12
|
-
super
|
13
|
-
end
|
14
|
-
|
15
|
-
def warn(message = nil, *args)
|
16
|
-
push_event(:warn, message)
|
17
|
-
super
|
18
|
-
end
|
19
|
-
|
20
|
-
def error(message = nil, *args)
|
21
|
-
push_event(:error, message)
|
22
|
-
super
|
23
|
-
end
|
24
|
-
|
25
|
-
def fatal(message = nil, *args)
|
26
|
-
push_event(:fatal, message)
|
27
|
-
super
|
28
|
-
end
|
29
|
-
|
30
|
-
def unknown(message = nil, *args)
|
31
|
-
push_event(:unknown, message)
|
32
|
-
super
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def push_event(level, message)
|
38
|
-
callsite = AppRequest.current && Utils.dev_callsite(caller.drop(1))
|
39
|
-
if callsite
|
40
|
-
payload = callsite.merge(message: message, level: level)
|
41
|
-
AppRequest.current.events << Event.new('meta_request.log', 0, 0, 0, payload)
|
42
|
-
end
|
43
|
-
rescue StandardError => e
|
44
|
-
MetaRequest.config.logger.fatal(e.message + "\n " + e.backtrace.join("\n "))
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaRequest
|
4
|
+
module LogInterceptor
|
5
|
+
def debug(message = nil, *args)
|
6
|
+
push_event(:debug, message)
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def info(message = nil, *args)
|
11
|
+
push_event(:info, message)
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def warn(message = nil, *args)
|
16
|
+
push_event(:warn, message)
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
def error(message = nil, *args)
|
21
|
+
push_event(:error, message)
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def fatal(message = nil, *args)
|
26
|
+
push_event(:fatal, message)
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
def unknown(message = nil, *args)
|
31
|
+
push_event(:unknown, message)
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def push_event(level, message)
|
38
|
+
callsite = AppRequest.current && Utils.dev_callsite(caller.drop(1))
|
39
|
+
if callsite
|
40
|
+
payload = callsite.merge(message: message, level: level)
|
41
|
+
AppRequest.current.events << Event.new('meta_request.log', 0, 0, 0, payload)
|
42
|
+
end
|
43
|
+
rescue StandardError => e
|
44
|
+
MetaRequest.config.logger.fatal(e.message + "\n " + e.backtrace.join("\n "))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -1,33 +1,33 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'json'
|
4
|
-
|
5
|
-
module MetaRequest
|
6
|
-
module Middlewares
|
7
|
-
class AppRequestHandler
|
8
|
-
def initialize(app)
|
9
|
-
@app = app
|
10
|
-
end
|
11
|
-
|
12
|
-
def call(env)
|
13
|
-
app_request = AppRequest.new env['action_dispatch.request_id']
|
14
|
-
app_request.current!
|
15
|
-
@app.call(env)
|
16
|
-
rescue StandardError => e
|
17
|
-
if defined?(ActionDispatch::ExceptionWrapper)
|
18
|
-
wrapper = if ActionDispatch::ExceptionWrapper.method_defined? :env
|
19
|
-
ActionDispatch::ExceptionWrapper.new(env, e)
|
20
|
-
else
|
21
|
-
ActionDispatch::ExceptionWrapper.new(env['action_dispatch.backtrace_cleaner'], e)
|
22
|
-
end
|
23
|
-
app_request.events.push(*Event.events_for_exception(wrapper))
|
24
|
-
else
|
25
|
-
app_request.events.push(*Event.events_for_exception(e))
|
26
|
-
end
|
27
|
-
raise
|
28
|
-
ensure
|
29
|
-
Storage.new(app_request.id).write(app_request.events.to_json) unless app_request.events.empty?
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module MetaRequest
|
6
|
+
module Middlewares
|
7
|
+
class AppRequestHandler
|
8
|
+
def initialize(app)
|
9
|
+
@app = app
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
app_request = AppRequest.new env['action_dispatch.request_id']
|
14
|
+
app_request.current!
|
15
|
+
@app.call(env)
|
16
|
+
rescue StandardError => e
|
17
|
+
if defined?(ActionDispatch::ExceptionWrapper)
|
18
|
+
wrapper = if ActionDispatch::ExceptionWrapper.method_defined? :env
|
19
|
+
ActionDispatch::ExceptionWrapper.new(env, e)
|
20
|
+
else
|
21
|
+
ActionDispatch::ExceptionWrapper.new(env['action_dispatch.backtrace_cleaner'], e)
|
22
|
+
end
|
23
|
+
app_request.events.push(*Event.events_for_exception(wrapper))
|
24
|
+
else
|
25
|
+
app_request.events.push(*Event.events_for_exception(e))
|
26
|
+
end
|
27
|
+
raise
|
28
|
+
ensure
|
29
|
+
Storage.new(app_request.id).write(app_request.events.to_json) unless app_request.events.empty?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,38 +1,38 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rack/contrib/response_headers'
|
4
|
-
|
5
|
-
module MetaRequest
|
6
|
-
module Middlewares
|
7
|
-
class Headers
|
8
|
-
def initialize(app, app_config)
|
9
|
-
@app = app
|
10
|
-
@app_config = app_config
|
11
|
-
end
|
12
|
-
|
13
|
-
def call(env)
|
14
|
-
request_path = env['PATH_INFO']
|
15
|
-
middleware = Rack::ResponseHeaders.new(@app) do |headers|
|
16
|
-
headers['X-Meta-Request-Version'] = MetaRequest::VERSION unless skip?(request_path)
|
17
|
-
end
|
18
|
-
middleware.call(env)
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
# returns true if path should be ignored (not handled by RailsPanel extension)
|
24
|
-
#
|
25
|
-
def skip?(path)
|
26
|
-
asset?(path) || path.start_with?('/__better_errors/')
|
27
|
-
end
|
28
|
-
|
29
|
-
def asset?(path)
|
30
|
-
@app_config.respond_to?(:assets) && path.start_with?(assets_prefix)
|
31
|
-
end
|
32
|
-
|
33
|
-
def assets_prefix
|
34
|
-
"/#{@app_config.assets.prefix[%r{\A/?(.*?)/?\z}, 1]}/"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack/contrib/response_headers'
|
4
|
+
|
5
|
+
module MetaRequest
|
6
|
+
module Middlewares
|
7
|
+
class Headers
|
8
|
+
def initialize(app, app_config)
|
9
|
+
@app = app
|
10
|
+
@app_config = app_config
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
request_path = env['PATH_INFO']
|
15
|
+
middleware = Rack::ResponseHeaders.new(@app) do |headers|
|
16
|
+
headers['X-Meta-Request-Version'] = MetaRequest::VERSION unless skip?(request_path)
|
17
|
+
end
|
18
|
+
middleware.call(env)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# returns true if path should be ignored (not handled by RailsPanel extension)
|
24
|
+
#
|
25
|
+
def skip?(path)
|
26
|
+
asset?(path) || path.start_with?('/__better_errors/')
|
27
|
+
end
|
28
|
+
|
29
|
+
def asset?(path)
|
30
|
+
@app_config.respond_to?(:assets) && path.start_with?(assets_prefix)
|
31
|
+
end
|
32
|
+
|
33
|
+
def assets_prefix
|
34
|
+
"/#{@app_config.assets.prefix[%r{\A/?(.*?)/?\z}, 1]}/"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,27 +1,27 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MetaRequest
|
4
|
-
module Middlewares
|
5
|
-
class MetaRequestHandler
|
6
|
-
def initialize(app)
|
7
|
-
@app = app
|
8
|
-
end
|
9
|
-
|
10
|
-
def call(env)
|
11
|
-
request_id = env['PATH_INFO'][%r{/__meta_request/(.+)\.json$}, 1]
|
12
|
-
if request_id
|
13
|
-
events_json(request_id)
|
14
|
-
else
|
15
|
-
@app.call(env)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def events_json(request_id)
|
22
|
-
events_json = Storage.new(request_id).read
|
23
|
-
[200, { 'Content-Type' => 'text/plain; charset=utf-8' }, [events_json]]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaRequest
|
4
|
+
module Middlewares
|
5
|
+
class MetaRequestHandler
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
request_id = env['PATH_INFO'][%r{/__meta_request/(.+)\.json$}, 1]
|
12
|
+
if request_id
|
13
|
+
events_json(request_id)
|
14
|
+
else
|
15
|
+
@app.call(env)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def events_json(request_id)
|
22
|
+
events_json = Storage.new(request_id).read
|
23
|
+
[200, { 'Content-Type' => 'text/plain; charset=utf-8' }, [events_json]]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MetaRequest
|
4
|
-
module Middlewares
|
5
|
-
autoload :Headers, 'meta_request/middlewares/headers'
|
6
|
-
autoload :AppRequestHandler, 'meta_request/middlewares/app_request_handler'
|
7
|
-
autoload :MetaRequestHandler, 'meta_request/middlewares/meta_request_handler'
|
8
|
-
end
|
9
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaRequest
|
4
|
+
module Middlewares
|
5
|
+
autoload :Headers, 'meta_request/middlewares/headers'
|
6
|
+
autoload :AppRequestHandler, 'meta_request/middlewares/app_request_handler'
|
7
|
+
autoload :MetaRequestHandler, 'meta_request/middlewares/meta_request_handler'
|
8
|
+
end
|
9
|
+
end
|
data/lib/meta_request/railtie.rb
CHANGED
@@ -1,27 +1,27 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rails/railtie'
|
4
|
-
|
5
|
-
module MetaRequest
|
6
|
-
class Railtie < ::Rails::Railtie
|
7
|
-
initializer 'meta_request.inject_middlewares' do |app|
|
8
|
-
app.middleware.use Middlewares::MetaRequestHandler
|
9
|
-
|
10
|
-
if defined? ActionDispatch::DebugExceptions
|
11
|
-
app.middleware.insert_before ActionDispatch::DebugExceptions, Middlewares::Headers, app.config
|
12
|
-
else
|
13
|
-
app.middleware.use Middlewares::Headers, app.config
|
14
|
-
end
|
15
|
-
|
16
|
-
app.middleware.use Middlewares::AppRequestHandler
|
17
|
-
end
|
18
|
-
|
19
|
-
initializer 'meta_request.log_interceptor' do
|
20
|
-
Rails.logger&.extend(LogInterceptor)
|
21
|
-
end
|
22
|
-
|
23
|
-
initializer 'meta_request.subscribe_to_notifications' do
|
24
|
-
AppNotifications.subscribe
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/railtie'
|
4
|
+
|
5
|
+
module MetaRequest
|
6
|
+
class Railtie < ::Rails::Railtie
|
7
|
+
initializer 'meta_request.inject_middlewares' do |app|
|
8
|
+
app.middleware.use Middlewares::MetaRequestHandler
|
9
|
+
|
10
|
+
if defined? ActionDispatch::DebugExceptions
|
11
|
+
app.middleware.insert_before ActionDispatch::DebugExceptions, Middlewares::Headers, app.config
|
12
|
+
else
|
13
|
+
app.middleware.use Middlewares::Headers, app.config
|
14
|
+
end
|
15
|
+
|
16
|
+
app.middleware.use Middlewares::AppRequestHandler
|
17
|
+
end
|
18
|
+
|
19
|
+
initializer 'meta_request.log_interceptor' do
|
20
|
+
Rails.logger&.extend(LogInterceptor)
|
21
|
+
end
|
22
|
+
|
23
|
+
initializer 'meta_request.subscribe_to_notifications' do
|
24
|
+
AppNotifications.subscribe
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/meta_request/storage.rb
CHANGED
@@ -1,45 +1,45 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MetaRequest
|
4
|
-
class Storage
|
5
|
-
attr_reader :key
|
6
|
-
|
7
|
-
def initialize(key)
|
8
|
-
@key = key
|
9
|
-
end
|
10
|
-
|
11
|
-
def write(value)
|
12
|
-
FileUtils.mkdir_p dir_path
|
13
|
-
File.open(json_file, 'wb') { |file| file.write(value) }
|
14
|
-
maintain_file_pool(MetaRequest.config.storage_pool_size)
|
15
|
-
end
|
16
|
-
|
17
|
-
def read
|
18
|
-
File.read(json_file)
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def maintain_file_pool(size)
|
24
|
-
files = Dir["#{dir_path}/*.json"]
|
25
|
-
files = files.sort_by { |f| -file_ctime(f) }
|
26
|
-
(files[size..-1] || []).each do |file|
|
27
|
-
FileUtils.rm_f(file)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def file_ctime(file)
|
32
|
-
File.stat(file).ctime.to_i
|
33
|
-
rescue Errno::ENOENT
|
34
|
-
0
|
35
|
-
end
|
36
|
-
|
37
|
-
def json_file
|
38
|
-
File.join(dir_path, "#{key}.json")
|
39
|
-
end
|
40
|
-
|
41
|
-
def dir_path
|
42
|
-
File.join(Rails.root, 'tmp', 'data', 'meta_request')
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaRequest
|
4
|
+
class Storage
|
5
|
+
attr_reader :key
|
6
|
+
|
7
|
+
def initialize(key)
|
8
|
+
@key = key
|
9
|
+
end
|
10
|
+
|
11
|
+
def write(value)
|
12
|
+
FileUtils.mkdir_p dir_path
|
13
|
+
File.open(json_file, 'wb') { |file| file.write(value) }
|
14
|
+
maintain_file_pool(MetaRequest.config.storage_pool_size)
|
15
|
+
end
|
16
|
+
|
17
|
+
def read
|
18
|
+
File.read(json_file)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def maintain_file_pool(size)
|
24
|
+
files = Dir["#{dir_path}/*.json"]
|
25
|
+
files = files.sort_by { |f| -file_ctime(f) }
|
26
|
+
(files[size..-1] || []).each do |file|
|
27
|
+
FileUtils.rm_f(file)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def file_ctime(file)
|
32
|
+
File.stat(file).ctime.to_i
|
33
|
+
rescue Errno::ENOENT
|
34
|
+
0
|
35
|
+
end
|
36
|
+
|
37
|
+
def json_file
|
38
|
+
File.join(dir_path, "#{key}.json")
|
39
|
+
end
|
40
|
+
|
41
|
+
def dir_path
|
42
|
+
File.join(Rails.root, 'tmp', 'data', 'meta_request')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/meta_request/utils.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MetaRequest
|
4
|
-
module Utils
|
5
|
-
module_function
|
6
|
-
|
7
|
-
def dev_callsite(caller)
|
8
|
-
app_line = caller.detect { |c| c.start_with? MetaRequest.rails_root }
|
9
|
-
return nil unless app_line
|
10
|
-
|
11
|
-
_, filename, _, line, _, method = app_line.split(/^(.*?)(:(\d+))(:in `(.*)')?$/)
|
12
|
-
|
13
|
-
{
|
14
|
-
filename: sub_source_path(filename),
|
15
|
-
line: line.to_i,
|
16
|
-
method: method
|
17
|
-
}
|
18
|
-
end
|
19
|
-
|
20
|
-
def sub_source_path(path)
|
21
|
-
rails_root = MetaRequest.rails_root
|
22
|
-
source_path = MetaRequest.config.source_path
|
23
|
-
return path if rails_root == source_path
|
24
|
-
|
25
|
-
path.sub(rails_root, source_path)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaRequest
|
4
|
+
module Utils
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def dev_callsite(caller)
|
8
|
+
app_line = caller.detect { |c| c.start_with? MetaRequest.rails_root }
|
9
|
+
return nil unless app_line
|
10
|
+
|
11
|
+
_, filename, _, line, _, method = app_line.split(/^(.*?)(:(\d+))(:in `(.*)')?$/)
|
12
|
+
|
13
|
+
{
|
14
|
+
filename: sub_source_path(filename),
|
15
|
+
line: line.to_i,
|
16
|
+
method: method
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def sub_source_path(path)
|
21
|
+
rails_root = MetaRequest.rails_root
|
22
|
+
source_path = MetaRequest.config.source_path
|
23
|
+
return path if rails_root == source_path
|
24
|
+
|
25
|
+
path.sub(rails_root, source_path)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/meta_request/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MetaRequest
|
4
|
-
VERSION = Gem.loaded_specs['meta_request'].version.to_s
|
5
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaRequest
|
4
|
+
VERSION = Gem.loaded_specs['meta_request'].version.to_s
|
5
|
+
end
|
data/lib/meta_request.rb
CHANGED
@@ -1,29 +1,29 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module MetaRequest
|
4
|
-
autoload :VERSION, 'meta_request/version'
|
5
|
-
autoload :Config, 'meta_request/config'
|
6
|
-
autoload :Event, 'meta_request/event'
|
7
|
-
autoload :AppRequest, 'meta_request/app_request'
|
8
|
-
autoload :Storage, 'meta_request/storage'
|
9
|
-
autoload :Middlewares, 'meta_request/middlewares'
|
10
|
-
autoload :LogInterceptor, 'meta_request/log_interceptor'
|
11
|
-
autoload :AppNotifications, 'meta_request/app_notifications'
|
12
|
-
autoload :Utils, 'meta_request/utils'
|
13
|
-
|
14
|
-
def self.config
|
15
|
-
@config ||= Config.new
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.configure
|
19
|
-
yield config
|
20
|
-
end
|
21
|
-
|
22
|
-
# stash a frozen copy away so we're not allocating a new string over and over
|
23
|
-
# again in AppNotifications and LogInterceptor
|
24
|
-
def self.rails_root
|
25
|
-
@rails_root ||= Rails.root.to_s.freeze
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
require 'meta_request/railtie'
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MetaRequest
|
4
|
+
autoload :VERSION, 'meta_request/version'
|
5
|
+
autoload :Config, 'meta_request/config'
|
6
|
+
autoload :Event, 'meta_request/event'
|
7
|
+
autoload :AppRequest, 'meta_request/app_request'
|
8
|
+
autoload :Storage, 'meta_request/storage'
|
9
|
+
autoload :Middlewares, 'meta_request/middlewares'
|
10
|
+
autoload :LogInterceptor, 'meta_request/log_interceptor'
|
11
|
+
autoload :AppNotifications, 'meta_request/app_notifications'
|
12
|
+
autoload :Utils, 'meta_request/utils'
|
13
|
+
|
14
|
+
def self.config
|
15
|
+
@config ||= Config.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.configure
|
19
|
+
yield config
|
20
|
+
end
|
21
|
+
|
22
|
+
# stash a frozen copy away so we're not allocating a new string over and over
|
23
|
+
# again in AppNotifications and LogInterceptor
|
24
|
+
def self.rails_root
|
25
|
+
@rails_root ||= Rails.root.to_s.freeze
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
require 'meta_request/railtie'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meta_request
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dejan Simic
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack-contrib
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
version: 3.0.0
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '7'
|
42
|
+
version: '7.1'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -49,7 +49,7 @@ dependencies:
|
|
49
49
|
version: 3.0.0
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: '7'
|
52
|
+
version: '7.1'
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: rspec
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -103,7 +103,7 @@ homepage: https://github.com/dejan/rails_panel/tree/master/meta_request
|
|
103
103
|
licenses:
|
104
104
|
- MIT
|
105
105
|
metadata: {}
|
106
|
-
post_install_message:
|
106
|
+
post_install_message:
|
107
107
|
rdoc_options: []
|
108
108
|
require_paths:
|
109
109
|
- lib
|
@@ -118,8 +118,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
118
|
- !ruby/object:Gem::Version
|
119
119
|
version: '0'
|
120
120
|
requirements: []
|
121
|
-
rubygems_version: 3.
|
122
|
-
signing_key:
|
121
|
+
rubygems_version: 3.3.7
|
122
|
+
signing_key:
|
123
123
|
specification_version: 4
|
124
124
|
summary: Request your Rails request
|
125
125
|
test_files: []
|