meta_request 0.4.3 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +30 -0
- data/lib/meta_request.rb +9 -3
- data/lib/meta_request/app_notifications.rb +30 -17
- data/lib/meta_request/config.rb +20 -0
- data/lib/meta_request/event.rb +9 -1
- data/lib/meta_request/log_interceptor.rb +4 -8
- data/lib/meta_request/middlewares.rb +0 -1
- data/lib/meta_request/railtie.rb +0 -1
- data/lib/meta_request/storage.rb +2 -2
- data/lib/meta_request/utils.rb +25 -0
- data/lib/meta_request/version.rb +1 -1
- metadata +7 -27
- data/lib/meta_request/middlewares/request_id.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 40d50e7981aca25dd87449d817b7a6e223491be3cb2155ad3ee82e081afce02f
|
4
|
+
data.tar.gz: 8fa75570b5c5b41b546f71aa883bd9df3bdf9b76e4a6a38f5498aa3af641e0fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22764f1ec9e723a596e56993c802e541263ce1c7902b88c30902d69701a4b47705c404ce85fd3d2240f5fda7f5d1e85f0512f192647d181e10f30a5f13c6e6a0
|
7
|
+
data.tar.gz: 4c62d0983519f5ae3779759aeba06354e6cb9d4c920feb42f9966be91d0615ca8439c7749109435c3d916f1a40d3718b7c9c5dc99d88b50a04ee44b243b74374
|
data/README.md
CHANGED
@@ -23,6 +23,36 @@ If you're using [LiveReload](http://livereload.com/) or
|
|
23
23
|
exclude watching your tmp/ folder because meta_request writes a lot of data there
|
24
24
|
and your browser will refresh like a madman.
|
25
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
|
+
|
26
56
|
## Licence
|
27
57
|
|
28
58
|
Copyright (c) 2012 Dejan Simic
|
data/lib/meta_request.rb
CHANGED
@@ -1,20 +1,26 @@
|
|
1
1
|
module MetaRequest
|
2
2
|
autoload :VERSION, "meta_request/version"
|
3
|
+
autoload :Config, "meta_request/config"
|
3
4
|
autoload :Event, "meta_request/event"
|
4
5
|
autoload :AppRequest, "meta_request/app_request"
|
5
6
|
autoload :Storage, "meta_request/storage"
|
6
7
|
autoload :Middlewares, "meta_request/middlewares"
|
7
8
|
autoload :LogInterceptor, "meta_request/log_interceptor"
|
8
9
|
autoload :AppNotifications, "meta_request/app_notifications"
|
10
|
+
autoload :Utils, "meta_request/utils"
|
9
11
|
|
10
|
-
def self.
|
11
|
-
|
12
|
+
def self.config
|
13
|
+
@config ||= Config.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.configure
|
17
|
+
yield config
|
12
18
|
end
|
13
19
|
|
14
20
|
# stash a frozen copy away so we're not allocating a new string over and over
|
15
21
|
# again in AppNotifications and LogInterceptor
|
16
22
|
def self.rails_root
|
17
|
-
|
23
|
+
@rails_root ||= Rails.root.to_s.freeze
|
18
24
|
end
|
19
25
|
end
|
20
26
|
|
@@ -24,34 +24,47 @@ module MetaRequest
|
|
24
24
|
payload[:options][k] = payload.delete(k) unless k.in? CACHE_KEY_COLUMNS
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
if
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
callsite = Utils.dev_callsite(caller)
|
28
|
+
payload.merge!(callsite) if callsite
|
29
|
+
|
30
|
+
Event.new(name, start, ending, transaction_id, payload)
|
31
|
+
}
|
32
|
+
|
33
|
+
# sql processing block - used for sql.active_record and sql.sequel
|
34
|
+
|
35
|
+
# HACK: we hardcode the event name to 'sql.active_record' so that the ui will
|
36
|
+
# display sequel events without modification. otherwise the ui would need to
|
37
|
+
# be modified to support a sequel tab (or to change the display name on the
|
38
|
+
# active_record tab when necessary - which maybe makes more sense?)
|
39
|
+
SQL_EVENT_NAME = "sql.active_record"
|
40
|
+
|
41
|
+
SQL_BLOCK = Proc.new {|*args|
|
42
|
+
name, start, ending, transaction_id, payload = args
|
43
|
+
callsite = Utils.dev_callsite(caller)
|
44
|
+
payload.merge!(callsite) if callsite
|
45
|
+
|
46
|
+
Event.new(SQL_EVENT_NAME, start, ending, transaction_id, payload)
|
47
|
+
}
|
48
|
+
|
49
|
+
VIEW_BLOCK = Proc.new {|*args|
|
50
|
+
name, start, ending, transaction_id, payload = args
|
51
|
+
payload[:identifier] = MetaRequest::Utils.sub_source_path(payload[:identifier])
|
32
52
|
|
33
53
|
Event.new(name, start, ending, transaction_id, payload)
|
34
54
|
}
|
55
|
+
|
35
56
|
# Subscribe to all events relevant to RailsPanel
|
36
57
|
#
|
37
58
|
def self.subscribe
|
38
59
|
new.
|
39
60
|
subscribe("meta_request.log").
|
40
|
-
subscribe("sql.active_record")
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
c = Callsite.parse(dev_caller)
|
45
|
-
payload.merge!(:line => c.line, :filename => c.filename, :method => c.method)
|
46
|
-
end
|
47
|
-
Event.new(name, start, ending, transaction_id, payload)
|
48
|
-
end.
|
49
|
-
subscribe("render_partial.action_view").
|
50
|
-
subscribe("render_template.action_view").
|
61
|
+
subscribe("sql.active_record", &SQL_BLOCK).
|
62
|
+
subscribe("sql.sequel", &SQL_BLOCK).
|
63
|
+
subscribe("render_partial.action_view", &VIEW_BLOCK).
|
64
|
+
subscribe("render_template.action_view", &VIEW_BLOCK).
|
51
65
|
subscribe("process_action.action_controller.exception").
|
52
66
|
subscribe("process_action.action_controller") do |*args|
|
53
67
|
name, start, ending, transaction_id, payload = args
|
54
|
-
payload[:format] ||= (payload[:formats]||[]).first # Rails 3.0.x Support
|
55
68
|
payload[:status] = '500' if payload[:exception]
|
56
69
|
Event.new(name, start, ending, transaction_id, payload)
|
57
70
|
end.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module MetaRequest
|
2
|
+
class Config
|
3
|
+
attr_writer :logger, :storage_pool_size, :source_path
|
4
|
+
|
5
|
+
# logger used for reporting gem's fatal errors
|
6
|
+
def logger
|
7
|
+
@logger ||= Logger.new(File.join(Rails.root, 'log', 'meta_request.log'))
|
8
|
+
end
|
9
|
+
|
10
|
+
# Number of files kept in storage.
|
11
|
+
# Increase when using an application loading many simultaneous requests.
|
12
|
+
def storage_pool_size
|
13
|
+
@storage_pool_size ||= 20
|
14
|
+
end
|
15
|
+
|
16
|
+
def source_path
|
17
|
+
@source_path ||= ENV['SOURCE_PATH'] || Rails.root.to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/meta_request/event.rb
CHANGED
@@ -7,6 +7,8 @@ module MetaRequest
|
|
7
7
|
# Subclass of ActiveSupport Event that is JSON encodable
|
8
8
|
#
|
9
9
|
class Event < ActiveSupport::Notifications::Event
|
10
|
+
NOT_JSON_ENCODABLE = 'Not JSON Encodable'.freeze
|
11
|
+
|
10
12
|
attr_reader :duration
|
11
13
|
|
12
14
|
def initialize(name, start, ending, transaction_id, payload)
|
@@ -34,11 +36,17 @@ module MetaRequest
|
|
34
36
|
def json_encodable(payload)
|
35
37
|
return {} unless payload.is_a?(Hash)
|
36
38
|
transform_hash(payload, :deep => true) { |hash, key, value|
|
39
|
+
if value.class.to_s == 'ActionDispatch::Http::Headers'
|
40
|
+
value = value.to_h.select { |k, _| k.upcase == k }
|
41
|
+
elsif defined?(ActiveRecord) && value.is_a?(ActiveRecord::ConnectionAdapters::AbstractAdapter)
|
42
|
+
value = NOT_JSON_ENCODABLE
|
43
|
+
end
|
44
|
+
|
37
45
|
begin
|
38
46
|
value.to_json(:methods => [:duration])
|
39
47
|
new_value = value
|
40
48
|
rescue
|
41
|
-
new_value =
|
49
|
+
new_value = NOT_JSON_ENCODABLE
|
42
50
|
end
|
43
51
|
hash[key] = new_value
|
44
52
|
}.with_indifferent_access
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'callsite'
|
2
|
-
|
3
1
|
module MetaRequest
|
4
2
|
module LogInterceptor
|
5
3
|
|
@@ -33,17 +31,15 @@ module MetaRequest
|
|
33
31
|
super
|
34
32
|
end
|
35
33
|
|
36
|
-
|
37
34
|
private
|
38
35
|
def push_event(level, message)
|
39
|
-
|
40
|
-
if
|
41
|
-
|
42
|
-
payload = {:message => message, :level => level, :line => c.line, :filename => c.filename, :method => c.method}
|
36
|
+
callsite = AppRequest.current && Utils.dev_callsite(caller.drop(1))
|
37
|
+
if callsite
|
38
|
+
payload = callsite.merge(message: message, level: level)
|
43
39
|
AppRequest.current.events << Event.new('meta_request.log', 0, 0, 0, payload)
|
44
40
|
end
|
45
41
|
rescue Exception => e
|
46
|
-
MetaRequest.logger.fatal(e.message + "\n " + e.backtrace.join("\n "))
|
42
|
+
MetaRequest.config.logger.fatal(e.message + "\n " + e.backtrace.join("\n "))
|
47
43
|
end
|
48
44
|
end
|
49
45
|
end
|
@@ -3,6 +3,5 @@ module MetaRequest
|
|
3
3
|
autoload :Headers, "meta_request/middlewares/headers"
|
4
4
|
autoload :AppRequestHandler, "meta_request/middlewares/app_request_handler"
|
5
5
|
autoload :MetaRequestHandler, "meta_request/middlewares/meta_request_handler"
|
6
|
-
autoload :RequestId, "meta_request/middlewares/request_id"
|
7
6
|
end
|
8
7
|
end
|
data/lib/meta_request/railtie.rb
CHANGED
@@ -4,7 +4,6 @@ module MetaRequest
|
|
4
4
|
class Railtie < ::Rails::Railtie
|
5
5
|
|
6
6
|
initializer 'meta_request.inject_middlewares' do |app|
|
7
|
-
app.middleware.use Middlewares::RequestId unless defined?(ActionDispatch::RequestId)
|
8
7
|
app.middleware.use Middlewares::MetaRequestHandler
|
9
8
|
|
10
9
|
if defined? ActionDispatch::DebugExceptions
|
data/lib/meta_request/storage.rb
CHANGED
@@ -9,7 +9,7 @@ module MetaRequest
|
|
9
9
|
def write(value)
|
10
10
|
FileUtils.mkdir_p dir_path
|
11
11
|
File.open(json_file, 'wb') { |file| file.write(value) }
|
12
|
-
maintain_file_pool(
|
12
|
+
maintain_file_pool(MetaRequest.config.storage_pool_size)
|
13
13
|
end
|
14
14
|
|
15
15
|
def read
|
@@ -27,7 +27,7 @@ module MetaRequest
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def file_ctime(file)
|
30
|
-
File.stat(file).ctime.to_i
|
30
|
+
File.stat(file).ctime.to_i
|
31
31
|
rescue Errno::ENOENT
|
32
32
|
0
|
33
33
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module MetaRequest
|
2
|
+
module Utils
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def dev_callsite(caller)
|
6
|
+
app_line = caller.detect { |c| c.start_with? MetaRequest.rails_root }
|
7
|
+
return nil unless app_line
|
8
|
+
|
9
|
+
_, filename, _, line, _, method = app_line.split(/^(.*?)(:(\d+))(:in `(.*)')?$/)
|
10
|
+
|
11
|
+
{
|
12
|
+
filename: sub_source_path(filename),
|
13
|
+
line: line.to_i,
|
14
|
+
method: method
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def sub_source_path(path)
|
19
|
+
rails_root = MetaRequest.rails_root
|
20
|
+
source_path = MetaRequest.config.source_path
|
21
|
+
return path if rails_root == source_path
|
22
|
+
path.sub(rails_root, source_path)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/meta_request/version.rb
CHANGED
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.
|
4
|
+
version: 0.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dejan Simic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: 3.0.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: '7'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: 3.0.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: '7'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rack-contrib
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,26 +50,6 @@ dependencies:
|
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '3'
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: callsite
|
55
|
-
requirement: !ruby/object:Gem::Requirement
|
56
|
-
requirements:
|
57
|
-
- - "~>"
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version: '0.0'
|
60
|
-
- - ">="
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: 0.0.11
|
63
|
-
type: :runtime
|
64
|
-
prerelease: false
|
65
|
-
version_requirements: !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - "~>"
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: '0.0'
|
70
|
-
- - ">="
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
version: 0.0.11
|
73
53
|
description: Supporting gem for Rails Panel (Google Chrome extension for Rails development)
|
74
54
|
email: desimic@gmail.com
|
75
55
|
executables: []
|
@@ -80,15 +60,16 @@ files:
|
|
80
60
|
- lib/meta_request.rb
|
81
61
|
- lib/meta_request/app_notifications.rb
|
82
62
|
- lib/meta_request/app_request.rb
|
63
|
+
- lib/meta_request/config.rb
|
83
64
|
- lib/meta_request/event.rb
|
84
65
|
- lib/meta_request/log_interceptor.rb
|
85
66
|
- lib/meta_request/middlewares.rb
|
86
67
|
- lib/meta_request/middlewares/app_request_handler.rb
|
87
68
|
- lib/meta_request/middlewares/headers.rb
|
88
69
|
- lib/meta_request/middlewares/meta_request_handler.rb
|
89
|
-
- lib/meta_request/middlewares/request_id.rb
|
90
70
|
- lib/meta_request/railtie.rb
|
91
71
|
- lib/meta_request/storage.rb
|
72
|
+
- lib/meta_request/utils.rb
|
92
73
|
- lib/meta_request/version.rb
|
93
74
|
homepage: https://github.com/dejan/rails_panel/tree/master/meta_request
|
94
75
|
licenses:
|
@@ -109,8 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
90
|
- !ruby/object:Gem::Version
|
110
91
|
version: '0'
|
111
92
|
requirements: []
|
112
|
-
|
113
|
-
rubygems_version: 2.5.1
|
93
|
+
rubygems_version: 3.0.3
|
114
94
|
signing_key:
|
115
95
|
specification_version: 4
|
116
96
|
summary: Request your Rails request
|
@@ -1,42 +0,0 @@
|
|
1
|
-
require 'securerandom'
|
2
|
-
require 'active_support/core_ext/string/access'
|
3
|
-
require 'active_support/core_ext/object/blank'
|
4
|
-
|
5
|
-
# Backported from Rails 3.2 (ActionDispatch::RequestId)
|
6
|
-
module MetaRequest
|
7
|
-
module Middlewares
|
8
|
-
# Makes a unique request id available to the action_dispatch.request_id env variable (which is then accessible through
|
9
|
-
# ActionDispatch::Request#uuid) and sends the same id to the client via the X-Request-Id header.
|
10
|
-
#
|
11
|
-
# The unique request id is either based off the X-Request-Id header in the request, which would typically be generated
|
12
|
-
# by a firewall, load balancer, or the web server, or, if this header is not available, a random uuid. If the
|
13
|
-
# header is accepted from the outside world, we sanitize it to a max of 255 chars and alphanumeric and dashes only.
|
14
|
-
#
|
15
|
-
# The unique request id can be used to trace a request end-to-end and would typically end up being part of log files
|
16
|
-
# from multiple pieces of the stack.
|
17
|
-
class RequestId
|
18
|
-
def initialize(app)
|
19
|
-
@app = app
|
20
|
-
end
|
21
|
-
|
22
|
-
def call(env)
|
23
|
-
env["action_dispatch.request_id"] = external_request_id(env) || internal_request_id
|
24
|
-
status, headers, body = @app.call(env)
|
25
|
-
|
26
|
-
headers["X-Request-Id"] = env["action_dispatch.request_id"]
|
27
|
-
[ status, headers, body ]
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
def external_request_id(env)
|
32
|
-
if request_id = env["HTTP_X_REQUEST_ID"].presence
|
33
|
-
request_id.gsub(/[^\w\-]/, "").first(255)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def internal_request_id
|
38
|
-
SecureRandom.hex(16)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|