rails_spotlight 0.1.6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|