tcell_agent 2.1.0 → 2.3.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/bin/tcell_agent +42 -146
- data/lib/tcell_agent.rb +8 -16
- data/lib/tcell_agent/agent.rb +76 -46
- data/lib/tcell_agent/config_initializer.rb +66 -0
- data/lib/tcell_agent/configuration.rb +72 -267
- data/lib/tcell_agent/instrument_servers.rb +14 -18
- data/lib/tcell_agent/instrumentation/cmdi.rb +15 -15
- data/lib/tcell_agent/instrumentation/lfi.rb +16 -5
- data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +39 -100
- data/lib/tcell_agent/logger.rb +1 -2
- data/lib/tcell_agent/rails/auth/authlogic.rb +49 -44
- data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
- data/lib/tcell_agent/rails/auth/devise.rb +103 -102
- data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +54 -58
- data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
- data/lib/tcell_agent/rails/csrf_exception.rb +0 -8
- data/lib/tcell_agent/rails/dlp.rb +0 -4
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +4 -1
- data/lib/tcell_agent/rails/{on_start.rb → railties/tcell_agent_railties.rb} +9 -16
- data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
- data/lib/tcell_agent/rails/routes.rb +3 -6
- data/lib/tcell_agent/rails/routes/grape.rb +4 -12
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +0 -1
- data/lib/tcell_agent/rust/agent_config.rb +43 -32
- data/lib/tcell_agent/rust/{libtcellagent-4.17.1.dylib → libtcellagent-6.2.1.dylib} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-4.17.1.so → libtcellagent-6.2.1.so} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-alpine-4.17.1.so → libtcellagent-alpine-6.2.1.so} +0 -0
- data/lib/tcell_agent/rust/models.rb +9 -0
- data/lib/tcell_agent/rust/native_agent.rb +18 -0
- data/lib/tcell_agent/rust/native_library.rb +2 -1
- data/lib/tcell_agent/rust/{tcellagent-4.17.1.dll → tcellagent-6.2.1.dll} +0 -0
- data/lib/tcell_agent/servers/puma.rb +7 -7
- data/lib/tcell_agent/servers/rack_puma_handler.rb +23 -0
- data/lib/tcell_agent/servers/rails_server.rb +4 -4
- data/lib/tcell_agent/servers/unicorn.rb +1 -1
- data/lib/tcell_agent/servers/webrick.rb +0 -1
- data/lib/tcell_agent/settings_reporter.rb +0 -79
- data/lib/tcell_agent/tcell_context.rb +1 -1
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/lib/tcell_agent/configuration_spec.rb +62 -212
- data/spec/lib/tcell_agent/instrument_servers_spec.rb +95 -0
- data/spec/lib/tcell_agent/instrumentation/cmdi_spec.rb +46 -4
- data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +47 -2
- data/spec/lib/tcell_agent/rust/agent_config_spec.rb +27 -0
- data/spec/lib/tcell_agent/settings_reporter_spec.rb +0 -73
- data/spec/spec_helper.rb +6 -0
- data/spec/support/builders.rb +6 -6
- data/spec/support/server_mocks/passenger_mock.rb +7 -0
- data/spec/support/server_mocks/puma_mock.rb +17 -0
- data/spec/support/server_mocks/rails_mock.rb +7 -0
- data/spec/support/server_mocks/thin_mock.rb +7 -0
- data/spec/support/server_mocks/unicorn_mock.rb +11 -0
- metadata +27 -14
- data/lib/tcell_agent/authlogic.rb +0 -23
- data/lib/tcell_agent/config/unknown_options.rb +0 -119
- data/lib/tcell_agent/devise.rb +0 -33
- data/lib/tcell_agent/rails/start_agent_after_initializers.rb +0 -12
- data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -195
@@ -136,8 +136,7 @@ module TCellAgent
|
|
136
136
|
prepend_around_filter :tcell_around_filter_routes
|
137
137
|
end
|
138
138
|
def tcell_around_filter_routes
|
139
|
-
if TCellAgent.configuration.
|
140
|
-
TCellAgent.configuration.should_intercept_requests?
|
139
|
+
if TCellAgent.configuration.should_intercept_requests?
|
141
140
|
TCellAgent::Instrumentation.safe_block('Determining Rails Route ID') do
|
142
141
|
_match, parameters, route = ::Rails.application.routes.router.recognize(request) { |r, _| r }.first
|
143
142
|
|
@@ -192,8 +191,7 @@ module TCellAgent
|
|
192
191
|
ActionDispatch::Journey::Router.class_eval do
|
193
192
|
alias_method :tcell_serve, :serve
|
194
193
|
def serve(req)
|
195
|
-
if TCellAgent.configuration.
|
196
|
-
TCellAgent.configuration.should_intercept_requests?
|
194
|
+
if TCellAgent.configuration.should_intercept_requests?
|
197
195
|
TCellAgent::Instrumentation.safe_block('Determining Rails Route ID') do
|
198
196
|
_match, parameters, route = find_routes(req).first
|
199
197
|
|
@@ -220,8 +218,7 @@ module TCellAgent
|
|
220
218
|
def call(env)
|
221
219
|
env['PATH_INFO'] = ActionDispatch::Journey::Router::Utils.normalize_path(env['PATH_INFO'])
|
222
220
|
|
223
|
-
if TCellAgent.configuration.
|
224
|
-
TCellAgent.configuration.should_intercept_requests?
|
221
|
+
if TCellAgent.configuration.should_intercept_requests?
|
225
222
|
TCellAgent::Instrumentation.safe_block('Determining Rails Route ID') do
|
226
223
|
_match, parameters, route = find_routes(env).first
|
227
224
|
|
@@ -5,15 +5,9 @@ module TCellAgent
|
|
5
5
|
def self.grape_route?(route)
|
6
6
|
if defined?(Grape::API)
|
7
7
|
begin
|
8
|
-
if ::Rails::VERSION::MAJOR == 4 &&
|
9
|
-
|
10
|
-
|
11
|
-
else
|
12
|
-
# does app inherit from Grape::API?
|
13
|
-
route.app.app < Grape::API
|
14
|
-
end
|
15
|
-
|
16
|
-
return true
|
8
|
+
return route.app < Grape::API if ::Rails::VERSION::MAJOR == 4 &&
|
9
|
+
::Rails::VERSION::MINOR < 2
|
10
|
+
return route.app.app < Grape::API
|
17
11
|
rescue StandardError # rubocop:disable Lint/HandleExceptions
|
18
12
|
# do nothing
|
19
13
|
end
|
@@ -76,9 +70,7 @@ module TCellAgent
|
|
76
70
|
Grape::Endpoint.class_eval do
|
77
71
|
alias_method :tcell_call!, :call!
|
78
72
|
def call!(env)
|
79
|
-
if TCellAgent.configuration.
|
80
|
-
TCellAgent.configuration.should_intercept_requests?
|
81
|
-
|
73
|
+
if TCellAgent.configuration.should_intercept_requests?
|
82
74
|
TCellAgent::Instrumentation.safe_block('Determining Rails Route ID') do
|
83
75
|
tcell_context = env[TCellAgent::Instrumentation::TCELL_ID]
|
84
76
|
if tcell_context && tcell_context.grape_mount_endpoint && respond_to?(:routes)
|
@@ -31,7 +31,6 @@ module TCellAgent
|
|
31
31
|
TCellAgent::Instrumentation.safe_block('Running AppSensor deferred due to streaming') do
|
32
32
|
if @meta_data
|
33
33
|
@meta_data.response_content_bytes_len = @content_length
|
34
|
-
|
35
34
|
appfirewall_policy = TCellAgent.policy(TCellAgent::PolicyTypes::APPSENSOR)
|
36
35
|
appfirewall_policy.check_appfirewall_injections(@meta_data)
|
37
36
|
end
|
@@ -1,48 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'tcell_agent/version'
|
4
|
+
require 'tcell_agent/rust/models'
|
2
5
|
|
3
6
|
module TCellAgent
|
4
7
|
module Rust
|
5
8
|
class AgentConfig < Hash
|
6
9
|
def initialize(configuration)
|
7
|
-
|
8
|
-
|
10
|
+
self['agent_type'] = 'Ruby'
|
11
|
+
self['agent_version'] = TCellAgent::VERSION
|
12
|
+
self['default_cache_dir'] = File.join(Dir.getwd, 'tcell/cache')
|
13
|
+
self['default_config_file_dir'] = File.join(Dir.getwd, 'config')
|
14
|
+
self['default_log_dir'] = File.join(Dir.getwd, 'tcell/logs')
|
15
|
+
self['default_preload_policy_file_dir'] = Dir.getwd
|
9
16
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
if defined?(ConfigInitializer)
|
18
|
+
overrides = Models.clean_nils(AgentConfigOverrides.new(configuration))
|
19
|
+
self['overrides'] = overrides
|
20
|
+
else
|
21
|
+
self['overrides'] = { 'applications' => [{ :enable_json_body_inspection => true }],
|
22
|
+
'config_file_path' => configuration.get_config_file_path }
|
16
23
|
end
|
24
|
+
end
|
25
|
+
end
|
17
26
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
self['application'] = {
|
27
|
+
class AgentConfigOverrides < Hash
|
28
|
+
def initialize(configuration)
|
29
|
+
applications = {
|
30
|
+
:allow_payloads => configuration.allow_payloads,
|
31
|
+
:api_key => configuration.api_key,
|
24
32
|
:app_id => configuration.app_id,
|
25
|
-
:
|
26
|
-
:tcell_api_url => configuration.tcell_api_url,
|
27
|
-
:tcell_input_url => configuration.tcell_input_url,
|
33
|
+
:enable_json_body_inspection => true,
|
28
34
|
:hmac_key => configuration.hmac_key,
|
35
|
+
:max_header_size => configuration.max_csp_header_bytes,
|
29
36
|
:password_hmac_key => configuration.password_hmac_key,
|
30
|
-
:
|
31
|
-
:
|
32
|
-
:js_agent_url => configuration.js_agent_url,
|
33
|
-
:cache_dir => configuration.cache_folder,
|
34
|
-
:log_dir => configuration.agent_log_dir,
|
35
|
-
:logging_options => logging_options,
|
36
|
-
:host_identifier => configuration.host_identifier,
|
37
|
-
:reverse_proxy_ip_address_header => configuration.reverse_proxy_ip_address_header,
|
38
|
-
:fetch_policies_from_tcell => configuration.should_start_policy_poll?,
|
39
|
-
:preload_policy_filename => configuration.preload_policy_filename
|
40
|
-
}
|
41
|
-
self['appfirewall'] = {
|
42
|
-
:enable_body_json_inspection => true,
|
43
|
-
:allow_log_payloads => true
|
37
|
+
:reverse_proxy => configuration.reverse_proxy,
|
38
|
+
:reverse_proxy_ip_address_header => configuration.reverse_proxy_ip_address_header
|
44
39
|
}
|
45
|
-
|
40
|
+
|
41
|
+
self['api_url'] = configuration.tcell_api_url
|
42
|
+
self['applications'] = [Models.clean_nils(applications)]
|
43
|
+
self['config_file_path'] = configuration.get_config_file_path
|
44
|
+
self['disabled_instrumentation'] = configuration.disabled_instrumentation
|
45
|
+
self['enabled'] = configuration.enabled
|
46
|
+
self['host_identifier'] = configuration.host_identifier
|
47
|
+
self['input_url'] = configuration.tcell_input_url
|
48
|
+
self['instrument'] = configuration.instrument
|
49
|
+
self['js_agent_api_url'] = configuration.js_agent_api_base_url
|
50
|
+
self['js_agent_url'] = configuration.js_agent_url
|
51
|
+
self['log_destination'] = configuration.logging_options[:destination]
|
52
|
+
self['log_dir'] = configuration.log_dir
|
53
|
+
self['log_enabled'] = configuration.logging_options[:enabled]
|
54
|
+
self['log_filename'] = configuration.logging_options[:log_filename]
|
55
|
+
self['log_level'] = configuration.logging_options[:level]
|
56
|
+
self['update_policy'] = configuration.fetch_policies_from_tcell
|
46
57
|
end
|
47
58
|
end
|
48
59
|
end
|
Binary file
|
Binary file
|
Binary file
|
@@ -58,6 +58,20 @@ module TCellAgent
|
|
58
58
|
response.errors
|
59
59
|
end
|
60
60
|
|
61
|
+
def self.test_agent(config)
|
62
|
+
agent_config = TCellAgent::Rust::AgentConfig.new(config)
|
63
|
+
|
64
|
+
config_pointer = FFI::MemoryPointer.from_string(
|
65
|
+
JSON.dump(agent_config)
|
66
|
+
)
|
67
|
+
|
68
|
+
buf = FFI::MemoryPointer.new(:uint8, 1024 * 8)
|
69
|
+
# config_pointer.size - 1: strips null terminator
|
70
|
+
TCellAgent::Rust::NativeLibrary.test_agent(
|
71
|
+
config_pointer, config_pointer.size - 1, buf, buf.size
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
61
75
|
def self.free_agent(agent_ptr)
|
62
76
|
if TCellAgent::Rust::NativeLibrary.common_lib_available? &&
|
63
77
|
agent_ptr
|
@@ -88,6 +102,9 @@ module TCellAgent
|
|
88
102
|
return nil
|
89
103
|
end
|
90
104
|
|
105
|
+
return unless response['config'] && response['agent_enabled']
|
106
|
+
|
107
|
+
TCellAgent.configuration.populate_configuration(response['config'])
|
91
108
|
NativeAgent.new(response['agent_ptr'])
|
92
109
|
end
|
93
110
|
|
@@ -209,6 +226,7 @@ module TCellAgent
|
|
209
226
|
:user_id => tcell_context.user_id,
|
210
227
|
:full_uri => tcell_context.uri
|
211
228
|
}
|
229
|
+
|
212
230
|
command_pointer = FFI::MemoryPointer.from_string(
|
213
231
|
JSON.dump(command_info)
|
214
232
|
)
|
@@ -6,7 +6,7 @@ module TCellAgent
|
|
6
6
|
require 'ffi'
|
7
7
|
extend FFI::Library
|
8
8
|
|
9
|
-
VERSION = '
|
9
|
+
VERSION = '6.2.1'.freeze
|
10
10
|
prefix = 'lib'
|
11
11
|
extension = '.so'
|
12
12
|
variant = ''
|
@@ -50,6 +50,7 @@ module TCellAgent
|
|
50
50
|
attach_function :update_policies, %i[pointer pointer size_t pointer size_t], :int
|
51
51
|
attach_function :test_event_sender, %i[pointer size_t pointer size_t], :int
|
52
52
|
attach_function :test_policies, %i[pointer size_t pointer size_t], :int
|
53
|
+
attach_function :test_agent, %i[pointer size_t pointer size_t], :int
|
53
54
|
|
54
55
|
def self.common_lib_available?
|
55
56
|
true
|
Binary file
|
@@ -4,21 +4,21 @@ if defined?(Puma.cli_config)
|
|
4
4
|
# Puma is running in single mode, so run both the initial instrumentation and
|
5
5
|
# start the agent
|
6
6
|
Puma::Runner.class_eval do
|
7
|
-
alias_method :
|
7
|
+
alias_method :tcell_original_start_server, :start_server
|
8
8
|
def start_server
|
9
|
-
TCellAgent.thread_agent.start('Puma
|
9
|
+
TCellAgent.thread_agent.start('Puma')
|
10
10
|
|
11
|
-
|
11
|
+
tcell_original_start_server
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
15
|
else
|
16
16
|
Puma::Server.class_eval do
|
17
|
-
alias_method :
|
17
|
+
alias_method :tcell_original_run, :run
|
18
18
|
def run(background = true)
|
19
19
|
TCellAgent.thread_agent.start('Puma Cluster Mode (Worker)')
|
20
20
|
|
21
|
-
|
21
|
+
tcell_original_run(background)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -28,11 +28,11 @@ if defined?(Puma.cli_config)
|
|
28
28
|
# Instrumentation will run for each worker but there's
|
29
29
|
# nothing we can do about that (Unicorn's preload_app behaves the same way)
|
30
30
|
Puma::Server.class_eval do
|
31
|
-
alias_method :
|
31
|
+
alias_method :tcell_original_run, :run
|
32
32
|
def run(background = true)
|
33
33
|
TCellAgent.thread_agent.start('Puma Cluster Mode (Worker)')
|
34
34
|
|
35
|
-
|
35
|
+
tcell_original_run(background)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Rack::Handler::Puma.class_eval do
|
4
|
+
class << self
|
5
|
+
alias_method :tcell_original_config, :config
|
6
|
+
def config(app, options = {})
|
7
|
+
conf = tcell_original_config(app, options)
|
8
|
+
|
9
|
+
if defined?(Puma::Server) && !Puma::Server.instance_methods.include?(:tcell_original_run)
|
10
|
+
Puma::Server.class_eval do
|
11
|
+
alias_method :tcell_original_run, :run
|
12
|
+
def run(background = true)
|
13
|
+
TCellAgent.thread_agent.start('Puma')
|
14
|
+
|
15
|
+
tcell_original_run(background)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
conf
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -5,17 +5,17 @@
|
|
5
5
|
Rails::Server.class_eval do
|
6
6
|
alias_method :tcell_build_app, :build_app
|
7
7
|
def build_app(app)
|
8
|
+
require('tcell_agent/servers/rack_puma_handler') if defined?(Rack::Handler::Puma)
|
8
9
|
require('tcell_agent/servers/unicorn') if defined?(Unicorn::HttpServer)
|
9
10
|
require('tcell_agent/servers/webrick') if defined?(Rack::Handler::WEBrick)
|
10
11
|
require('tcell_agent/servers/thin') if defined?(Thin::Server)
|
11
12
|
|
12
13
|
if defined?(Puma::Server)
|
13
14
|
Puma::Server.class_eval do
|
14
|
-
alias_method :
|
15
|
+
alias_method :tcell_original_run, :run
|
15
16
|
def run(background = true)
|
16
|
-
TCellAgent.thread_agent.start('Puma
|
17
|
-
|
18
|
-
original_run(background)
|
17
|
+
TCellAgent.thread_agent.start('Puma')
|
18
|
+
tcell_original_run(background)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -3,7 +3,7 @@ Unicorn::HttpServer.class_eval do
|
|
3
3
|
# - This check also ensures that a server is running as opposed to a different command such
|
4
4
|
# as `bundle exec rails runner User.count`.
|
5
5
|
unless Unicorn::HttpServer::START_CTX && Unicorn::HttpServer::START_CTX[0]
|
6
|
-
require 'tcell_agent/rails/
|
6
|
+
require 'tcell_agent/rails/railties/tcell_agent_unicorn_railties'
|
7
7
|
end
|
8
8
|
|
9
9
|
# This only gets instrumented when preload_app is true
|
@@ -37,85 +37,6 @@ module TCellAgent
|
|
37
37
|
)
|
38
38
|
end
|
39
39
|
|
40
|
-
TCellAgent::Instrumentation.safe_block('Instrumenting Initial Config') do
|
41
|
-
TCellAgent.send_event(
|
42
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
43
|
-
'allow_payloads',
|
44
|
-
(!!TCellAgent.configuration.allow_payloads).to_s # rubocop:disable Style/DoubleNegation
|
45
|
-
)
|
46
|
-
)
|
47
|
-
|
48
|
-
TCellAgent.send_event(
|
49
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
50
|
-
'reverse_proxy',
|
51
|
-
(!!TCellAgent.configuration.reverse_proxy).to_s # rubocop:disable Style/DoubleNegation
|
52
|
-
)
|
53
|
-
)
|
54
|
-
|
55
|
-
# Because of all the diff ways to initialize the agent
|
56
|
-
# some some of the following vars might not be set until
|
57
|
-
# we call this method, so call this method to set all
|
58
|
-
# the variables
|
59
|
-
TCellAgent.configuration.log_filename
|
60
|
-
|
61
|
-
TCellAgent.send_event(
|
62
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
63
|
-
'config_filename',
|
64
|
-
TCellAgent.configuration.config_filename
|
65
|
-
)
|
66
|
-
)
|
67
|
-
TCellAgent.send_event(
|
68
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
69
|
-
'logging_directory',
|
70
|
-
TCellAgent.configuration.agent_log_dir
|
71
|
-
)
|
72
|
-
)
|
73
|
-
|
74
|
-
TCellAgent.send_event(
|
75
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
76
|
-
'agent_home_directory',
|
77
|
-
TCellAgent.configuration.agent_home_dir
|
78
|
-
)
|
79
|
-
)
|
80
|
-
|
81
|
-
logging_options = TCellAgent.configuration.logging_options || {}
|
82
|
-
use_default_setting = !logging_options.key?(:enabled) && !logging_options.key?('enabled')
|
83
|
-
if use_default_setting || logging_options[:enabled] || logging_options['enabled']
|
84
|
-
TCellAgent.send_event(
|
85
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new('logging_enabled', 'true')
|
86
|
-
)
|
87
|
-
|
88
|
-
TCellAgent.send_event(
|
89
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
90
|
-
'logging_level',
|
91
|
-
logging_options[:level] || logging_options['level'] || 'INFO'
|
92
|
-
)
|
93
|
-
)
|
94
|
-
else
|
95
|
-
TCellAgent.send_event(
|
96
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new('logging_enabled', 'false')
|
97
|
-
)
|
98
|
-
end
|
99
|
-
|
100
|
-
if TCellAgent.configuration.hmac_key
|
101
|
-
TCellAgent.send_event(
|
102
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
103
|
-
'hmac_key_present',
|
104
|
-
(!!TCellAgent.configuration.hmac_key).to_s # rubocop:disable Style/DoubleNegation
|
105
|
-
)
|
106
|
-
)
|
107
|
-
end
|
108
|
-
|
109
|
-
if TCellAgent.configuration.reverse_proxy
|
110
|
-
TCellAgent.send_event(
|
111
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
112
|
-
'reverse_proxy_ip_address_header',
|
113
|
-
TCellAgent.configuration.reverse_proxy_ip_address_header
|
114
|
-
)
|
115
|
-
)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
40
|
if defined?(::Rails)
|
120
41
|
TCellAgent::Instrumentation.safe_block('Instrumenting routes') do
|
121
42
|
TCellAgent::Instrumentation::Rails.instrument_routes
|