stackify-ruby-apm 1.14.8 → 1.16.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|