stackify-ruby-apm 1.10.2 → 1.13.2
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/lib/stackify_apm/agent.rb +0 -2
- data/lib/stackify_apm/config.rb +36 -5
- data/lib/stackify_apm/context.rb +4 -1
- data/lib/stackify_apm/context/prefix.rb +30 -0
- data/lib/stackify_apm/context/request/headers.rb +30 -0
- data/lib/stackify_apm/context_builder.rb +1 -0
- data/lib/stackify_apm/helper/database_helper.rb +40 -1
- data/lib/stackify_apm/instrumenter_helper.rb +90 -4
- data/lib/stackify_apm/logger/logger_high_version.rb +5 -1
- data/lib/stackify_apm/logger/logger_lower_version.rb +5 -1
- data/lib/stackify_apm/middleware.rb +21 -3
- data/lib/stackify_apm/normalizers/active_record.rb +16 -8
- data/lib/stackify_apm/root_info.rb +7 -1
- data/lib/stackify_apm/serializers/transactions.rb +5 -0
- data/lib/stackify_apm/span/context.rb +42 -1
- data/lib/stackify_apm/spies.rb +4 -2
- data/lib/stackify_apm/spies/action_dispatch.rb +6 -1
- data/lib/stackify_apm/spies/curb.rb +41 -20
- data/lib/stackify_apm/spies/curb/easy.rb +220 -92
- data/lib/stackify_apm/spies/curb/multi.rb +26 -12
- data/lib/stackify_apm/spies/custom_instrumenter.rb +25 -4
- data/lib/stackify_apm/spies/delayed_job.rb +49 -0
- data/lib/stackify_apm/spies/dynamo_db.rb +50 -0
- data/lib/stackify_apm/spies/faraday.rb +87 -0
- data/lib/stackify_apm/spies/httparty.rb +45 -24
- data/lib/stackify_apm/spies/httpclient.rb +41 -20
- data/lib/stackify_apm/spies/httprb.rb +39 -18
- data/lib/stackify_apm/spies/log4r.rb +60 -0
- data/lib/stackify_apm/spies/logger.rb +117 -0
- data/lib/stackify_apm/spies/logging.rb +66 -0
- data/lib/stackify_apm/spies/net_http.rb +38 -20
- data/lib/stackify_apm/spies/redis.rb +36 -30
- data/lib/stackify_apm/spies/sequel.rb +28 -11
- data/lib/stackify_apm/spies/sinatra_activerecord/mysql_adapter.rb +27 -25
- data/lib/stackify_apm/spies/sinatra_activerecord/postgresql_adapter.rb +27 -24
- data/lib/stackify_apm/spies/sinatra_activerecord/sqlite_adapter.rb +18 -8
- data/lib/stackify_apm/spies/stackify_logger.rb +28 -16
- data/lib/stackify_apm/spies/sucker_punch.rb +39 -0
- data/lib/stackify_apm/spies/yell.rb +65 -0
- data/lib/stackify_apm/util.rb +10 -9
- data/lib/stackify_apm/version.rb +1 -1
- data/stackify-ruby-apm.gemspec +1 -0
- metadata +26 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1ee1b9b91d78729820e74b7fbc014310af4037390de6c0982cb0169cba50a8a
|
4
|
+
data.tar.gz: 3a7dfe377099f033779e85d591e8ec973039ee4a4b59f20175e57afdd967819a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 143b1fba17994c286ad71dc020d731247079b28a75fda11ee742ed8d49c023557a731e16c0ae8715153d6f5c98dbbb7dbbdaa10a225d4ad8f5f0750aedb7a739
|
7
|
+
data.tar.gz: 28be6a1c40fa6dab5fc5a35f2c56e99984c579d4e5f84e5481ffa6e5c9b9fa9c615a0425c1af81d5a3d1d7d4088df1b4f777250fde816b48a2049f320a1df1c4
|
data/lib/stackify_apm/agent.rb
CHANGED
@@ -101,8 +101,6 @@ module StackifyRubyAPM
|
|
101
101
|
info '[Agent] start()'
|
102
102
|
info '[Agent] transport type: ' + @config.transport
|
103
103
|
spies_name = ''
|
104
|
-
# If the rake task is detected as being ran then we don't load the spies
|
105
|
-
StackifyRubyAPM::Util.apm_disabled_in_rake
|
106
104
|
return false unless @config.instrument
|
107
105
|
config.enabled_spies.each do |lib|
|
108
106
|
spies_name = spies_name + ', ' + lib.inspect.to_s
|
data/lib/stackify_apm/config.rb
CHANGED
@@ -26,7 +26,7 @@ module StackifyRubyAPM
|
|
26
26
|
environment_name: ENV['RAILS_ENV'] || ENV['RACK_ENV'],
|
27
27
|
already_instrumented_flag: false,
|
28
28
|
rum_auto_injection: false,
|
29
|
-
rum_enabled:
|
29
|
+
rum_enabled: true,
|
30
30
|
rum_cookie_path: '/',
|
31
31
|
rum_cookie_name: '.Stackify.Rum',
|
32
32
|
transport: StackifyRubyAPM::TRACE_LOG,
|
@@ -70,7 +70,8 @@ module StackifyRubyAPM
|
|
70
70
|
transport_http_endpoint: 'https://localhost:10601',
|
71
71
|
|
72
72
|
queue: true,
|
73
|
-
lambda_handler: ''
|
73
|
+
lambda_handler: '',
|
74
|
+
prefix_enabled: false
|
74
75
|
}.freeze
|
75
76
|
|
76
77
|
ENV_TO_KEY = {
|
@@ -97,7 +98,8 @@ module StackifyRubyAPM
|
|
97
98
|
'STACKIFY_FLUSH_INTERVAL' => 'flush_interval_seconds',
|
98
99
|
'STACKIFY_DISABLED_SPIES' => [:list, 'disabled_spies'],
|
99
100
|
'STACKIFY_QUEUE' => [:bool, 'queue'],
|
100
|
-
'STACKIFY_LAMBDA_HANDLER' => 'lambda_handler'
|
101
|
+
'STACKIFY_LAMBDA_HANDLER' => 'lambda_handler',
|
102
|
+
'STACKIFY_PREFIX_ENABLED' => [:bool, 'prefix_enabled']
|
101
103
|
}.freeze
|
102
104
|
|
103
105
|
def initialize(options = {})
|
@@ -105,6 +107,7 @@ module StackifyRubyAPM
|
|
105
107
|
set_from_args(options)
|
106
108
|
set_from_config_file
|
107
109
|
set_from_env
|
110
|
+
set_prefix_paths if @prefix_enabled
|
108
111
|
yield self if block_given?
|
109
112
|
debug_logger
|
110
113
|
StackifyRubyAPM::Util.host_os == 'WINDOWS' ? load_stackify_props_windows : load_stackify_props_linux
|
@@ -170,6 +173,7 @@ module StackifyRubyAPM
|
|
170
173
|
|
171
174
|
attr_accessor :queue
|
172
175
|
attr_accessor :lambda_handler
|
176
|
+
attr_accessor :prefix_enabled
|
173
177
|
|
174
178
|
attr_reader :client_id
|
175
179
|
attr_reader :device_id
|
@@ -210,6 +214,20 @@ module StackifyRubyAPM
|
|
210
214
|
httparty
|
211
215
|
stackify_logger
|
212
216
|
sidekiq
|
217
|
+
delayed_job
|
218
|
+
faraday
|
219
|
+
sucker_punch
|
220
|
+
dynamo_db
|
221
|
+
]
|
222
|
+
end
|
223
|
+
|
224
|
+
def prefix_spies
|
225
|
+
return [] unless @prefix_enabled
|
226
|
+
%w[
|
227
|
+
logger
|
228
|
+
logging
|
229
|
+
log4r
|
230
|
+
yell
|
213
231
|
]
|
214
232
|
end
|
215
233
|
|
@@ -232,7 +250,7 @@ module StackifyRubyAPM
|
|
232
250
|
available_spies
|
233
251
|
end
|
234
252
|
|
235
|
-
new_available_spies - disabled_spies
|
253
|
+
new_available_spies + prefix_spies - disabled_spies
|
236
254
|
end
|
237
255
|
|
238
256
|
# Default Transport
|
@@ -253,7 +271,11 @@ module StackifyRubyAPM
|
|
253
271
|
|
254
272
|
def assign(options)
|
255
273
|
options.each do |key, value|
|
256
|
-
|
274
|
+
begin
|
275
|
+
send("#{key}=", value)
|
276
|
+
rescue Exception => e
|
277
|
+
info "[Config] Key: '#{key}' doesn't exist."
|
278
|
+
end
|
257
279
|
end
|
258
280
|
end
|
259
281
|
|
@@ -294,6 +316,14 @@ module StackifyRubyAPM
|
|
294
316
|
assign(YAML.load_file(config_file) || {})
|
295
317
|
end
|
296
318
|
|
319
|
+
# set log paths to prefix path if prefix_enabled is true
|
320
|
+
def set_prefix_paths
|
321
|
+
all_user_profile = ENV['ALLUSERSPROFILE'] || "C:\\ProgramData"
|
322
|
+
|
323
|
+
@log_path = StackifyRubyAPM::Util.host_os == 'WINDOWS' ? "#{all_user_profile}\\Stackify\\Agent\\debug\\stackify-ruby-apm-1.log" : "/usr/local/prefix/debug/stackify-ruby-apm-1.log"
|
324
|
+
@log_trace_path = StackifyRubyAPM::Util.host_os == 'WINDOWS' ? "#{all_user_profile}\\Stackify\\Agent\\log\\" : '/usr/local/prefix/log/'
|
325
|
+
end
|
326
|
+
|
297
327
|
# rubocop:disable Naming/AccessorMethodName
|
298
328
|
def set_rails(app)
|
299
329
|
self.application_name ||= format_name(application_name || app.class.parent_name).strip
|
@@ -381,6 +411,7 @@ module StackifyRubyAPM
|
|
381
411
|
info '[Config] environment_name must be String type.' unless @environment_name.is_a?(String) && defined?(@environment_name)
|
382
412
|
info '[Config] transport must be String type.' unless @transport.is_a?(String) && defined?(@transport)
|
383
413
|
info '[Config] Transport should be one of these values: [agent_socket, default, agent_http]. Should be a String.' if defined?(@transport) && !%w[agent_socket default agent_http].include?(@transport.downcase)
|
414
|
+
info '[Config] prefix_enabled must be Boolean type: true/false.' unless [TrueClass, FalseClass].include?(@prefix_enabled.class) && defined?(@prefix_enabled)
|
384
415
|
end
|
385
416
|
# rubocop:enable Metrics/CyclomaticComplexity
|
386
417
|
# rubocop:enable Metrics/PerceivedComplexity
|
data/lib/stackify_apm/context.rb
CHANGED
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
# This class initializes the parameters and variables for the context of Transaction/Span
|
4
4
|
|
5
|
+
require 'stackify_apm/context/prefix'
|
5
6
|
require 'stackify_apm/context/request'
|
7
|
+
require 'stackify_apm/context/request/headers'
|
6
8
|
require 'stackify_apm/context/request/socket'
|
7
9
|
require 'stackify_apm/context/request/url'
|
8
10
|
require 'stackify_apm/context/response'
|
@@ -12,12 +14,13 @@ module StackifyRubyAPM
|
|
12
14
|
class Context
|
13
15
|
include NaivelyHashable
|
14
16
|
|
15
|
-
attr_accessor :request, :response, :aws
|
17
|
+
attr_accessor :request, :response, :aws, :category, :prefix
|
16
18
|
attr_reader :custom, :tags
|
17
19
|
|
18
20
|
def initialize
|
19
21
|
@custom = {}
|
20
22
|
@tags = {}
|
23
|
+
@prefix = Context::Prefix.new
|
21
24
|
end
|
22
25
|
|
23
26
|
# add aws context to context instance
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StackifyRubyAPM
|
4
|
+
class Context
|
5
|
+
# @api private
|
6
|
+
class Prefix
|
7
|
+
include NaivelyHashable
|
8
|
+
|
9
|
+
attr_accessor :response_body, :request_body
|
10
|
+
attr_reader :response_headers, :request_headers
|
11
|
+
|
12
|
+
def request_headers=(headers)
|
13
|
+
@request_headers = to_json_list(headers)
|
14
|
+
end
|
15
|
+
|
16
|
+
def response_headers=(headers)
|
17
|
+
@response_headers = to_json_list(headers)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def to_json_list(header)
|
22
|
+
list_header = []
|
23
|
+
header.each do |key, value|
|
24
|
+
list_header << {key => value}
|
25
|
+
end
|
26
|
+
list_header.to_json
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StackifyRubyAPM
|
4
|
+
# @api private
|
5
|
+
class Context
|
6
|
+
# @api private
|
7
|
+
class Request
|
8
|
+
# @api private
|
9
|
+
class Headers
|
10
|
+
include NaivelyHashable
|
11
|
+
|
12
|
+
def initialize(req)
|
13
|
+
@values = build_headers req
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :values
|
17
|
+
|
18
|
+
def build_headers req
|
19
|
+
env = req.env
|
20
|
+
headers = Hash[*env.select {|k,v| k.start_with? 'HTTP_'}
|
21
|
+
.collect {|k,v| [k.sub(/^HTTP_/, ''), v]}
|
22
|
+
.collect {|k,v| [k.split('_').collect(&:capitalize).join('-'), v]}
|
23
|
+
.sort
|
24
|
+
.flatten]
|
25
|
+
return headers
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -18,10 +18,49 @@ module DatabaseHelper
|
|
18
18
|
elsif driver.include? 'db2'
|
19
19
|
'db2'
|
20
20
|
elsif driver.include? 'sqlite'
|
21
|
-
'
|
21
|
+
'sqlite'
|
22
22
|
end
|
23
23
|
end
|
24
24
|
# rubocop:enable Metrics/CyclomaticComplexity
|
25
25
|
# rubocop:enable Metrics/PerceivedComplexity
|
26
|
+
|
27
|
+
# Check the prepared statement by placeholder if its valid
|
28
|
+
# placeholder - contains the prepared statement pattern.
|
29
|
+
# Placeholder for mysql, sqlite, jdbc oracle, db2 is ?, example "SELECT * FROM posts WHERE author = ? and id = ?"
|
30
|
+
# Placeholder for postgres is $1, $2,...$n, example "SELECT * FROM posts WHERE author = $1 and id = $2"
|
31
|
+
# statement - contains the db properties such as SQL, PROVIDER, etc.
|
32
|
+
# So if there's payload value we append PREFIX_SQL_PARAMETERS to the existing object properties.
|
33
|
+
# payload - contains the payload[:binds] which is the payload value/data of the placeholder.
|
34
|
+
# Example payload: {:sql=>"SELECT * FROM posts WHERE author = ? and id = ?", :db_adapter=>"mysql2::client", :binds=>["J.K. Rowling", 1]}
|
35
|
+
def check_prepared_stmt_by_placeholder(placeholder, statement, payload)
|
36
|
+
sqlParam = []
|
37
|
+
unless payload[:binds].nil?
|
38
|
+
payload[:binds].each_with_index do |record, idx|
|
39
|
+
if record && defined?(record.value)
|
40
|
+
StackifyRubyAPM::Util.pushToAryIndex(sqlParam, idx, record.value[0..999])
|
41
|
+
elsif ((record && record.instance_of?(Array)) && defined?(record[1]))
|
42
|
+
StackifyRubyAPM::Util.pushToAryIndex(sqlParam, idx, record[1][0..999])
|
43
|
+
else
|
44
|
+
StackifyRubyAPM::Util.pushToAryIndex(sqlParam, idx, record[0..999])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
statement[:PREFIX_SQL_PARAMETERS] = sqlParam[0..99].to_json if sqlParam.count > 0
|
48
|
+
statement[:PREFIX_SQL_PARAMETER_COUNT] = sqlParam.length.to_s if sqlParam.count > 0
|
49
|
+
true
|
50
|
+
else
|
51
|
+
false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Common DB span properties shared to sequel, activerecord, etc.
|
56
|
+
def get_common_db_properties
|
57
|
+
{
|
58
|
+
CATEGORY: 'Database',
|
59
|
+
SUBCATEGORY: 'Execute',
|
60
|
+
COMPONENT_CATEGORY: 'DB Query',
|
61
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
62
|
+
PROVIDER: 'generic'
|
63
|
+
}
|
64
|
+
end
|
26
65
|
end
|
27
66
|
include DatabaseHelper
|
@@ -90,9 +90,8 @@ module StackifyRubyAPM
|
|
90
90
|
)
|
91
91
|
end
|
92
92
|
|
93
|
-
req = #{current_method_without}(*args, &block)
|
94
93
|
StackifyRubyAPM.span name, type, context: ctx do
|
95
|
-
|
94
|
+
#{current_method_without}(*args, &block)
|
96
95
|
end
|
97
96
|
else
|
98
97
|
return #{current_method_without}(*args, &block)
|
@@ -169,9 +168,9 @@ module StackifyRubyAPM
|
|
169
168
|
CATEGORY: 'Ruby'
|
170
169
|
)
|
171
170
|
end
|
172
|
-
|
171
|
+
|
173
172
|
StackifyRubyAPM.span name, type, context: ctx do
|
174
|
-
|
173
|
+
_self_without_apm_#{current_method}(*args, &block)
|
175
174
|
end
|
176
175
|
else
|
177
176
|
return _self_without_apm_#{current_method}(*args, &block)
|
@@ -190,6 +189,93 @@ module StackifyRubyAPM
|
|
190
189
|
@custom_class_info[current_class.to_s]['controller'] = true if class_path && class_path.include?('controllers')
|
191
190
|
@custom_class_info[current_class.to_s]['model'] = true if class_path && class_path.include?('models')
|
192
191
|
end
|
192
|
+
|
193
|
+
# Monkey patch the single ruby module file.
|
194
|
+
#
|
195
|
+
# tracked_func - trackedFunction variable in stackify.json
|
196
|
+
# current_module - module variable in stackify.json
|
197
|
+
# class_path - file_path variable in stackify.json
|
198
|
+
# options - other options such as trackedFunctionName
|
199
|
+
def self.patched_module(tracked_func, current_module, class_path, **options)
|
200
|
+
current_method = options[:current_method] || nil
|
201
|
+
tracked_function_name = options[:tracked_function_name] || nil
|
202
|
+
transaction = options[:is_transaction] || nil
|
203
|
+
mod_spy = "#{current_module}Spy"
|
204
|
+
|
205
|
+
unless @custom_instrumented[current_module.to_s]
|
206
|
+
@custom_instrumented[current_module.to_s] = {}
|
207
|
+
end
|
208
|
+
|
209
|
+
unless @custom_instrumented[current_module.to_s][current_method.to_s]
|
210
|
+
@custom_instrumented[current_module.to_s][current_method.to_s] = false
|
211
|
+
end
|
212
|
+
|
213
|
+
unless @custom_class_info[current_module.to_s]
|
214
|
+
@custom_class_info[current_module.to_s] = {}
|
215
|
+
end
|
216
|
+
|
217
|
+
unless @custom_class_info[current_module.to_s]['controller']
|
218
|
+
@custom_class_info[current_module.to_s]['controller'] = false
|
219
|
+
end
|
220
|
+
|
221
|
+
unless @custom_class_info[current_module.to_s]['model']
|
222
|
+
@custom_class_info[current_module.to_s]['model'] = false
|
223
|
+
end
|
224
|
+
|
225
|
+
return unless @custom_instrumented[current_module.to_s][current_method.to_s] == false
|
226
|
+
|
227
|
+
eval <<-RUBY
|
228
|
+
module #{mod_spy}
|
229
|
+
def self.install
|
230
|
+
#{current_module}.class_eval do
|
231
|
+
class<< self
|
232
|
+
alias_method "#{current_method}_without_apm", "#{current_method}"
|
233
|
+
|
234
|
+
def #{current_method}(*args, &block)
|
235
|
+
if StackifyRubyAPM.current_transaction.nil? && #{!transaction.nil?}
|
236
|
+
t = StackifyRubyAPM.transaction("custom.#{current_module}.#{current_method}", TRACETYPE)
|
237
|
+
begin
|
238
|
+
req = #{current_method}_without_apm(*args, &block)
|
239
|
+
rescue Exception => e
|
240
|
+
StackifyRubyAPM.report(e)
|
241
|
+
raise e
|
242
|
+
ensure
|
243
|
+
t.submit
|
244
|
+
end
|
245
|
+
return req
|
246
|
+
elsif StackifyRubyAPM.current_transaction
|
247
|
+
name = "Custom Instrument"
|
248
|
+
type = "#{current_module}##{current_method}"
|
249
|
+
ctx = if "#{tracked_func}" == 'true'
|
250
|
+
Span::Context.new(
|
251
|
+
CATEGORY: 'Ruby',
|
252
|
+
TRACKED_FUNC: "#{tracked_function_name}"
|
253
|
+
)
|
254
|
+
else
|
255
|
+
Span::Context.new(
|
256
|
+
CATEGORY: 'Ruby'
|
257
|
+
)
|
258
|
+
end
|
259
|
+
|
260
|
+
StackifyRubyAPM.span name, type, context: ctx do
|
261
|
+
#{current_method}_without_apm(*args, &block)
|
262
|
+
end
|
263
|
+
else
|
264
|
+
return #{current_method}_without_apm(*args, &block)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
StackifyRubyAPM::Spies.register current_module.to_s, class_path.to_s, #{mod_spy}, true, "#{current_method}", "#{tracked_func}", "#{tracked_function_name}"
|
273
|
+
RUBY
|
274
|
+
@custom_instrumented[current_module.to_s][current_method.to_s] = true
|
275
|
+
@custom_class_info[current_module.to_s]['controller'] = true if class_path && class_path.include?('controllers')
|
276
|
+
@custom_class_info[current_module.to_s]['model'] = true if class_path && class_path.include?('models')
|
277
|
+
end
|
278
|
+
|
193
279
|
# rubocop:enable Metrics/CyclomaticComplexity
|
194
280
|
# rubocop:enable Metrics/PerceivedComplexity
|
195
281
|
# rubocop:enable Lint/UselessAssignment
|
@@ -29,7 +29,11 @@ module StackifyRubyAPM
|
|
29
29
|
temp_filename = logdev.gsub('-1.log', '')
|
30
30
|
new_logdev = temp_filename + '-1.log'
|
31
31
|
end
|
32
|
-
|
32
|
+
begin
|
33
|
+
@logdev = LogDevice.new(new_logdev, shift_size: shift_size)
|
34
|
+
rescue StandardError => e
|
35
|
+
puts "Stackify Profiler unable to access [" + logdev + "]"
|
36
|
+
end
|
33
37
|
end
|
34
38
|
end
|
35
39
|
require 'stackify_apm/logger/log_device'
|
@@ -20,7 +20,11 @@ module StackifyRubyAPM
|
|
20
20
|
temp_filename = logdev.gsub('-1.log', '')
|
21
21
|
new_logdev = temp_filename + '-1.log'
|
22
22
|
end
|
23
|
-
|
23
|
+
begin
|
24
|
+
@logdev = LogDevice.new(new_logdev, shift_size: shift_size)
|
25
|
+
rescue StandardError => e
|
26
|
+
puts "Stackify Profiler unable to access [" + logdev + "]"
|
27
|
+
end
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
@@ -39,7 +39,8 @@ module StackifyRubyAPM
|
|
39
39
|
# rubocop:disable Metrics/PerceivedComplexity
|
40
40
|
def call(env)
|
41
41
|
begin
|
42
|
-
|
42
|
+
context = StackifyRubyAPM.build_context(env)
|
43
|
+
transaction = build_transaction(env, context) if running?
|
43
44
|
resp = @app.call env
|
44
45
|
|
45
46
|
@rack_status = resp[0].to_i
|
@@ -47,6 +48,8 @@ module StackifyRubyAPM
|
|
47
48
|
@rack_body = resp[2]
|
48
49
|
@configuration = config
|
49
50
|
|
51
|
+
build_prefix_context(transaction, context)
|
52
|
+
|
50
53
|
if okay_to_modify?
|
51
54
|
@configuration.already_instrumented_flag = true
|
52
55
|
if @configuration.rum_enabled.is_a?(TrueClass)
|
@@ -92,8 +95,9 @@ module StackifyRubyAPM
|
|
92
95
|
|
93
96
|
# Start of transaction building with params: name, type, context
|
94
97
|
#
|
95
|
-
def build_transaction(env)
|
96
|
-
|
98
|
+
def build_transaction(env, context=nil)
|
99
|
+
context = context || StackifyRubyAPM.build_context(env)
|
100
|
+
StackifyRubyAPM.transaction 'Rack', 'WEBAPP', context: context
|
97
101
|
end
|
98
102
|
|
99
103
|
def running?
|
@@ -129,5 +133,19 @@ module StackifyRubyAPM
|
|
129
133
|
def xhr?
|
130
134
|
@rack_headers['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'
|
131
135
|
end
|
136
|
+
|
137
|
+
# Add prefix instrument data to transaction context if enabled
|
138
|
+
def build_prefix_context(transaction, context)
|
139
|
+
return nil unless @configuration.prefix_enabled.is_a?(TrueClass)
|
140
|
+
|
141
|
+
source = nil
|
142
|
+
body = @rack_body
|
143
|
+
body.each { |fragment| source ? (source << fragment.to_s) : (source = fragment.to_s) }
|
144
|
+
|
145
|
+
transaction.context.prefix.request_body = context && context.request && context.request.body || ""
|
146
|
+
transaction.context.prefix.request_headers = context && context.request && context.request.headers || Hash.new
|
147
|
+
transaction.context.prefix.response_body = source || ""
|
148
|
+
transaction.context.prefix.response_headers = @rack_headers || Hash.new
|
149
|
+
end
|
132
150
|
end
|
133
151
|
end
|