stackify-ruby-apm 1.14.8 → 1.16.0.beta1
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 +5 -4
- data/lib/stackify_apm/config.rb +40 -5
- data/lib/stackify_apm/context.rb +2 -1
- data/lib/stackify_apm/instrumenter.rb +4 -4
- data/lib/stackify_apm/instrumenter_helper.rb +12 -12
- data/lib/stackify_apm/logger/log_device.rb +2 -1
- data/lib/stackify_apm/middleware.rb +9 -10
- data/lib/stackify_apm/normalizers/active_record.rb +17 -3
- data/lib/stackify_apm/response_manipulator.rb +19 -14
- data/lib/stackify_apm/root_info.rb +2 -2
- data/lib/stackify_apm/span/context.rb +1 -1
- data/lib/stackify_apm/spies/action_dispatch.rb +26 -0
- data/lib/stackify_apm/spies/curb/easy.rb +16 -16
- data/lib/stackify_apm/spies/delayed_job.rb +2 -2
- data/lib/stackify_apm/spies/httpclient.rb +4 -4
- data/lib/stackify_apm/spies/sequel.rb +2 -2
- data/lib/stackify_apm/spies/sidekiq.rb +2 -2
- data/lib/stackify_apm/spies/sinatra.rb +14 -4
- data/lib/stackify_apm/spies/sucker_punch.rb +2 -2
- data/lib/stackify_apm/spies/tilt.rb +2 -2
- data/lib/stackify_apm/util.rb +86 -0
- data/lib/stackify_apm/version.rb +2 -2
- data/lib/stackify_ruby_apm.rb +56 -11
- data/stackify-ruby-apm.gemspec +51 -14
- metadata +68 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ebb6c26f4eef249448035790df567d74b2c81915d42dcba72a4d8dfa83649f0
|
4
|
+
data.tar.gz: d4a30f83de5976fbacab28c544b27c5d8afb26b13db4af484570e666f4424717
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af4ef9861dfdeb3eaa8e721ed92f55d752c8687f53aa818596b7688e0a909e1971e35b0aab90c7a37569eb2930c3e07a17697795b932ffee3e4cecc95e92ba67
|
7
|
+
data.tar.gz: 8df99628de54aadbe98674602da416dfde21d637f879ea70d540ad4ce830dc740f449da68f390a595893f4ac3665f1b0f8d03edc5d6512e9049cabf5af483585
|
data/lib/stackify_apm/agent.rb
CHANGED
@@ -40,6 +40,7 @@ module StackifyRubyAPM
|
|
40
40
|
date_now = Time.now
|
41
41
|
current_trace_file = config.log_trace_path + squish(host_name) + '#' + squish(pid.to_s)
|
42
42
|
if ENV['STACKIFY_RUBY_ENV'] != 'rspec'
|
43
|
+
Util.checkOrCreateFolder(config.log_trace_path)
|
43
44
|
config.tracer_logger = StackifyLogger.new(current_trace_file, config.filenum_rotate, config.logger_byte_size)
|
44
45
|
config.debug_logger
|
45
46
|
config.logtime_created = date_now.strftime('%H:%M')
|
@@ -148,12 +149,12 @@ module StackifyRubyAPM
|
|
148
149
|
|
149
150
|
# Loads transaction
|
150
151
|
#
|
151
|
-
def transaction(*args, &block)
|
152
|
-
instrumenter.transaction(*args, &block)
|
152
|
+
def transaction(*args, **kwargs, &block)
|
153
|
+
instrumenter.transaction(*args, **kwargs, &block)
|
153
154
|
end
|
154
155
|
|
155
|
-
def span(*args, &block)
|
156
|
-
instrumenter.span(*args, &block)
|
156
|
+
def span(*args, **kwargs, &block)
|
157
|
+
instrumenter.span(*args, **kwargs, &block)
|
157
158
|
end
|
158
159
|
|
159
160
|
# Responsible for building the transaction's context
|
data/lib/stackify_apm/config.rb
CHANGED
@@ -26,13 +26,13 @@ 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: false,
|
30
30
|
rum_cookie_path: '/',
|
31
31
|
rum_cookie_name: '.Stackify.Rum',
|
32
32
|
transport: StackifyRubyAPM::TRACE_LOG,
|
33
33
|
instrument: true,
|
34
34
|
debug_logging: false,
|
35
|
-
log_path: StackifyRubyAPM::Util.host_os == 'WINDOWS' ? 'C:\ProgramData\Stackify\Ruby\
|
35
|
+
log_path: StackifyRubyAPM::Util.host_os == 'WINDOWS' ? 'C:\ProgramData\Stackify\Ruby\debug\stackify-ruby-apm-1.log' : '/usr/local/stackify/stackify-ruby-apm/debug/stackify-ruby-apm-1.log',
|
36
36
|
log_level: Logger::INFO,
|
37
37
|
log_trace_path: StackifyRubyAPM::Util.host_os == 'WINDOWS' ? 'C:\ProgramData\Stackify\Ruby\log\\' : '/usr/local/stackify/stackify-ruby-apm/log/',
|
38
38
|
|
@@ -71,14 +71,17 @@ module StackifyRubyAPM
|
|
71
71
|
|
72
72
|
queue: true,
|
73
73
|
lambda_handler: '',
|
74
|
-
prefix_enabled: false
|
74
|
+
prefix_enabled: false,
|
75
|
+
|
76
|
+
rum_script_url: 'https://stckjs.stackify.com/stckjs.js',
|
77
|
+
rum_key: ''
|
75
78
|
}.freeze
|
76
79
|
|
77
80
|
ENV_TO_KEY = {
|
78
81
|
'STACKIFY_DEBUG' => [:bool, 'debug_logging'],
|
79
82
|
'STACKIFY_APPLICATION_NAME' => 'application_name',
|
80
83
|
'STACKIFY_ENVIRONMENT_NAME' => 'environment_name',
|
81
|
-
'
|
84
|
+
'RETRACE_RUMV2_ENABLED' => [:bool, 'rum_enabled'],
|
82
85
|
'STACKIFY_RUM_AUTO_INJECT' => [:bool, 'rum_auto_injection'],
|
83
86
|
'STACKIFY_RUM_SCRIPT_SRC' => 'rum_script_src',
|
84
87
|
'STACKIFY_TRANSPORT' => 'transport',
|
@@ -99,7 +102,9 @@ module StackifyRubyAPM
|
|
99
102
|
'STACKIFY_DISABLED_SPIES' => [:list, 'disabled_spies'],
|
100
103
|
'STACKIFY_QUEUE' => [:bool, 'queue'],
|
101
104
|
'STACKIFY_LAMBDA_HANDLER' => 'lambda_handler',
|
102
|
-
'STACKIFY_PREFIX_ENABLED' => [:bool, 'prefix_enabled']
|
105
|
+
'STACKIFY_PREFIX_ENABLED' => [:bool, 'prefix_enabled'],
|
106
|
+
'RETRACE_RUM_SCRIPT_URL' => 'rum_script_url',
|
107
|
+
'RETRACE_RUM_KEY' => 'rum_key'
|
103
108
|
}.freeze
|
104
109
|
|
105
110
|
def initialize(options = {})
|
@@ -180,6 +185,9 @@ module StackifyRubyAPM
|
|
180
185
|
attr_reader :apm_disabled_in_rake
|
181
186
|
attr_reader :client_run_domain
|
182
187
|
|
188
|
+
attr_accessor :rum_script_url
|
189
|
+
attr_accessor :rum_key
|
190
|
+
|
183
191
|
def app=(app)
|
184
192
|
case app_type?(app)
|
185
193
|
when :rails
|
@@ -261,6 +269,10 @@ module StackifyRubyAPM
|
|
261
269
|
# For unix socket we don't create a trace log file
|
262
270
|
when StackifyRubyAPM::TRACE_LOG
|
263
271
|
debugger_logpath = log_path == '-' ? $stdout : log_path
|
272
|
+
if (debugger_logpath == log_path)
|
273
|
+
dir_name = File.dirname(debugger_logpath)
|
274
|
+
Util.checkOrCreateFolder(dir_name)
|
275
|
+
end
|
264
276
|
logger = StackifyLogger.new(debugger_logpath, debugger_filenum_rotate, debugger_byte_size)
|
265
277
|
logger.level = log_level
|
266
278
|
self.logger = logger
|
@@ -336,6 +348,10 @@ module StackifyRubyAPM
|
|
336
348
|
|
337
349
|
def build_logger
|
338
350
|
debugger_logpath = log_path == '-' ? $stdout : log_path
|
351
|
+
if (debugger_logpath == log_path)
|
352
|
+
dir_name = File.dirname(debugger_logpath)
|
353
|
+
Util.checkOrCreateFolder(dir_name)
|
354
|
+
end
|
339
355
|
logger = StackifyLogger.new(debugger_logpath, debugger_filenum_rotate, debugger_byte_size)
|
340
356
|
logger.level = log_level
|
341
357
|
self.logger = logger
|
@@ -412,6 +428,25 @@ module StackifyRubyAPM
|
|
412
428
|
info '[Config] transport must be String type.' unless @transport.is_a?(String) && defined?(@transport)
|
413
429
|
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
430
|
info '[Config] prefix_enabled must be Boolean type: true/false.' unless [TrueClass, FalseClass].include?(@prefix_enabled.class) && defined?(@prefix_enabled)
|
431
|
+
|
432
|
+
valid_rum_script_url = false
|
433
|
+
if defined?(@rum_script_url) && @rum_script_url.is_a?(String)
|
434
|
+
valid_rum_script_url = @rum_script_url =~ /^((((https?|ftps?|gopher|telnet|nntp):\/\/)|(mailto:|news:))(%[0-9A-Fa-f]{2}|[\-\(\)_\.!~*';\/?:@&=+$,A-Za-z0-9])+)([\)\.!';\/?:,][\[:blank:|:blank:\]])?$/
|
435
|
+
end
|
436
|
+
|
437
|
+
if !valid_rum_script_url
|
438
|
+
@rum_script_url = 'https://stckjs.stackify.com/stckjs.js'
|
439
|
+
end
|
440
|
+
|
441
|
+
valid_rum_key = false
|
442
|
+
if defined?(@rum_key) && @rum_key.is_a?(String)
|
443
|
+
valid_rum_key = @rum_key =~ %r{^[A-Za-z0-9_-]+$}
|
444
|
+
end
|
445
|
+
|
446
|
+
if !valid_rum_key
|
447
|
+
@rum_key = ''
|
448
|
+
end
|
449
|
+
|
415
450
|
end
|
416
451
|
# rubocop:enable Metrics/CyclomaticComplexity
|
417
452
|
# rubocop:enable Metrics/PerceivedComplexity
|
data/lib/stackify_apm/context.rb
CHANGED
@@ -14,13 +14,14 @@ module StackifyRubyAPM
|
|
14
14
|
class Context
|
15
15
|
include NaivelyHashable
|
16
16
|
|
17
|
-
attr_accessor :request, :response, :aws, :category, :prefix
|
17
|
+
attr_accessor :request, :response, :aws, :category, :prefix, :rum
|
18
18
|
attr_reader :custom, :tags
|
19
19
|
|
20
20
|
def initialize
|
21
21
|
@custom = {}
|
22
22
|
@tags = {}
|
23
23
|
@prefix = Context::Prefix.new
|
24
|
+
@rum = false
|
24
25
|
end
|
25
26
|
|
26
27
|
# add aws context to context instance
|
@@ -56,7 +56,7 @@ module StackifyRubyAPM
|
|
56
56
|
|
57
57
|
# Creates a new transaction or return the currently running
|
58
58
|
#
|
59
|
-
def transaction(*args)
|
59
|
+
def transaction(*args, **kwargs)
|
60
60
|
unless config.instrument
|
61
61
|
yield if block_given?
|
62
62
|
return
|
@@ -67,7 +67,7 @@ module StackifyRubyAPM
|
|
67
67
|
return transaction
|
68
68
|
end
|
69
69
|
|
70
|
-
transaction = Transaction.new self, *args
|
70
|
+
transaction = Transaction.new self, *args, **kwargs
|
71
71
|
|
72
72
|
self.current_transaction = transaction
|
73
73
|
return transaction unless block_given?
|
@@ -82,14 +82,14 @@ module StackifyRubyAPM
|
|
82
82
|
transaction
|
83
83
|
end
|
84
84
|
|
85
|
-
def span(*args, &block)
|
85
|
+
def span(*args, **kwargs, &block)
|
86
86
|
unless current_transaction
|
87
87
|
return yield if block_given?
|
88
88
|
|
89
89
|
return
|
90
90
|
end
|
91
91
|
|
92
|
-
current_transaction.span(*args, &block)
|
92
|
+
current_transaction.span(*args, **kwargs, &block)
|
93
93
|
end
|
94
94
|
|
95
95
|
# Once the transaction is submitted it will be stored temporarily in queue
|
@@ -73,11 +73,11 @@ module StackifyRubyAPM
|
|
73
73
|
then "protected"
|
74
74
|
end
|
75
75
|
}
|
76
|
-
def #{current_method}(*args, &block)
|
76
|
+
def #{current_method}(*args, **kwargs, &block)
|
77
77
|
if StackifyRubyAPM.current_transaction.nil? && #{!transaction.nil?}
|
78
78
|
t = StackifyRubyAPM.transaction("custom.#{current_class}.#{current_method}", TRACETYPE)
|
79
79
|
begin
|
80
|
-
req = #{current_method_without}(*args, &block)
|
80
|
+
req = #{current_method_without}(*args, **kwargs, &block)
|
81
81
|
rescue Exception => e
|
82
82
|
StackifyRubyAPM.report(e)
|
83
83
|
raise e
|
@@ -100,10 +100,10 @@ module StackifyRubyAPM
|
|
100
100
|
end
|
101
101
|
|
102
102
|
StackifyRubyAPM.span name, type, context: ctx do
|
103
|
-
#{current_method_without}(*args, &block)
|
103
|
+
#{current_method_without}(*args, **kwargs, &block)
|
104
104
|
end
|
105
105
|
else
|
106
|
-
return #{current_method_without}(*args, &block)
|
106
|
+
return #{current_method_without}(*args, **kwargs, &block)
|
107
107
|
end
|
108
108
|
end
|
109
109
|
end
|
@@ -152,11 +152,11 @@ module StackifyRubyAPM
|
|
152
152
|
#{current_class}.class_eval do
|
153
153
|
singleton_class.send(:alias_method, :"_self_without_apm_#{current_method}", :"#{current_method}")
|
154
154
|
|
155
|
-
def self.#{current_method}(*args, &block)
|
155
|
+
def self.#{current_method}(*args, **kwargs, &block)
|
156
156
|
if StackifyRubyAPM.current_transaction.nil? && #{!transaction.nil?}
|
157
157
|
t = StackifyRubyAPM.transaction("custom.#{current_class}.#{current_method}", TRACETYPE)
|
158
158
|
begin
|
159
|
-
req = _self_without_apm_#{current_method}(*args, &block)
|
159
|
+
req = _self_without_apm_#{current_method}(*args, **kwargs, &block)
|
160
160
|
rescue Exception => e
|
161
161
|
StackifyRubyAPM.report(e)
|
162
162
|
raise e
|
@@ -179,10 +179,10 @@ module StackifyRubyAPM
|
|
179
179
|
end
|
180
180
|
|
181
181
|
StackifyRubyAPM.span name, type, context: ctx do
|
182
|
-
_self_without_apm_#{current_method}(*args, &block)
|
182
|
+
_self_without_apm_#{current_method}(*args, **kwargs, &block)
|
183
183
|
end
|
184
184
|
else
|
185
|
-
return _self_without_apm_#{current_method}(*args, &block)
|
185
|
+
return _self_without_apm_#{current_method}(*args, **kwargs, &block)
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|
@@ -240,11 +240,11 @@ module StackifyRubyAPM
|
|
240
240
|
class<< self
|
241
241
|
alias_method "#{current_method}_without_apm", "#{current_method}"
|
242
242
|
|
243
|
-
def #{current_method}(*args, &block)
|
243
|
+
def #{current_method}(*args, **kwargs, &block)
|
244
244
|
if StackifyRubyAPM.current_transaction.nil? && #{!transaction.nil?}
|
245
245
|
t = StackifyRubyAPM.transaction("custom.#{current_module}.#{current_method}", TRACETYPE)
|
246
246
|
begin
|
247
|
-
req = #{current_method}_without_apm(*args, &block)
|
247
|
+
req = #{current_method}_without_apm(*args, **kwargs, &block)
|
248
248
|
rescue Exception => e
|
249
249
|
StackifyRubyAPM.report(e)
|
250
250
|
raise e
|
@@ -267,10 +267,10 @@ module StackifyRubyAPM
|
|
267
267
|
end
|
268
268
|
|
269
269
|
StackifyRubyAPM.span name, type, context: ctx do
|
270
|
-
#{current_method}_without_apm(*args, &block)
|
270
|
+
#{current_method}_without_apm(*args, **kwargs, &block)
|
271
271
|
end
|
272
272
|
else
|
273
|
-
return #{current_method}_without_apm(*args, &block)
|
273
|
+
return #{current_method}_without_apm(*args, **kwargs, &block)
|
274
274
|
end
|
275
275
|
end
|
276
276
|
end
|
@@ -84,10 +84,11 @@ module StackifyRubyAPM
|
|
84
84
|
# Override create_logfile of core LogDevice class where we set File.chmod to 0o777
|
85
85
|
def create_logfile(filename)
|
86
86
|
logdev = super
|
87
|
-
File.chmod(0o777, filename)
|
88
87
|
|
89
88
|
begin
|
90
89
|
dir_name = File.dirname(filename)
|
90
|
+
StackifyRubyAPM::Util.checkOrCreateFolder(dir_name)
|
91
|
+
File.chmod(0o777, filename)
|
91
92
|
# repath current file due to windows separator \\ doesn't work with Dir.glob
|
92
93
|
dir_name = dir_name.split(File::ALT_SEPARATOR).join(File::SEPARATOR)
|
93
94
|
search_files = File.join("#{dir_name}", "{[!stackify-ruby-apm]*}.log")
|
@@ -28,6 +28,7 @@ module StackifyRubyAPM
|
|
28
28
|
CONTENT_TYPE_REGEX = %r{text\/html|application\/xhtml\+xml/}
|
29
29
|
CONTENT_DISPOSITION = 'Content-Disposition'.freeze
|
30
30
|
ATTACHMENT = 'attachment'.freeze
|
31
|
+
CONTENT_LENGTH = 'Content-Length'.freeze
|
31
32
|
|
32
33
|
def initialize(app)
|
33
34
|
@app = app
|
@@ -53,17 +54,15 @@ module StackifyRubyAPM
|
|
53
54
|
if okay_to_modify?
|
54
55
|
@configuration.already_instrumented_flag = true
|
55
56
|
if @configuration.rum_enabled.is_a?(TrueClass)
|
56
|
-
|
57
|
-
|
58
|
-
response = Rack::Response.new @rack_body, @rack_status, @rack_headers
|
59
|
-
response.set_cookie(@configuration.rum_cookie_name, value: transaction.id, path: @configuration.rum_cookie_path)
|
60
|
-
resp = response.finish
|
61
|
-
end
|
62
|
-
if @configuration.rum_auto_injection.is_a?(TrueClass)
|
63
|
-
response_manupulate = StackifyRubyAPM::ResponseManipulator.new(env, resp, @configuration)
|
64
|
-
response_string = response_manupulate.adjust_pagehtml_response
|
57
|
+
response_manipulated = StackifyRubyAPM::ResponseManipulator.new(env, resp, @configuration)
|
58
|
+
response_string = response_manipulated.adjust_pagehtml_response
|
65
59
|
if response_string
|
66
|
-
|
60
|
+
if @rack_headers.key?(CONTENT_LENGTH)
|
61
|
+
content_length = response_string ? response_string.bytesize : 0
|
62
|
+
@rack_headers[CONTENT_LENGTH] = content_length.to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
response = Rack::Response.new(response_string, @rack_status, @rack_headers)
|
67
66
|
resp = response.finish
|
68
67
|
else
|
69
68
|
resp
|
@@ -3,6 +3,7 @@
|
|
3
3
|
# Possible use of ActiveSupport.on_load(:active_record)
|
4
4
|
|
5
5
|
require 'stackify_apm/helper/database_helper'
|
6
|
+
require 'rails'
|
6
7
|
|
7
8
|
module StackifyRubyAPM
|
8
9
|
module Normalizers
|
@@ -79,17 +80,30 @@ module StackifyRubyAPM
|
|
79
80
|
end
|
80
81
|
|
81
82
|
if (connection.nil?)
|
82
|
-
|
83
|
+
if ::ActiveRecord::Base.respond_to?(:connection)
|
84
|
+
return ::ActiveRecord::Base.connection.adapter_name.downcase
|
85
|
+
else
|
86
|
+
return 'generic'
|
87
|
+
end
|
83
88
|
end
|
84
89
|
|
85
90
|
if (connection.respond_to?(:adapter_name) && connection.adapter_name.nil?)
|
86
|
-
|
91
|
+
if ::ActiveRecord::Base.respond_to?(:connection)
|
92
|
+
return ::ActiveRecord::Base.connection.adapter_name.downcase
|
93
|
+
else
|
94
|
+
return 'generic'
|
95
|
+
end
|
87
96
|
end
|
88
97
|
|
89
98
|
connection.adapter_name.downcase
|
90
99
|
rescue StandardError => error
|
91
100
|
debug '[SqlNormalizer] lookup_adapter err: ' + error.inspect.to_s
|
92
|
-
nil
|
101
|
+
# do a last fail safe check before returning nil
|
102
|
+
if ::ActiveRecord::Base.respond_to?(:connection)
|
103
|
+
::ActiveRecord::Base.connection.adapter_name.downcase
|
104
|
+
else
|
105
|
+
nil
|
106
|
+
end
|
93
107
|
end
|
94
108
|
|
95
109
|
def lookup_adapter_config
|
@@ -22,6 +22,7 @@ module StackifyRubyAPM
|
|
22
22
|
GT = '>'.freeze
|
23
23
|
CHARSET_RE = /<\s*meta[^>]+charset\s*=[^>]*>/
|
24
24
|
X_UA_COMPATIBLE_RE = /<\s*meta[^>]+http-equiv\s*=\s*['"]x-ua-compatible['"][^>]*>/
|
25
|
+
STACKIFY_SETTING_TAG = '<script type="text/javascript">(window.StackifySettings ||'
|
25
26
|
|
26
27
|
def initialize(env, rack_response, config)
|
27
28
|
@env = env
|
@@ -46,27 +47,23 @@ module StackifyRubyAPM
|
|
46
47
|
close_old_response(response)
|
47
48
|
return nil unless source
|
48
49
|
|
49
|
-
|
50
|
-
device_id = @config.device_id
|
51
|
-
client_rundomain = @config.client_run_domain
|
50
|
+
transaction_id = defined?(StackifyRubyAPM.current_transaction.id) ? StackifyRubyAPM.current_transaction.id : nil
|
52
51
|
inject_flag = false
|
53
52
|
|
54
|
-
if
|
55
|
-
|
56
|
-
inject_flag = true
|
57
|
-
else
|
58
|
-
info 'RUM Injection Error: Client RUM Domain is invalid.'
|
59
|
-
end
|
53
|
+
if transaction_id
|
54
|
+
inject_flag = true
|
60
55
|
else
|
61
|
-
info 'RUM Injection Error: No
|
56
|
+
info 'RUM Injection Error: No Transaction ID found.'
|
62
57
|
end
|
63
58
|
|
64
59
|
return unless inject_flag
|
65
60
|
|
61
|
+
return if has_stackify_tag(source[0..SCAN_LIMIT])
|
62
|
+
|
66
63
|
# Only scan the first 50k (roughly) then give up.
|
67
64
|
insertion_index = find_end_of_head_open(source[0..SCAN_LIMIT])
|
68
65
|
|
69
|
-
if insertion_index
|
66
|
+
if insertion_index
|
70
67
|
source = source[0...insertion_index] <<
|
71
68
|
StackifyRubyAPM.inject_rum_script <<
|
72
69
|
source[insertion_index..-1]
|
@@ -77,13 +74,21 @@ module StackifyRubyAPM
|
|
77
74
|
# rubocop:enable Metrics/PerceivedComplexity
|
78
75
|
|
79
76
|
def find_end_of_head_open(beginning_of_source)
|
80
|
-
head_open = beginning_of_source.index(
|
81
|
-
beginning_of_source.index(GT, head_open)
|
77
|
+
head_open = beginning_of_source.index(HEAD_START)
|
78
|
+
beginning_of_source.index(GT, head_open) + 1 if head_open
|
79
|
+
end
|
80
|
+
|
81
|
+
def has_stackify_tag(beginning_of_source)
|
82
|
+
!!beginning_of_source.index(STACKIFY_SETTING_TAG)
|
82
83
|
end
|
83
84
|
|
84
85
|
def gather_source(response)
|
85
86
|
source = nil
|
86
|
-
response.
|
87
|
+
if response.respond_to?(:each)
|
88
|
+
response.each { |fragment| source ? (source << fragment.to_s) : (source = fragment.to_s) }
|
89
|
+
else
|
90
|
+
source << response
|
91
|
+
end
|
87
92
|
source
|
88
93
|
end
|
89
94
|
|
@@ -31,7 +31,7 @@ module StackifyRubyAPM
|
|
31
31
|
APPLICATION_FILESYSTEM_PATH: @config.root_path,
|
32
32
|
APPLICATION_NAME: @config.application_name.strip,
|
33
33
|
APPLICATION_ENV: @config.environment_name || 'Development',
|
34
|
-
REPORTING_URL: @transaction.name,
|
34
|
+
REPORTING_URL: @transaction.name || '/',
|
35
35
|
TRACE_ID: @transaction.id,
|
36
36
|
THREAD_ID: Thread.current.object_id,
|
37
37
|
TRACE_SOURCE: 'RUBY',
|
@@ -45,7 +45,7 @@ module StackifyRubyAPM
|
|
45
45
|
hash[:METHOD] = @transaction.context.request.method if @transaction.context && @transaction.context.request && @transaction.context.request.method
|
46
46
|
hash[:STATUS] = @transaction.context.response.status_code if @transaction.context && @transaction.context.response && @transaction.context.response.status_code
|
47
47
|
hash[:URL] = @transaction.context.request.url[:full] if @transaction.context && @transaction.context.request && @transaction.context.request.url[:full]
|
48
|
-
hash[:
|
48
|
+
hash[:ISRUM] = 'TRUE' if @transaction.context && @transaction.context.rum
|
49
49
|
hash[:AWS_LAMBDA_ARN] = @transaction.context.aws[:arn] if @transaction.context && @transaction.context.aws && @transaction.context.aws[:arn]
|
50
50
|
hash[:PREFIX_RESPONSE_BODY] = @transaction.context.prefix.response_body.to_s if @transaction.context.prefix && @transaction.context.prefix.response_body
|
51
51
|
hash[:PREFIX_RESPONSE_SIZE_BYTES] = @transaction.context.prefix.response_body.length.to_s if @transaction.context.prefix && @transaction.context.prefix.response_body
|
@@ -26,6 +26,26 @@ module StackifyRubyAPM
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
class ActionDispatchDebugExceptionsSpy
|
30
|
+
def install
|
31
|
+
::ActionDispatch::DebugExceptions.class_eval do
|
32
|
+
alias_method 'render_exception_without_apm', 'render_exception'
|
33
|
+
|
34
|
+
def render_exception(env, exception)
|
35
|
+
# Creates exception log report
|
36
|
+
#
|
37
|
+
begin
|
38
|
+
StackifyRubyAPM.report(exception)
|
39
|
+
rescue Exception => e
|
40
|
+
StackifyRubyAPM.agent.error '[ActionDispatchDebugExceptionsSpy] Error: repoting exception.'
|
41
|
+
StackifyRubyAPM.agent.error "[ActionDispatchDebugExceptionsSpy] #{e.inspect}"
|
42
|
+
end
|
43
|
+
render_exception_without_apm env, exception
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
29
49
|
# Registers ActionDispatch spy, go to: /stackify_apm/spies.rb
|
30
50
|
#
|
31
51
|
register(
|
@@ -33,5 +53,11 @@ module StackifyRubyAPM
|
|
33
53
|
'action_dispatch/show_exception',
|
34
54
|
ActionDispatchSpy.new
|
35
55
|
)
|
56
|
+
|
57
|
+
register(
|
58
|
+
'ActionDispatch::DebugExceptions',
|
59
|
+
'action_dispatch/debug_exceptions',
|
60
|
+
ActionDispatchDebugExceptionsSpy.new
|
61
|
+
)
|
36
62
|
end
|
37
63
|
end
|
@@ -16,9 +16,9 @@ module StackifyRubyAPM
|
|
16
16
|
singleton_class.send(:alias_method, :http_put_without_apm, :http_put)
|
17
17
|
singleton_class.send(:alias_method, :http_get_without_apm, :http_get)
|
18
18
|
singleton_class.send(:alias_method, :http_delete_without_apm, :http_delete)
|
19
|
-
def self.perform(*args)
|
19
|
+
def self.perform(*args, **kwargs)
|
20
20
|
req = nil
|
21
|
-
return perform_without_apm(*args) unless StackifyRubyAPM.current_transaction
|
21
|
+
return perform_without_apm(*args, **kwargs) unless StackifyRubyAPM.current_transaction
|
22
22
|
|
23
23
|
begin
|
24
24
|
# Data configuration
|
@@ -40,14 +40,14 @@ module StackifyRubyAPM
|
|
40
40
|
rescue Exception => e
|
41
41
|
StackifyRubyAPM.agent.error "[CurbEasySpy] Error: creating span context."
|
42
42
|
StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
|
43
|
-
return perform_without_apm(*args)
|
43
|
+
return perform_without_apm(*args, **kwargs)
|
44
44
|
end
|
45
45
|
|
46
46
|
# Creates new span from HTTP result
|
47
47
|
StackifyRubyAPM.span name, type, context: ctx do
|
48
48
|
# Submits HTTP request
|
49
49
|
#
|
50
|
-
res = perform_without_apm(*args)
|
50
|
+
res = perform_without_apm(*args, **kwargs)
|
51
51
|
|
52
52
|
begin
|
53
53
|
status_code = res.status.sub(/^0-9/, '').to_i
|
@@ -67,9 +67,9 @@ module StackifyRubyAPM
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
def self.http_post(*args)
|
70
|
+
def self.http_post(*args, **kwargs)
|
71
71
|
req = nil
|
72
|
-
return http_post_without_apm(*args) unless StackifyRubyAPM.current_transaction
|
72
|
+
return http_post_without_apm(*args, **kwargs) unless StackifyRubyAPM.current_transaction
|
73
73
|
|
74
74
|
begin
|
75
75
|
# Data configuration
|
@@ -90,12 +90,12 @@ module StackifyRubyAPM
|
|
90
90
|
rescue Exception => e
|
91
91
|
StackifyRubyAPM.agent.error "[CurbEasySpy] Error: creating span context."
|
92
92
|
StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
|
93
|
-
return http_post_without_apm(*args)
|
93
|
+
return http_post_without_apm(*args, **kwargs)
|
94
94
|
end
|
95
95
|
|
96
96
|
# Creates new span from HTTP result
|
97
97
|
StackifyRubyAPM.span name, type, context: ctx do
|
98
|
-
res = http_post_without_apm(*args)
|
98
|
+
res = http_post_without_apm(*args, **kwargs)
|
99
99
|
|
100
100
|
begin
|
101
101
|
status_code = res.status.sub(/^0-9/, '').to_i
|
@@ -178,9 +178,9 @@ module StackifyRubyAPM
|
|
178
178
|
end
|
179
179
|
end
|
180
180
|
|
181
|
-
def self.http_get(*args)
|
181
|
+
def self.http_get(*args, **kwargs)
|
182
182
|
req = nil
|
183
|
-
return http_get_without_apm(*args) unless StackifyRubyAPM.current_transaction
|
183
|
+
return http_get_without_apm(*args, **kwargs) unless StackifyRubyAPM.current_transaction
|
184
184
|
|
185
185
|
begin
|
186
186
|
# Data configuration
|
@@ -201,12 +201,12 @@ module StackifyRubyAPM
|
|
201
201
|
rescue Exception => e
|
202
202
|
StackifyRubyAPM.agent.error "[CurbEasySpy] Error: creating span context."
|
203
203
|
StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
|
204
|
-
return http_get_without_apm(*args)
|
204
|
+
return http_get_without_apm(*args, **kwargs)
|
205
205
|
end
|
206
206
|
|
207
207
|
# Creates new span from HTTP result
|
208
208
|
StackifyRubyAPM.span name, type, context: ctx do
|
209
|
-
res = http_get_without_apm(*args)
|
209
|
+
res = http_get_without_apm(*args, **kwargs)
|
210
210
|
|
211
211
|
begin
|
212
212
|
status_code = res.status.sub(/^0-9/, '').to_i
|
@@ -227,9 +227,9 @@ module StackifyRubyAPM
|
|
227
227
|
end
|
228
228
|
end
|
229
229
|
|
230
|
-
def self.http_delete(*args)
|
230
|
+
def self.http_delete(*args, **kwargs)
|
231
231
|
req = nil
|
232
|
-
return http_delete_without_apm(*args) unless StackifyRubyAPM.current_transaction
|
232
|
+
return http_delete_without_apm(*args, **kwargs) unless StackifyRubyAPM.current_transaction
|
233
233
|
|
234
234
|
begin
|
235
235
|
# Data configuration
|
@@ -250,12 +250,12 @@ module StackifyRubyAPM
|
|
250
250
|
rescue Exception => e
|
251
251
|
StackifyRubyAPM.agent.error "[CurbEasySpy] Error: creating span context."
|
252
252
|
StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
|
253
|
-
return http_delete_without_apm(*args)
|
253
|
+
return http_delete_without_apm(*args, **kwargs)
|
254
254
|
end
|
255
255
|
|
256
256
|
# Creates new span from HTTP result
|
257
257
|
StackifyRubyAPM.span name, type, context: ctx do
|
258
|
-
res = http_delete_without_apm(*args)
|
258
|
+
res = http_delete_without_apm(*args, **kwargs)
|
259
259
|
|
260
260
|
begin
|
261
261
|
status_code = res.status.sub(/^0-9/, '').to_i
|
@@ -12,7 +12,7 @@ module StackifyRubyAPM
|
|
12
12
|
Delayed::Backend::Base.class_eval do
|
13
13
|
alias_method 'invoke_job_without_apm', 'invoke_job'
|
14
14
|
|
15
|
-
def invoke_job(*args, &block)
|
15
|
+
def invoke_job(*args, **kwargs, &block)
|
16
16
|
ret = nil
|
17
17
|
begin
|
18
18
|
name = nil
|
@@ -29,7 +29,7 @@ module StackifyRubyAPM
|
|
29
29
|
ctx = StackifyRubyAPM::Context.new
|
30
30
|
ctx.category = 'Delayed::Job'
|
31
31
|
transaction = StackifyRubyAPM.transaction name, 'TASK', context: ctx
|
32
|
-
ret = invoke_job_without_apm(*args, &block)
|
32
|
+
ret = invoke_job_without_apm(*args, **kwargs, &block)
|
33
33
|
rescue StackifyRubyAPM::InternalError
|
34
34
|
raise # Don't report StackifyRubyAPM errors
|
35
35
|
rescue StandardError => e
|
@@ -12,9 +12,9 @@ module StackifyRubyAPM
|
|
12
12
|
HTTPClient.class_eval do
|
13
13
|
alias_method 'request_without_apm', 'request'
|
14
14
|
|
15
|
-
def request(method, uri, *args, &block)
|
15
|
+
def request(method, uri, *args, **kwargs, &block)
|
16
16
|
req = nil
|
17
|
-
return request_without_apm(method, uri, *args, &block) unless StackifyRubyAPM.current_transaction
|
17
|
+
return request_without_apm(method, uri, *args, **kwargs, &block) unless StackifyRubyAPM.current_transaction
|
18
18
|
|
19
19
|
begin
|
20
20
|
# Data configuration
|
@@ -36,7 +36,7 @@ module StackifyRubyAPM
|
|
36
36
|
rescue Exception => e
|
37
37
|
StackifyRubyAPM.agent.error "[HTTPClientSpy] Error: creating span context."
|
38
38
|
StackifyRubyAPM.agent.error "[HTTPClientSpy] #{e.inspect}"
|
39
|
-
return request_without_apm(method, uri, *args, &block)
|
39
|
+
return request_without_apm(method, uri, *args, **kwargs, &block)
|
40
40
|
end
|
41
41
|
|
42
42
|
# Creates new span from HTTP result
|
@@ -44,7 +44,7 @@ module StackifyRubyAPM
|
|
44
44
|
StackifyRubyAPM.span name, type, context: ctx do
|
45
45
|
# Submits HTTP request
|
46
46
|
#
|
47
|
-
res = request_without_apm(method, uri, *args, &block)
|
47
|
+
res = request_without_apm(method, uri, *args, **kwargs, &block)
|
48
48
|
|
49
49
|
begin
|
50
50
|
ctx.update_status(res.status_code)
|