rails_spotlight 0.1.6 → 0.2.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 +4 -4
- data/.rubocop.yml +1 -0
- data/Guardfile +1 -0
- data/README.md +25 -2
- data/chrome_ext_private_policy.md +39 -0
- data/docker-compose.yml +0 -4
- data/fake_spec_res/rails_spotlight_spec.rb +8 -8
- data/lib/rails_spotlight/app_notifications.rb +88 -0
- data/lib/rails_spotlight/app_request.rb +20 -0
- data/lib/rails_spotlight/channels/live_console_channel.rb +91 -0
- data/lib/rails_spotlight/channels/request_completed_channel.rb +15 -0
- data/lib/rails_spotlight/channels.rb +8 -0
- data/lib/rails_spotlight/configuration.rb +91 -0
- data/lib/rails_spotlight/event.rb +110 -0
- data/lib/rails_spotlight/log_interceptor.rb +47 -0
- data/lib/rails_spotlight/middlewares/concerns/skip_request_paths.rb +35 -0
- data/lib/rails_spotlight/middlewares/handlers/file_action_handler.rb +13 -6
- data/lib/rails_spotlight/middlewares/handlers/meta_action_handler.rb +28 -0
- data/lib/rails_spotlight/middlewares/handlers/sql_action_handler.rb +52 -19
- data/lib/rails_spotlight/middlewares/handlers/verify_action_handler.rb +4 -1
- data/lib/rails_spotlight/middlewares/header_marker.rb +33 -0
- data/lib/rails_spotlight/middlewares/main_request_handler.rb +35 -0
- data/lib/rails_spotlight/middlewares/request_completed.rb +71 -0
- data/lib/rails_spotlight/middlewares/request_handler.rb +2 -0
- data/lib/rails_spotlight/middlewares.rb +10 -0
- data/lib/rails_spotlight/railtie.rb +30 -10
- data/lib/rails_spotlight/storage.rb +47 -0
- data/lib/rails_spotlight/utils.rb +28 -0
- data/lib/rails_spotlight/version.rb +1 -1
- data/lib/rails_spotlight.rb +22 -3
- data/lib/tasks/init.rake +36 -0
- metadata +82 -9
- data/lib/rails_spotlight/support/project.rb +0 -19
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../../support/project'
|
4
|
-
|
5
3
|
module RailsSpotlight
|
6
4
|
module Middlewares
|
7
5
|
module Handlers
|
@@ -9,7 +7,7 @@ module RailsSpotlight
|
|
9
7
|
def execute
|
10
8
|
raise NotFound, 'File not found' unless path_valid?
|
11
9
|
|
12
|
-
File.write(file_path,
|
10
|
+
File.write(file_path, new_content) if write_mode?
|
13
11
|
rescue => e # rubocop:disable Style/RescueStandardError
|
14
12
|
raise UnprocessableEntity, e.message
|
15
13
|
end
|
@@ -20,11 +18,16 @@ module RailsSpotlight
|
|
20
18
|
File.read(file_path)
|
21
19
|
end
|
22
20
|
|
21
|
+
def new_content
|
22
|
+
json_request_body.fetch('content')
|
23
|
+
end
|
24
|
+
|
23
25
|
def json_response_body
|
24
26
|
{
|
25
27
|
source: text_response_body,
|
26
|
-
|
27
|
-
|
28
|
+
changed: write_mode?,
|
29
|
+
project: ::RailsSpotlight.config.project_name
|
30
|
+
}.merge(write_mode? ? { new_content: new_content } : {})
|
28
31
|
end
|
29
32
|
|
30
33
|
def write_mode?
|
@@ -40,7 +43,11 @@ module RailsSpotlight
|
|
40
43
|
end
|
41
44
|
|
42
45
|
def file_path
|
43
|
-
@file_path ||=
|
46
|
+
@file_path ||= if json_request_body.fetch('file').start_with?(::RailsSpotlight.config.rails_root)
|
47
|
+
json_request_body.fetch('file')
|
48
|
+
else
|
49
|
+
File.join(::RailsSpotlight.config.rails_root, json_request_body.fetch('file'))
|
50
|
+
end
|
44
51
|
end
|
45
52
|
end
|
46
53
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsSpotlight
|
4
|
+
module Middlewares
|
5
|
+
module Handlers
|
6
|
+
class MetaActionHandler < BaseActionHandler
|
7
|
+
def execute; end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def json_response_body
|
12
|
+
{
|
13
|
+
events: events,
|
14
|
+
project: ::RailsSpotlight.config.project_name
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def id
|
19
|
+
@id ||= request.params['id']
|
20
|
+
end
|
21
|
+
|
22
|
+
def events
|
23
|
+
@events ||= Storage.new(id).read || []
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,32 +1,35 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../../support/project'
|
4
|
-
|
5
3
|
module RailsSpotlight
|
6
4
|
module Middlewares
|
7
5
|
module Handlers
|
8
6
|
class SqlActionHandler < BaseActionHandler
|
9
7
|
def execute
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
else
|
17
|
-
ActiveSupport::Notifications.subscribed(method(:logger), 'sql.active_record') do
|
18
|
-
transaction
|
19
|
-
end
|
8
|
+
validate_project!
|
9
|
+
return transaction unless ActiveSupport.const_defined?('ExecutionContext')
|
10
|
+
|
11
|
+
ActiveSupport::ExecutionContext.set(rails_spotlight: request_id) do
|
12
|
+
transaction
|
20
13
|
end
|
21
14
|
end
|
22
15
|
|
23
16
|
private
|
24
17
|
|
18
|
+
def validate_project!
|
19
|
+
Rails.logger.warn required_projects
|
20
|
+
return if required_projects.blank?
|
21
|
+
return if required_projects.include?(::RailsSpotlight.config.project_name)
|
22
|
+
|
23
|
+
raise UnprocessableEntity, "Check your connetction settings the current query is not allowed to be executed on the #{::RailsSpotlight.config.project_name} project"
|
24
|
+
end
|
25
|
+
|
25
26
|
def transaction
|
26
27
|
ActiveRecord::Base.transaction do
|
27
|
-
begin
|
28
|
-
|
29
|
-
|
28
|
+
begin # rubocop:disable Style/RedundantBegin
|
29
|
+
ActiveSupport::Notifications.subscribed(method(:logger), 'sql.active_record', monotonic: true) do
|
30
|
+
run
|
31
|
+
end
|
32
|
+
rescue => e # rubocop:disable Style/RescueStandardError
|
30
33
|
self.error = e
|
31
34
|
ensure
|
32
35
|
raise ActiveRecord::Rollback unless force_execution?
|
@@ -34,16 +37,27 @@ module RailsSpotlight
|
|
34
37
|
end
|
35
38
|
end
|
36
39
|
|
37
|
-
|
38
|
-
|
40
|
+
def run
|
41
|
+
return self.result = ActiveRecord::Base.connection.exec_query(query) if connection_options.blank? || !ActiveRecord::Base.respond_to?(:connects_to)
|
42
|
+
|
43
|
+
connections = ActiveRecord::Base.connects_to(**connection_options)
|
44
|
+
|
45
|
+
adapter = connections.find { |c| c.role == use['role'] && c.shard.to_s == use['shard'] }
|
46
|
+
raise UnprocessableEntity, "Connection not found for role: `#{use["role"]}` and shard: `#{use["shard"]}`" if adapter.blank?
|
47
|
+
|
48
|
+
self.result = adapter.connection.exec_query(query)
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_accessor :result, :error
|
39
52
|
|
40
53
|
def json_response_body
|
41
54
|
{
|
55
|
+
query: query,
|
42
56
|
result: result,
|
43
57
|
logs: logs,
|
44
|
-
error: error.inspect,
|
58
|
+
error: error.present? ? error.inspect : nil,
|
45
59
|
query_mode: force_execution? ? 'force' : 'default',
|
46
|
-
project: ::RailsSpotlight
|
60
|
+
project: ::RailsSpotlight.config.project_name
|
47
61
|
}
|
48
62
|
end
|
49
63
|
|
@@ -61,6 +75,25 @@ module RailsSpotlight
|
|
61
75
|
@query ||= json_request_body.fetch('query')
|
62
76
|
end
|
63
77
|
|
78
|
+
def raw_options
|
79
|
+
@raw_options ||= json_request_body.fetch('options', {}) || {}
|
80
|
+
end
|
81
|
+
|
82
|
+
def required_projects
|
83
|
+
@required_projects ||= raw_options.fetch('projects', [])
|
84
|
+
end
|
85
|
+
|
86
|
+
def use
|
87
|
+
@use ||= { 'shard' => 'default', 'role' => 'reading' }.merge(raw_options.fetch('use', {}))
|
88
|
+
end
|
89
|
+
|
90
|
+
def connection_options
|
91
|
+
@connection_options ||= raw_options
|
92
|
+
.symbolize_keys
|
93
|
+
.slice(:database, :shards)
|
94
|
+
.reject { |_, v| v.nil? || (!v.is_a?(TrueClass) && !v.is_a?(FalseClass) && v.empty?) } # TODO: Check for each rails version
|
95
|
+
end
|
96
|
+
|
64
97
|
def force_execution?
|
65
98
|
@force_execution ||= json_request_body['mode'] == 'force'
|
66
99
|
end
|
@@ -18,7 +18,10 @@ module RailsSpotlight
|
|
18
18
|
body: request.body.read,
|
19
19
|
content_type: request.content_type,
|
20
20
|
request_method: request.request_method,
|
21
|
-
version: request.get_header('HTTP_X_RAILS_SPOTLIGHT')
|
21
|
+
version: request.get_header('HTTP_X_RAILS_SPOTLIGHT'),
|
22
|
+
current_gem_version: ::RailsSpotlight::VERSION,
|
23
|
+
project: ::RailsSpotlight.config.project_name,
|
24
|
+
action_cable_path: defined?(ActionCable) ? ActionCable&.server&.config&.mount_path : nil
|
22
25
|
}
|
23
26
|
end
|
24
27
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rack/contrib/response_headers'
|
4
|
+
require_relative 'concerns/skip_request_paths'
|
5
|
+
|
6
|
+
module RailsSpotlight
|
7
|
+
module Middlewares
|
8
|
+
class HeaderMarker
|
9
|
+
include ::RailsSpotlight::Middlewares::SkipRequestPaths
|
10
|
+
|
11
|
+
def initialize(app, app_config)
|
12
|
+
@app = app
|
13
|
+
@app_config = app_config
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
request_path = env['PATH_INFO']
|
18
|
+
middleware = Rack::ResponseHeaders.new(app) do |headers|
|
19
|
+
headers['X-Rails-Spotlight-Version'] = RailsSpotlight::VERSION unless skip?(request_path)
|
20
|
+
end
|
21
|
+
middleware.call(env)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :app, :app_config
|
27
|
+
|
28
|
+
def default_skip_paths
|
29
|
+
%w[/__better_errors]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module RailsSpotlight
|
6
|
+
module Middlewares
|
7
|
+
class MainRequestHandler
|
8
|
+
def initialize(app)
|
9
|
+
@app = app
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :app
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
app_request = AppRequest.new env['action_dispatch.request_id']
|
16
|
+
app_request.current!
|
17
|
+
app.call(env)
|
18
|
+
rescue StandardError => e
|
19
|
+
if defined?(ActionDispatch::ExceptionWrapper)
|
20
|
+
wrapper = if ActionDispatch::ExceptionWrapper.method_defined? :env
|
21
|
+
ActionDispatch::ExceptionWrapper.new(env, e)
|
22
|
+
else
|
23
|
+
ActionDispatch::ExceptionWrapper.new(env['action_dispatch.backtrace_cleaner'], e)
|
24
|
+
end
|
25
|
+
app_request.events.push(*Event.events_for_exception(wrapper))
|
26
|
+
else
|
27
|
+
app_request.events.push(*Event.events_for_exception(e))
|
28
|
+
end
|
29
|
+
raise
|
30
|
+
ensure
|
31
|
+
Storage.new(app_request.id).write(app_request.events.to_json) unless app_request.events.empty?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'concerns/skip_request_paths'
|
4
|
+
|
5
|
+
module RailsSpotlight
|
6
|
+
module Middlewares
|
7
|
+
class RequestCompleted
|
8
|
+
include ::RailsSpotlight::Middlewares::SkipRequestPaths
|
9
|
+
|
10
|
+
def initialize(app, app_config)
|
11
|
+
@app = app
|
12
|
+
@app_config = app_config
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
if skip?(env['PATH_INFO']) || (env['HTTP_CONNECTION'] == 'Upgrade' && env['HTTP_UPGRADE'] == 'websocket')
|
17
|
+
app.call(env)
|
18
|
+
else
|
19
|
+
status, headers, body = app.call(env)
|
20
|
+
publish_event(status, headers, env)
|
21
|
+
[status, headers, body]
|
22
|
+
end
|
23
|
+
rescue => e # rubocop:disable Style/RescueStandardError
|
24
|
+
::RailsSpotlight.config.logger.error "Error in RailsSpotlight::Middlewares::RequestCompletedHandler instrumentation: #{e.message}"
|
25
|
+
app.call(env)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :app, :app_config
|
31
|
+
|
32
|
+
def rails_spotlight_request_id
|
33
|
+
Thread.current[:rails_spotlight_request_id]&.id
|
34
|
+
end
|
35
|
+
|
36
|
+
def publish_event(status, _headers, env)
|
37
|
+
return if status < 100
|
38
|
+
return unless rails_spotlight_request_id
|
39
|
+
|
40
|
+
request = ActionDispatch::Request.new(env)
|
41
|
+
|
42
|
+
host, url = host_and_url(env)
|
43
|
+
ActionCable.server.broadcast(
|
44
|
+
'rails_spotlight_request_completed_channel',
|
45
|
+
{
|
46
|
+
rails_spotlight_version: RailsSpotlight::VERSION,
|
47
|
+
id: rails_spotlight_request_id,
|
48
|
+
http_method: env['REQUEST_METHOD'],
|
49
|
+
host: host,
|
50
|
+
url: url,
|
51
|
+
format: request.format.symbol,
|
52
|
+
controller: request.path_parameters[:controller],
|
53
|
+
action: request.path_parameters[:action]
|
54
|
+
}
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
def host_and_url(env)
|
59
|
+
scheme = env['rack.url_scheme']
|
60
|
+
host = env['HTTP_HOST']
|
61
|
+
path = env['PATH_INFO']
|
62
|
+
query_string = env['QUERY_STRING']
|
63
|
+
|
64
|
+
host_url = "#{scheme}://#{host}"
|
65
|
+
full_url = "#{host_url}#{path}"
|
66
|
+
full_url += "?#{query_string}" unless query_string.empty?
|
67
|
+
[host_url, full_url]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -5,6 +5,7 @@ require_relative 'handlers/file_action_handler'
|
|
5
5
|
require_relative 'handlers/sql_action_handler'
|
6
6
|
require_relative 'handlers/verify_action_handler'
|
7
7
|
require_relative 'handlers/not_found_action_handler'
|
8
|
+
require_relative 'handlers/meta_action_handler'
|
8
9
|
|
9
10
|
module RailsSpotlight
|
10
11
|
module Middlewares
|
@@ -31,6 +32,7 @@ module RailsSpotlight
|
|
31
32
|
when 'file' then Handlers::FileActionHandler.new(*args).call
|
32
33
|
when 'sql' then Handlers::SqlActionHandler.new(*args).call
|
33
34
|
when 'verify' then Handlers::VerifyActionHandler.new(*args).call
|
35
|
+
when 'meta' then Handlers::MetaActionHandler.new(*args).call
|
34
36
|
else
|
35
37
|
Handlers::NotFoundActionHandler.new(*args).call
|
36
38
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsSpotlight
|
4
|
+
module Middlewares
|
5
|
+
autoload :RequestHandler, 'rails_spotlight/middlewares/request_handler'
|
6
|
+
autoload :RequestCompleted, 'rails_spotlight/middlewares/request_completed'
|
7
|
+
autoload :HeaderMarker, 'rails_spotlight/middlewares/header_marker'
|
8
|
+
autoload :MainRequestHandler, 'rails_spotlight/middlewares/main_request_handler'
|
9
|
+
end
|
10
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rails/railtie'
|
4
|
-
require 'meta_request'
|
5
4
|
|
6
5
|
module RailsSpotlight
|
7
6
|
class Railtie < ::Rails::Railtie
|
@@ -9,20 +8,41 @@ module RailsSpotlight
|
|
9
8
|
insert_middleware unless Rails.env.production?
|
10
9
|
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
initializer 'rails_spotlight.log_interceptor' do
|
12
|
+
Rails.logger&.extend(LogInterceptor) unless Rails.env.production?
|
13
|
+
end
|
14
|
+
|
15
|
+
initializer 'rails_spotlight.subscribe_to_notifications' do
|
16
|
+
AppNotifications.subscribe unless Rails.env.production?
|
17
|
+
end
|
18
|
+
|
19
|
+
initializer 'rails_spotlight.action_cable_setup' do
|
20
|
+
unless Rails.env.production?
|
21
|
+
app.config.after_initialize do
|
22
|
+
existing_origins = Array(app.config.action_cable.allowed_request_origins)
|
23
|
+
app.config.action_cable.allowed_request_origins = existing_origins | [%r{\Achrome-extension://.*\z}]
|
24
|
+
|
25
|
+
require 'rails_spotlight/channels/request_completed_channel' if ::RailsSpotlight.config.request_completed_broadcast_enabled?
|
26
|
+
require 'rails_spotlight/channels/live_console_channel' if ::RailsSpotlight.config.live_console_enabled?
|
27
|
+
Rails.application.routes.draw { mount ActionCable.server => '/cable' } if ::RailsSpotlight.config.auto_mount_action_cable?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
19
31
|
|
20
32
|
def insert_middleware
|
33
|
+
app.middleware.use ::RailsSpotlight::Middlewares::RequestHandler
|
34
|
+
|
21
35
|
if defined? ActionDispatch::DebugExceptions
|
22
|
-
app.middleware.insert_before ActionDispatch::DebugExceptions, RailsSpotlight::Middlewares::
|
36
|
+
app.middleware.insert_before ActionDispatch::DebugExceptions, ::RailsSpotlight::Middlewares::HeaderMarker, app.config
|
23
37
|
else
|
24
|
-
app.middleware.use RailsSpotlight::Middlewares::
|
38
|
+
app.middleware.use ::RailsSpotlight::Middlewares::HeaderMarker, app.config
|
25
39
|
end
|
40
|
+
|
41
|
+
app.middleware.use ::RailsSpotlight::Middlewares::MainRequestHandler
|
42
|
+
|
43
|
+
return unless ::RailsSpotlight.config.request_completed_broadcast_enabled?
|
44
|
+
|
45
|
+
app.middleware.insert_after ::RailsSpotlight::Middlewares::HeaderMarker, RailsSpotlight::Middlewares::RequestCompleted, app.config
|
26
46
|
end
|
27
47
|
|
28
48
|
def app
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsSpotlight
|
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
|
+
# Use File.binwrite instead File.open(json_file, 'wb') { |file| file.write(value) }
|
14
|
+
File.binwrite(json_file, value)
|
15
|
+
maintain_file_pool(RailsSpotlight.config.storage_pool_size)
|
16
|
+
end
|
17
|
+
|
18
|
+
def read
|
19
|
+
# avoid FileNotFound error
|
20
|
+
File.exist?(json_file) ? File.read(json_file) : '[]'
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def maintain_file_pool(size)
|
26
|
+
files = Dir["#{dir_path}/*.json"]
|
27
|
+
files = files.sort_by { |f| -file_ctime(f) }
|
28
|
+
(files[size..] || []).each do |file|
|
29
|
+
FileUtils.rm_f(file)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def file_ctime(file)
|
34
|
+
File.stat(file).ctime.to_i
|
35
|
+
rescue Errno::ENOENT
|
36
|
+
0
|
37
|
+
end
|
38
|
+
|
39
|
+
def json_file
|
40
|
+
File.join(dir_path, "#{key}.json")
|
41
|
+
end
|
42
|
+
|
43
|
+
def dir_path
|
44
|
+
@dir_path ||= RailsSpotlight.config.storage_path
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsSpotlight
|
4
|
+
module Utils
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def dev_callsite(caller)
|
8
|
+
app_line = caller.detect { |c| c.start_with? RailsSpotlight.config.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 = RailsSpotlight.config.rails_root
|
22
|
+
source_path = RailsSpotlight.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/rails_spotlight.rb
CHANGED
@@ -1,9 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'rails_spotlight/version'
|
4
|
-
require_relative 'rails_spotlight/middlewares/request_handler'
|
5
|
-
|
6
3
|
module RailsSpotlight
|
4
|
+
autoload :VERSION, 'rails_spotlight/version'
|
5
|
+
autoload :Configuration, 'rails_spotlight/configuration'
|
6
|
+
autoload :Storage, 'rails_spotlight/storage'
|
7
|
+
autoload :Event, 'rails_spotlight/event'
|
8
|
+
autoload :AppRequest, 'rails_spotlight/app_request'
|
9
|
+
autoload :Middlewares, 'rails_spotlight/middlewares'
|
10
|
+
autoload :LogInterceptor, 'rails_spotlight/log_interceptor'
|
11
|
+
autoload :AppNotifications, 'rails_spotlight/app_notifications'
|
12
|
+
autoload :Utils, 'rails_spotlight/utils'
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def config
|
16
|
+
@config ||= Configuration.load_config
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
autoload :Channels, 'rails_spotlight/channels'
|
7
21
|
end
|
8
22
|
|
9
23
|
require_relative 'rails_spotlight/railtie'
|
24
|
+
|
25
|
+
if defined?(Rake)
|
26
|
+
spec = Gem::Specification.find_by_name 'rails_spotlight'
|
27
|
+
load "#{spec.gem_dir}/lib/tasks/init.rake"
|
28
|
+
end
|
data/lib/tasks/init.rake
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
|
5
|
+
namespace :rails_spotlight do
|
6
|
+
desc 'Generate rails_spotlight configuration file'
|
7
|
+
task generate_config: :environment do
|
8
|
+
require 'fileutils'
|
9
|
+
|
10
|
+
config_path = Rails.root.join('config', 'rails_spotlight.yml')
|
11
|
+
|
12
|
+
default_config = <<~YAML
|
13
|
+
# Default configuration for RailsSpotlight
|
14
|
+
PROJECT_NAME: <%=Rails.application.class.respond_to?(:module_parent_name) ? Rails.application.class.module_parent_name : Rails.application.class.parent_name%>
|
15
|
+
SOURCE_PATH: <%=Rails.root%>
|
16
|
+
STORAGE_PATH: <%=Rails.root.join('tmp', 'data', 'rails_spotlight')%>
|
17
|
+
STORAGE_POOL_SIZE: 20
|
18
|
+
LOGGER: <%=Logger.new(Rails.root.join('log', 'rails_spotlight.log'))%>
|
19
|
+
MIDDLEWARE_SKIPPED_PATHS: []
|
20
|
+
NOT_ENCODABLE_EVENT_VALUES:
|
21
|
+
# Rest of the configuration is required for ActionCable. It will be disabled automatically in when ActionCable is not available.
|
22
|
+
LIVE_CONSOLE_ENABLED: true
|
23
|
+
REQUEST_COMPLETED_BROADCAST_ENABLED: false
|
24
|
+
AUTO_MOUNT_ACTION_CABLE: true
|
25
|
+
ACTION_CABLE_MOUNT_PATH: /cable
|
26
|
+
YAML
|
27
|
+
|
28
|
+
if File.exist?(config_path)
|
29
|
+
puts 'Config file already exists: config/rails_spotlight.yml'
|
30
|
+
else
|
31
|
+
FileUtils.mkdir_p(File.dirname(config_path))
|
32
|
+
File.write(config_path, default_config)
|
33
|
+
puts 'Created config file: config/rails_spotlight.yml'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|