tcell_agent 1.1.3 → 1.1.4
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 +10 -2
- data/lib/tcell_agent.rb +3 -3
- data/lib/tcell_agent/agent.rb +42 -52
- data/lib/tcell_agent/agent/event_processor.rb +129 -162
- data/lib/tcell_agent/agent/fork_pipe_manager.rb +57 -62
- data/lib/tcell_agent/agent/policy_manager.rb +83 -104
- data/lib/tcell_agent/agent/policy_types.rb +24 -29
- data/lib/tcell_agent/agent/route_manager.rb +36 -46
- data/lib/tcell_agent/agent/static_agent.rb +19 -21
- data/lib/tcell_agent/api.rb +23 -28
- data/lib/tcell_agent/appsensor/injections_reporter.rb +7 -11
- data/lib/tcell_agent/authlogic.rb +7 -7
- data/lib/tcell_agent/cmdi.rb +22 -23
- data/lib/tcell_agent/config/unknown_options.rb +71 -69
- data/lib/tcell_agent/configuration.rb +187 -191
- data/lib/tcell_agent/devise.rb +13 -15
- data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
- data/lib/tcell_agent/instrumentation.rb +120 -124
- data/lib/tcell_agent/logger.rb +29 -45
- data/lib/tcell_agent/patches.rb +5 -5
- data/lib/tcell_agent/policies/dataloss_policy.rb +263 -288
- data/lib/tcell_agent/policies/http_redirect_policy.rb +25 -37
- data/lib/tcell_agent/policies/http_tx_policy.rb +48 -52
- data/lib/tcell_agent/policies/login_fraud_policy.rb +15 -20
- data/lib/tcell_agent/policies/policy.rb +0 -2
- data/lib/tcell_agent/policies/rust_policies.rb +24 -29
- data/lib/tcell_agent/rails.rb +2 -3
- data/lib/tcell_agent/rails/auth/authlogic.rb +2 -2
- data/lib/tcell_agent/rails/auth/devise.rb +2 -2
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +2 -2
- data/lib/tcell_agent/rails/better_ip.rb +12 -16
- data/lib/tcell_agent/rails/csrf_exception.rb +4 -7
- data/lib/tcell_agent/rails/dlp.rb +208 -107
- data/lib/tcell_agent/rails/dlp/process_request.rb +37 -47
- data/lib/tcell_agent/rails/dlp_handler.rb +9 -11
- data/lib/tcell_agent/rails/js_agent_insert.rb +11 -14
- data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +8 -7
- data/lib/tcell_agent/rails/middleware/context_middleware.rb +4 -5
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +5 -8
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +24 -27
- data/lib/tcell_agent/rails/on_start.rb +5 -5
- data/lib/tcell_agent/rails/responses.rb +7 -9
- data/lib/tcell_agent/rails/routes.rb +62 -81
- data/lib/tcell_agent/rails/routes/grape.rb +25 -30
- data/lib/tcell_agent/rails/routes/route_id.rb +9 -14
- data/lib/tcell_agent/rails/settings_reporter.rb +44 -33
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +15 -18
- data/lib/tcell_agent/routes/table.rb +31 -33
- data/lib/tcell_agent/rust/{libtcellagent-1.3.0.dylib → libtcellagent-1.3.1.dylib} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-1.3.0.so → libtcellagent-1.3.1.so} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-alpine-1.3.0.so → libtcellagent-alpine-1.3.1.so} +0 -0
- data/lib/tcell_agent/rust/models.rb +32 -37
- data/lib/tcell_agent/rust/tcellagent-1.3.1.dll +0 -0
- data/lib/tcell_agent/rust/whisperer.rb +101 -104
- data/lib/tcell_agent/sensor_events/app_config.rb +7 -7
- data/lib/tcell_agent/sensor_events/appsensor_event.rb +26 -27
- data/lib/tcell_agent/sensor_events/appsensor_meta_event.rb +20 -88
- data/lib/tcell_agent/sensor_events/command_injection.rb +52 -80
- data/lib/tcell_agent/sensor_events/discovery.rb +27 -27
- data/lib/tcell_agent/sensor_events/dlp.rb +50 -56
- data/lib/tcell_agent/sensor_events/honeytokens.rb +9 -9
- data/lib/tcell_agent/sensor_events/metrics.rb +20 -21
- data/lib/tcell_agent/sensor_events/patches.rb +10 -12
- data/lib/tcell_agent/sensor_events/sensor.rb +32 -36
- data/lib/tcell_agent/sensor_events/server_agent.rb +130 -127
- data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +60 -80
- data/lib/tcell_agent/sensor_events/util/utils.rb +3 -5
- data/lib/tcell_agent/servers/passenger.rb +5 -9
- data/lib/tcell_agent/servers/puma.rb +18 -27
- data/lib/tcell_agent/servers/rails_server.rb +5 -9
- data/lib/tcell_agent/servers/thin.rb +2 -4
- data/lib/tcell_agent/servers/unicorn.rb +18 -27
- data/lib/tcell_agent/servers/webrick.rb +2 -4
- data/lib/tcell_agent/settings_reporter.rb +126 -0
- data/lib/tcell_agent/sinatra.rb +24 -26
- data/lib/tcell_agent/start_background_thread.rb +21 -142
- data/lib/tcell_agent/system_info.rb +4 -3
- data/lib/tcell_agent/tcell_context.rb +150 -0
- data/lib/tcell_agent/userinfo.rb +3 -3
- data/lib/tcell_agent/utils/io.rb +19 -24
- data/lib/tcell_agent/utils/params.rb +9 -15
- data/lib/tcell_agent/utils/queue_with_timeout.rb +26 -32
- data/lib/tcell_agent/utils/strings.rb +4 -6
- data/lib/tcell_agent/version.rb +1 -1
- data/spec/lib/tcell_agent/agent/policy_manager_spec.rb +5 -5
- data/spec/lib/tcell_agent/agent/static_agent_spec.rb +7 -7
- data/spec/lib/tcell_agent/cmdi_spec.rb +21 -21
- data/spec/lib/tcell_agent/hooks/login_fraud_spec.rb +29 -24
- data/spec/lib/tcell_agent/instrumentation_spec.rb +4 -4
- data/spec/lib/tcell_agent/patches_spec.rb +8 -8
- data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +23 -23
- data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +2 -2
- data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +69 -0
- data/spec/lib/tcell_agent/rails/dlp_spec.rb +1039 -0
- data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +271 -0
- data/spec/lib/tcell_agent/rails/logger_spec.rb +5 -5
- data/spec/lib/tcell_agent/rails/middleware/appsensor_middleware_spec.rb +3 -3
- data/spec/lib/tcell_agent/rails/middleware/dlp_middleware_spec.rb +4 -4
- data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +5 -5
- data/spec/lib/tcell_agent/rails/middleware/redirect_middleware_spec.rb +1 -1
- data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +11 -8
- data/spec/lib/tcell_agent/rails/responses_spec.rb +2 -2
- data/spec/lib/tcell_agent/rails/routes/grape_spec.rb +2 -2
- data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +1 -1
- data/spec/lib/tcell_agent/rails/routes/routes_spec.rb +4 -4
- data/spec/lib/tcell_agent/rust/models_spec.rb +83 -75
- data/spec/lib/tcell_agent/rust/whisperer_spec.rb +14 -14
- data/spec/lib/tcell_agent/sensor_events/appsensor_meta_event_spec.rb +19 -70
- data/spec/lib/tcell_agent/sensor_events/sessions_metric_spec.rb +1 -1
- data/spec/lib/tcell_agent/settings_reporter_spec.rb +162 -0
- data/spec/lib/tcell_agent/tcell_context_spec.rb +154 -0
- data/spec/spec_helper.rb +5 -0
- metadata +18 -10
- data/lib/tcell_agent/appsensor/meta_data.rb +0 -132
- data/lib/tcell_agent/patches/meta_data.rb +0 -59
- data/lib/tcell_agent/rust/tcellagent-1.3.0.dll +0 -0
- data/spec/lib/tcell_agent/appsensor/meta_data_spec.rb +0 -71
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
# See the file "LICENSE" for the full license governing this code.
|
4
2
|
|
5
3
|
require 'logger'
|
@@ -11,103 +9,93 @@ module TCellAgent
|
|
11
9
|
module SensorEvents
|
12
10
|
module Util
|
13
11
|
def self.hmac(data)
|
14
|
-
hmac_key = Util.get_hmac_key
|
12
|
+
hmac_key = Util.get_hmac_key
|
15
13
|
|
16
14
|
h = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), hmac_key.to_s, data)
|
17
15
|
|
18
|
-
|
16
|
+
h[0...h.length / 2]
|
19
17
|
end
|
20
18
|
|
21
19
|
def self.request_sanitized_json(request)
|
22
|
-
sanitized_headers =
|
23
|
-
headers = request.headers.select {|k,
|
24
|
-
|
25
|
-
|
20
|
+
sanitized_headers = {}
|
21
|
+
headers = request.headers.select { |k, _v| k.start_with? 'HTTP_' }
|
22
|
+
.collect { |pair| [pair[0].sub(/^HTTP_/, ''), pair[1]] }
|
23
|
+
.sort
|
26
24
|
headers.each do |header_name, header_value|
|
27
25
|
lower_header_name = header_name.downcase
|
28
|
-
if lower_header_name ==
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
26
|
+
sanitized_headers[header_name] = if lower_header_name == 'cookie'
|
27
|
+
[santize_request_cookie_string(header_value)]
|
28
|
+
elsif %w[content_type content_length user_agent csp].include?(lower_header_name)
|
29
|
+
[header_value]
|
30
|
+
else
|
31
|
+
[]
|
32
|
+
end
|
35
33
|
end
|
36
|
-
new_request = {
|
37
|
-
|
38
|
-
|
34
|
+
new_request = { 'method' => request.request_method,
|
35
|
+
'uri' => sanitize_uri(request.fullpath),
|
36
|
+
'headers' => sanitized_headers }
|
39
37
|
request_body = request.body.read
|
40
38
|
if request_body
|
41
|
-
new_request[
|
39
|
+
new_request['post_data'] = sanitize_query_string(request_body)
|
42
40
|
end
|
43
41
|
new_request
|
44
42
|
end
|
45
43
|
|
46
44
|
def self.response_sanitized_json(response)
|
47
|
-
status, headers,
|
48
|
-
sanitized_headers =
|
49
|
-
content_type =
|
45
|
+
status, headers, _body = *response
|
46
|
+
sanitized_headers = {}
|
47
|
+
content_type = 'unknown'
|
50
48
|
headers.each do |header_name, header_value|
|
51
49
|
lower_header_name = header_name.downcase
|
52
|
-
if lower_header_name ==
|
53
|
-
sanitized_headers[header_name] = [
|
50
|
+
if lower_header_name == 'set-cookie'
|
51
|
+
sanitized_headers[header_name] = [santize_response_cookie_string(header_value)]
|
54
52
|
else
|
55
|
-
if lower_header_name ==
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
sanitized_headers[header_name] = []
|
62
|
-
end
|
53
|
+
content_type = header_value if lower_header_name == 'content-type'
|
54
|
+
sanitized_headers[header_name] = if ['content-type', 'content-length'].include?(lower_header_name)
|
55
|
+
[header_value]
|
56
|
+
else
|
57
|
+
[]
|
58
|
+
end
|
63
59
|
end
|
64
60
|
end
|
65
|
-
|
66
|
-
|
67
|
-
|
61
|
+
|
62
|
+
{ 'status' => status,
|
63
|
+
'headers' => sanitized_headers }
|
68
64
|
end
|
69
65
|
|
70
66
|
def self.santize_request_cookie_string(request_cookie_string)
|
71
|
-
sanitized_cookies =
|
72
|
-
cookies = CGI::Cookie
|
67
|
+
sanitized_cookies = {}
|
68
|
+
cookies = CGI::Cookie.parse(request_cookie_string)
|
73
69
|
cookies.each do |cookie_name, cookie_value|
|
74
|
-
if cookie_value.length != 1
|
75
|
-
next
|
76
|
-
end
|
70
|
+
next if cookie_value.length != 1
|
77
71
|
sanitized_cookies[cookie_name] = Util.hmac(cookie_value[0])
|
78
72
|
end
|
79
|
-
sanitized_cookies.map{|k,v| "#{k}=#{v}"}.join(';')
|
73
|
+
sanitized_cookies.map { |k, v| "#{k}=#{v}" }.join(';')
|
80
74
|
end
|
81
75
|
|
82
76
|
def self.santize_response_cookie_string(response_cookie_string_value)
|
83
77
|
cookie_parts = response_cookie_string_value.split('; ')
|
84
78
|
cookie_string = cookie_parts[0]
|
85
|
-
cookies = CGI::Cookie
|
86
|
-
if cookies.length != 1
|
87
|
-
return "[COOKIEMALFORMED]"
|
88
|
-
end
|
79
|
+
cookies = CGI::Cookie.parse(cookie_string)
|
80
|
+
return '[COOKIEMALFORMED]' if cookies.length != 1
|
89
81
|
cookie_name = cookies.keys.first
|
90
82
|
cookie_values = cookies.values.first
|
91
|
-
if
|
92
|
-
return "[COOKIEHADTOOMANYVALUES]"
|
93
|
-
end
|
83
|
+
return '[COOKIEHADTOOMANYVALUES]' if cookie_values.length != 1
|
94
84
|
h = Util.hmac(cookie_values[0])
|
95
85
|
new_cookie_string = "#{cookie_name}=#{h}"
|
96
86
|
cookie_parts[0] = new_cookie_string
|
97
|
-
cookie_parts.map{|k,v| "#{k}=#{v}"}.join('; ')
|
87
|
+
cookie_parts.map { |k, v| "#{k}=#{v}" }.join('; ')
|
98
88
|
end
|
99
89
|
|
100
90
|
def self.sanitize_query_string(query)
|
101
|
-
params = CGI
|
91
|
+
params = CGI.parse(query)
|
102
92
|
params.each do |param_name, param_values|
|
103
|
-
if param_values
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
param_name.match(/sessionid/i))
|
110
|
-
params[param_name] = ["?"]
|
93
|
+
next if param_values.nil? || param_values.empty?
|
94
|
+
if param_name.match(/password/i) ||
|
95
|
+
param_name.match(/passwd/i) ||
|
96
|
+
param_name.match(/token/i) ||
|
97
|
+
param_name.match(/sessionid/i)
|
98
|
+
params[param_name] = ['?']
|
111
99
|
next
|
112
100
|
end
|
113
101
|
new_param_values = []
|
@@ -117,50 +105,42 @@ module TCellAgent
|
|
117
105
|
end
|
118
106
|
params[param_name] = new_param_values
|
119
107
|
end
|
120
|
-
params.map{|k,v| "#{k}=#{v.join(',')}"}.join('&')
|
108
|
+
params.map { |k, v| "#{k}=#{v.join(',')}" }.join('&')
|
121
109
|
end
|
122
110
|
|
123
111
|
def self.strip_values_query_string(query)
|
124
|
-
params = CGI
|
112
|
+
params = CGI.parse(query)
|
125
113
|
params.each do |param_name, param_values|
|
126
|
-
if param_values
|
127
|
-
|
128
|
-
end
|
129
|
-
params[param_name] = [""]
|
114
|
+
next if param_values.nil? || param_values.empty?
|
115
|
+
params[param_name] = ['']
|
130
116
|
end
|
131
|
-
params.map{|k,v| "#{k}=#{v.join(',')}"}.join('&')
|
117
|
+
params.map { |k, v| "#{k}=#{v.join(',')}" }.join('&')
|
132
118
|
end
|
133
119
|
|
134
120
|
def self.sanitize_uri(uri_string)
|
135
121
|
uri = URI(uri_string)
|
136
122
|
query = uri.query
|
137
|
-
|
138
|
-
|
139
|
-
end
|
140
|
-
return uri.to_s
|
123
|
+
uri.query = sanitize_query_string(query) if query
|
124
|
+
uri.to_s
|
141
125
|
end
|
142
126
|
|
143
127
|
def self.strip_uri_values(uri_string)
|
144
128
|
uri = URI(uri_string)
|
145
129
|
query = uri.query
|
146
|
-
|
147
|
-
|
148
|
-
end
|
149
|
-
return uri.to_s
|
130
|
+
uri.query = strip_values_query_string(query) if query
|
131
|
+
uri.to_s
|
150
132
|
end
|
151
133
|
|
152
134
|
def self.get_hmac_key
|
153
|
-
if
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
end
|
158
|
-
return "tcell_hmac_key"
|
135
|
+
return TCellAgent.configuration.hmac_key if TCellAgent.configuration.hmac_key
|
136
|
+
return TCellAgent.configuration.app_id if TCellAgent.configuration.app_id
|
137
|
+
|
138
|
+
'tcell_hmac_key'
|
159
139
|
end
|
160
140
|
|
161
141
|
def self.clean_header_keys(request_env_or_header_keys)
|
162
142
|
if request_env_or_header_keys.is_a?(Hash)
|
163
|
-
request_env_or_header_keys.select {|k,
|
143
|
+
request_env_or_header_keys.select { |k, _v| k.start_with? 'HTTP_' }.collect { |k, _v| k.sub(/^HTTP_/, '') }
|
164
144
|
else
|
165
145
|
request_env_or_header_keys.map { |k| k.sub(/^HTTP_/, '') }
|
166
146
|
end
|
@@ -14,11 +14,9 @@ module TCellAgent
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def self.
|
18
|
-
route_id = jhash("#{(method ||
|
19
|
-
if
|
20
|
-
route_id = route_id.to_s
|
21
|
-
end
|
17
|
+
def self.calculate_route_id(method, path)
|
18
|
+
route_id = jhash("#{(method || '').downcase}|#{path}")
|
19
|
+
route_id = route_id.to_s if route_id
|
22
20
|
route_id
|
23
21
|
end
|
24
22
|
end
|
@@ -1,17 +1,16 @@
|
|
1
1
|
PhusionPassenger::LoaderSharedHelpers.class_eval do
|
2
|
-
|
3
2
|
alias_method :tcell_after_loading_app_code, :after_loading_app_code
|
4
3
|
def after_loading_app_code(options)
|
5
4
|
tcell_after_loading_app_code(options)
|
6
5
|
|
7
|
-
TCellAgent::Instrumentation.safe_block(
|
6
|
+
TCellAgent::Instrumentation.safe_block('Initial Passenger Instrumentation') do
|
8
7
|
# This runs in Passenger's AppPreloader (a process which is killed at some point)
|
9
8
|
# but it's still a good place to do the initial instrumentation so it's only sent once.
|
10
9
|
# Since this process doesn't receive any requests there is no need to run policy polling
|
11
10
|
# but we still need the event processor to send the startup events
|
12
11
|
original_policy_polling = TCellAgent.configuration.enable_policy_polling
|
13
12
|
TCellAgent.configuration.enable_policy_polling = false
|
14
|
-
TCellAgent.run_instrumentation(
|
13
|
+
TCellAgent.run_instrumentation('Passenger')
|
15
14
|
TCellAgent.configuration.enable_policy_polling = original_policy_polling
|
16
15
|
end
|
17
16
|
end
|
@@ -20,11 +19,10 @@ PhusionPassenger::LoaderSharedHelpers.class_eval do
|
|
20
19
|
def before_handling_requests(forked, options)
|
21
20
|
result_if_needed = tcell_before_handling_requests(forked, options)
|
22
21
|
|
23
|
-
TCellAgent.run_instrumentation(
|
22
|
+
TCellAgent.run_instrumentation('Passenger', false)
|
24
23
|
|
25
24
|
result_if_needed
|
26
25
|
end
|
27
|
-
|
28
26
|
end
|
29
27
|
|
30
28
|
# Passenger's parent process is known as the AppPreloader, the problem is this
|
@@ -32,10 +30,8 @@ end
|
|
32
30
|
# This will give every child process its own event manager to avoid the dependency
|
33
31
|
# on this disappearing process
|
34
32
|
class << TCellAgent::Agent
|
35
|
-
|
36
|
-
|
37
|
-
def is_parent_process?
|
33
|
+
alias_method :tcell_parent_process?, :parent_process?
|
34
|
+
def parent_process?
|
38
35
|
true
|
39
36
|
end
|
40
|
-
|
41
37
|
end
|
@@ -1,40 +1,21 @@
|
|
1
1
|
if defined?(Puma.cli_config)
|
2
|
-
|
3
|
-
|
4
|
-
# Instrumentation will run for each worker but there's
|
5
|
-
# nothing we can do about that (Unicorn's preload_app behaves the same way)
|
6
|
-
Puma::Server.class_eval do
|
7
|
-
|
8
|
-
alias_method :original_run, :run
|
9
|
-
def run(background=true)
|
10
|
-
TCellAgent.run_instrumentation("Puma Cluster Mode (Worker)")
|
11
|
-
|
12
|
-
original_run(background)
|
13
|
-
end
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
else
|
19
|
-
|
20
|
-
if Puma.cli_config.options[:workers] == 0
|
2
|
+
if Puma.cli_config.options[:preload_app]
|
3
|
+
if Puma.cli_config.options[:workers] == 0 # rubocop:disable Style/NumericPredicate
|
21
4
|
# Puma is running in single mode, so run both the initial instrumentation and
|
22
5
|
# start the agent
|
23
6
|
Puma::Runner.class_eval do
|
24
|
-
|
25
7
|
alias_method :original_start_server, :start_server
|
26
8
|
def start_server
|
27
|
-
TCellAgent.run_instrumentation(
|
9
|
+
TCellAgent.run_instrumentation('Puma Single Mode')
|
28
10
|
|
29
11
|
original_start_server
|
30
12
|
end
|
31
|
-
|
32
13
|
end
|
33
14
|
|
34
15
|
else
|
35
16
|
|
36
17
|
# Runs initial instrumentation only once on the master process
|
37
|
-
puma_server_starting = proc { TCellAgent.run_instrumentation(
|
18
|
+
puma_server_starting = proc { TCellAgent.run_instrumentation('Puma Cluster Mode') }
|
38
19
|
|
39
20
|
# before_fork was added in Puma v2.13.0
|
40
21
|
if Puma.cli_config.options[:before_fork]
|
@@ -46,11 +27,10 @@ if defined?(Puma.cli_config)
|
|
46
27
|
# Each puma worker still needs the agent started but no need to run
|
47
28
|
# initial instrumentation again
|
48
29
|
Puma::Server.class_eval do
|
49
|
-
|
50
30
|
alias_method :original_run, :run
|
51
|
-
def run(background=true)
|
31
|
+
def run(background = true)
|
52
32
|
begin
|
53
|
-
TCellAgent.logger.debug(
|
33
|
+
TCellAgent.logger.debug('Instrumenting: Puma Cluster Mode (Worker)')
|
54
34
|
TCellAgent.thread_agent.start
|
55
35
|
rescue StandardError => e
|
56
36
|
TCellAgent.logger.error("Could not start thread agent. #{e.message}")
|
@@ -58,9 +38,20 @@ if defined?(Puma.cli_config)
|
|
58
38
|
|
59
39
|
original_run(background)
|
60
40
|
end
|
61
|
-
|
62
41
|
end
|
63
42
|
end
|
64
43
|
|
44
|
+
else
|
45
|
+
# this ensures instrumentation runs for preload_app = false.
|
46
|
+
# Instrumentation will run for each worker but there's
|
47
|
+
# nothing we can do about that (Unicorn's preload_app behaves the same way)
|
48
|
+
Puma::Server.class_eval do
|
49
|
+
alias_method :original_run, :run
|
50
|
+
def run(background = true)
|
51
|
+
TCellAgent.run_instrumentation('Puma Cluster Mode (Worker)')
|
52
|
+
|
53
|
+
original_run(background)
|
54
|
+
end
|
55
|
+
end
|
65
56
|
end
|
66
57
|
end
|
@@ -3,27 +3,23 @@
|
|
3
3
|
# launched through Rack::Server interface
|
4
4
|
|
5
5
|
Rails::Server.class_eval do
|
6
|
-
|
7
6
|
alias_method :tcell_build_app, :build_app
|
8
7
|
def build_app(app)
|
9
|
-
require(
|
10
|
-
require(
|
11
|
-
require(
|
8
|
+
require('tcell_agent/servers/unicorn') if defined?(Unicorn::HttpServer)
|
9
|
+
require('tcell_agent/servers/webrick') if defined?(Rack::Handler::WEBrick)
|
10
|
+
require('tcell_agent/servers/thin') if defined?(Thin::Server)
|
12
11
|
|
13
12
|
if defined?(Puma::Server)
|
14
13
|
Puma::Server.class_eval do
|
15
|
-
|
16
14
|
alias_method :original_run, :run
|
17
|
-
def run(background=true)
|
18
|
-
TCellAgent.run_instrumentation(
|
15
|
+
def run(background = true)
|
16
|
+
TCellAgent.run_instrumentation('Puma Single Mode')
|
19
17
|
|
20
18
|
original_run(background)
|
21
19
|
end
|
22
|
-
|
23
20
|
end
|
24
21
|
end
|
25
22
|
|
26
23
|
tcell_build_app(app)
|
27
24
|
end
|
28
|
-
|
29
25
|
end
|
@@ -1,11 +1,9 @@
|
|
1
|
-
require(
|
1
|
+
require('tcell_agent/servers/unicorn') if defined?(Unicorn::HttpServer)
|
2
2
|
|
3
3
|
Thin::Server.class_eval do
|
4
|
-
|
5
4
|
alias_method :original_start, :start
|
6
5
|
def start
|
7
|
-
TCellAgent.run_instrumentation(
|
6
|
+
TCellAgent.run_instrumentation('Thin Server')
|
8
7
|
original_start
|
9
8
|
end
|
10
|
-
|
11
9
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
Unicorn::HttpServer.class_eval do
|
2
|
-
|
3
2
|
# - This will be false when preload_app is false (even when unicorn is sent USR2 SIGNAL)
|
4
3
|
# - This check also ensures that a server is running as opposed to a different command such
|
5
4
|
# as `bundle exec rails runner User.count`.
|
6
5
|
unless Unicorn::HttpServer::START_CTX && Unicorn::HttpServer::START_CTX[0]
|
7
|
-
TCellAgent.run_instrumentation(
|
6
|
+
TCellAgent.run_instrumentation('Unicorn')
|
8
7
|
end
|
9
8
|
|
10
9
|
# this only runs when preload_app=true because when preload_app=false
|
@@ -12,7 +11,7 @@ Unicorn::HttpServer.class_eval do
|
|
12
11
|
# the class definitions
|
13
12
|
alias_method :tcell_bind_new_listeners!, :bind_new_listeners!
|
14
13
|
def bind_new_listeners!
|
15
|
-
TCellAgent.run_instrumentation(
|
14
|
+
TCellAgent.run_instrumentation('Unicorn')
|
16
15
|
|
17
16
|
tcell_bind_new_listeners!
|
18
17
|
end
|
@@ -24,15 +23,15 @@ Unicorn::HttpServer.class_eval do
|
|
24
23
|
def load_config!
|
25
24
|
tcell_load_config!
|
26
25
|
|
27
|
-
TCellAgent::Instrumentation.safe_block(
|
26
|
+
TCellAgent::Instrumentation.safe_block('Reloading Tcell Config') do
|
28
27
|
new_config = TCellAgent::Configuration.new
|
29
|
-
TCellAgent.logger.debug(
|
28
|
+
TCellAgent.logger.debug('Reloading config')
|
30
29
|
TCellAgent.logger.debug(
|
31
|
-
"ENABLED:#{new_config.enabled}"
|
32
|
-
"|ENABLE_EVENT_MANAGER:#{new_config.enable_event_manager}"
|
33
|
-
"|ENABLE_EVENT_CONSUMER:#{new_config.enable_event_consumer}"
|
34
|
-
"|ENABLE_POLICY_POLLING:#{new_config.enable_policy_polling}"
|
35
|
-
"|ENABLE_INSTRUMENTATION:#{new_config.enable_instrumentation}"
|
30
|
+
"ENABLED:#{new_config.enabled}" \
|
31
|
+
"|ENABLE_EVENT_MANAGER:#{new_config.enable_event_manager}" \
|
32
|
+
"|ENABLE_EVENT_CONSUMER:#{new_config.enable_event_consumer}" \
|
33
|
+
"|ENABLE_POLICY_POLLING:#{new_config.enable_policy_polling}" \
|
34
|
+
"|ENABLE_INSTRUMENTATION:#{new_config.enable_instrumentation}" \
|
36
35
|
"|ENABLE_INTERCEPT_REQUESTS:#{new_config.enable_intercept_requests}"
|
37
36
|
)
|
38
37
|
old_config = TCellAgent.configuration
|
@@ -41,7 +40,7 @@ Unicorn::HttpServer.class_eval do
|
|
41
40
|
|
42
41
|
if new_config.enabled ^ old_config.enabled
|
43
42
|
if new_config.enabled
|
44
|
-
TCellAgent.run_instrumentation(
|
43
|
+
TCellAgent.run_instrumentation('Unicorn')
|
45
44
|
|
46
45
|
else
|
47
46
|
TCellAgent.thread_agent.stop_event_processor
|
@@ -52,15 +51,13 @@ Unicorn::HttpServer.class_eval do
|
|
52
51
|
|
53
52
|
if new_config.enable_event_manager ^ old_config.enable_event_manager
|
54
53
|
if new_config.enable_event_manager
|
55
|
-
TCellAgent.run_instrumentation(
|
54
|
+
TCellAgent.run_instrumentation('Unicorn Restart')
|
56
55
|
else
|
57
56
|
TCellAgent.thread_agent.stop_event_processor
|
58
57
|
end
|
59
|
-
|
58
|
+
elsif new_config.enable_event_manager
|
60
59
|
# Just in case
|
61
|
-
|
62
|
-
TCellAgent.thread_agent.ensure_event_processor_running
|
63
|
-
end
|
60
|
+
TCellAgent.thread_agent.ensure_event_processor_running
|
64
61
|
end
|
65
62
|
|
66
63
|
if new_config.enable_event_consumer ^ old_config.enable_event_consumer
|
@@ -69,11 +66,9 @@ Unicorn::HttpServer.class_eval do
|
|
69
66
|
else
|
70
67
|
TCellAgent.thread_agent.stop_metrics_event_thread
|
71
68
|
end
|
72
|
-
|
69
|
+
elsif new_config.enable_event_consumer
|
73
70
|
# Just in case
|
74
|
-
|
75
|
-
TCellAgent.thread_agent.ensure_metrics_event_thread_running
|
76
|
-
end
|
71
|
+
TCellAgent.thread_agent.ensure_metrics_event_thread_running
|
77
72
|
end
|
78
73
|
|
79
74
|
if new_config.enable_policy_polling ^ old_config.enable_policy_polling
|
@@ -82,11 +77,9 @@ Unicorn::HttpServer.class_eval do
|
|
82
77
|
else
|
83
78
|
TCellAgent.thread_agent.stop_policy_polling
|
84
79
|
end
|
85
|
-
|
80
|
+
elsif new_config.enable_policy_polling
|
86
81
|
# Just in case
|
87
|
-
|
88
|
-
TCellAgent.thread_agent.ensure_policy_polling_running
|
89
|
-
end
|
82
|
+
TCellAgent.thread_agent.ensure_policy_polling_running
|
90
83
|
end
|
91
84
|
end
|
92
85
|
end
|
@@ -94,7 +87,7 @@ Unicorn::HttpServer.class_eval do
|
|
94
87
|
# this only runs when preload_app=true because when preload_app=false
|
95
88
|
# the gems aren't loaded early enough for tcell to override
|
96
89
|
# the class definitions
|
97
|
-
|
90
|
+
alias_method :tcell_init_worker_process, :init_worker_process
|
98
91
|
def init_worker_process(work)
|
99
92
|
start_process = tcell_init_worker_process(work)
|
100
93
|
|
@@ -103,7 +96,6 @@ Unicorn::HttpServer.class_eval do
|
|
103
96
|
TCellAgent.thread_agent.policy_polling_worker_mutex = Mutex.new
|
104
97
|
TCellAgent.thread_agent.policy_polling_thread = nil
|
105
98
|
TCellAgent.thread_agent.start
|
106
|
-
|
107
99
|
rescue StandardError => e
|
108
100
|
TCellAgent.logger.error("Could not start thread agent. #{e.message}")
|
109
101
|
end
|
@@ -111,5 +103,4 @@ Unicorn::HttpServer.class_eval do
|
|
111
103
|
|
112
104
|
start_process
|
113
105
|
end
|
114
|
-
|
115
106
|
end
|