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