stackify-ruby-apm 1.12.3 → 1.14.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/stackify_apm/config.rb +4 -1
- data/lib/stackify_apm/helper/database_helper.rb +6 -5
- data/lib/stackify_apm/logger/log_device.rb +19 -0
- data/lib/stackify_apm/middleware.rb +2 -0
- data/lib/stackify_apm/normalizers/active_record.rb +11 -0
- data/lib/stackify_apm/root_info.rb +6 -6
- data/lib/stackify_apm/span/context.rb +16 -13
- data/lib/stackify_apm/spies/dynamo_db.rb +51 -0
- data/lib/stackify_apm/spies/faraday.rb +87 -0
- data/lib/stackify_apm/spies/log4r.rb +2 -1
- data/lib/stackify_apm/spies/logger.rb +2 -1
- data/lib/stackify_apm/spies/logging.rb +2 -1
- data/lib/stackify_apm/spies/mongo.rb +3 -1
- data/lib/stackify_apm/spies/redis.rb +13 -6
- data/lib/stackify_apm/spies/sinatra_activerecord/mysql_adapter.rb +21 -0
- data/lib/stackify_apm/spies/sinatra_activerecord/postgresql_adapter.rb +8 -0
- data/lib/stackify_apm/spies/sucker_punch.rb +39 -0
- data/lib/stackify_apm/spies/yell.rb +2 -1
- data/lib/stackify_apm/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d95a01fea8c43d40a4cf1f0f541f539e31d9e022d985e70096d3b01260cbab8
|
4
|
+
data.tar.gz: c4a871133a02ba479ceea744f9f868ab34910c291e947fe62cc644330f6935c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4ca5f2806b494bc98ecb9828a01dbb3e459328401c8a880a4239d0ff8ad16073ace3a7e52ec02fb93b633f14f1b6493dd46daa381ee0ef7fc9ac23a1a319cdb
|
7
|
+
data.tar.gz: 873b62a9ef92ef3ea222ea7ed2fbfff26e41b2114ea030ac668646db394e0093feab0588d08e390776fcc38b8d6ff152cf6df1d472b886be0f102a71f5d0ab90
|
data/lib/stackify_apm/config.rb
CHANGED
@@ -29,7 +29,7 @@ module DatabaseHelper
|
|
29
29
|
# Placeholder for mysql, sqlite, jdbc oracle, db2 is ?, example "SELECT * FROM posts WHERE author = ? and id = ?"
|
30
30
|
# Placeholder for postgres is $1, $2,...$n, example "SELECT * FROM posts WHERE author = $1 and id = $2"
|
31
31
|
# statement - contains the db properties such as SQL, PROVIDER, etc.
|
32
|
-
# So if there's payload value we append
|
32
|
+
# So if there's payload value we append PREFIX_SQL_PARAMETERS to the existing object properties.
|
33
33
|
# payload - contains the payload[:binds] which is the payload value/data of the placeholder.
|
34
34
|
# Example payload: {:sql=>"SELECT * FROM posts WHERE author = ? and id = ?", :db_adapter=>"mysql2::client", :binds=>["J.K. Rowling", 1]}
|
35
35
|
def check_prepared_stmt_by_placeholder(placeholder, statement, payload)
|
@@ -37,14 +37,15 @@ module DatabaseHelper
|
|
37
37
|
unless payload[:binds].nil?
|
38
38
|
payload[:binds].each_with_index do |record, idx|
|
39
39
|
if record && defined?(record.value)
|
40
|
-
StackifyRubyAPM::Util.pushToAryIndex(sqlParam, idx, record.value)
|
40
|
+
StackifyRubyAPM::Util.pushToAryIndex(sqlParam, idx, record.value[0..999])
|
41
41
|
elsif ((record && record.instance_of?(Array)) && defined?(record[1]))
|
42
|
-
StackifyRubyAPM::Util.pushToAryIndex(sqlParam, idx, record[1])
|
42
|
+
StackifyRubyAPM::Util.pushToAryIndex(sqlParam, idx, record[1][0..999])
|
43
43
|
else
|
44
|
-
StackifyRubyAPM::Util.pushToAryIndex(sqlParam, idx, record)
|
44
|
+
StackifyRubyAPM::Util.pushToAryIndex(sqlParam, idx, record[0..999])
|
45
45
|
end
|
46
46
|
end
|
47
|
-
statement[:
|
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
|
48
49
|
true
|
49
50
|
else
|
50
51
|
false
|
@@ -8,6 +8,7 @@
|
|
8
8
|
module StackifyRubyAPM
|
9
9
|
# @api private
|
10
10
|
class LogDevice < Logger::LogDevice
|
11
|
+
MAX_LOG_FILES_COUNT = 10
|
11
12
|
alias_method 'write_without_apm', 'write'
|
12
13
|
def write(message)
|
13
14
|
if @filename
|
@@ -84,6 +85,24 @@ module StackifyRubyAPM
|
|
84
85
|
def create_logfile(filename)
|
85
86
|
logdev = super
|
86
87
|
File.chmod(0o777, filename)
|
88
|
+
|
89
|
+
begin
|
90
|
+
dir_name = File.dirname(filename)
|
91
|
+
# repath current file due to windows separator \\ doesn't work with Dir.glob
|
92
|
+
dir_name = dir_name.split(File::ALT_SEPARATOR).join(File::SEPARATOR)
|
93
|
+
search_files = File.join("#{dir_name}", "{[!stackify-ruby-apm]*}.log")
|
94
|
+
log_files = Dir.glob(search_files).sort_by { |f| File.stat(f).mtime}.reverse
|
95
|
+
|
96
|
+
if log_files.length > MAX_LOG_FILES_COUNT
|
97
|
+
files_to_delete = log_files[MAX_LOG_FILES_COUNT..-1]
|
98
|
+
files_to_delete.each { |f|
|
99
|
+
File.delete(f) if File.exists? f
|
100
|
+
}
|
101
|
+
end
|
102
|
+
rescue
|
103
|
+
# nothing to do here
|
104
|
+
end
|
105
|
+
|
87
106
|
logdev
|
88
107
|
end
|
89
108
|
# rubocop:enable Style/RescueModifier
|
@@ -53,6 +53,8 @@ module StackifyRubyAPM
|
|
53
53
|
if okay_to_modify?
|
54
54
|
@configuration.already_instrumented_flag = true
|
55
55
|
if @configuration.rum_enabled.is_a?(TrueClass)
|
56
|
+
# close old response body proxy to close all db connections
|
57
|
+
@rack_body.close if @rack_body.respond_to?(:close)
|
56
58
|
response = Rack::Response.new @rack_body, @rack_status, @rack_headers
|
57
59
|
response.set_cookie(@configuration.rum_cookie_name, value: transaction.id, path: @configuration.rum_cookie_path)
|
58
60
|
resp = response.finish
|
@@ -29,9 +29,13 @@ module StackifyRubyAPM
|
|
29
29
|
private
|
30
30
|
|
31
31
|
def query_variables(payload)
|
32
|
+
adapter_config = lookup_adapter_config
|
32
33
|
props = get_common_db_properties
|
33
34
|
props[:PROVIDER] = get_profiler(lookup_adapter)
|
34
35
|
props[:SQL] = payload[:sql]
|
36
|
+
if adapter_config
|
37
|
+
props[:URL] = "#{adapter_config[:host]}:#{adapter_config[:port]}"
|
38
|
+
end
|
35
39
|
props
|
36
40
|
end
|
37
41
|
|
@@ -42,6 +46,13 @@ module StackifyRubyAPM
|
|
42
46
|
nil
|
43
47
|
end
|
44
48
|
|
49
|
+
def lookup_adapter_config
|
50
|
+
::ActiveRecord::Base.connection_config.to_h
|
51
|
+
rescue StandardError => error
|
52
|
+
debug '[SqlNormalizer] lookup_adapter_config err: ' + error.inspect.to_s
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
45
56
|
def check_prepared_stmt(statement, payload)
|
46
57
|
if StackifyRubyAPM.agent.config.prefix_enabled
|
47
58
|
case get_profiler(lookup_adapter)
|
@@ -47,12 +47,12 @@ module StackifyRubyAPM
|
|
47
47
|
hash[:URL] = @transaction.context.request.url[:full] if @transaction.context && @transaction.context.request && @transaction.context.request.url[:full]
|
48
48
|
hash[:RUM] = true if @config.rum_enabled.is_a?(TrueClass)
|
49
49
|
hash[:AWS_LAMBDA_ARN] = @transaction.context.aws[:arn] if @transaction.context && @transaction.context.aws && @transaction.context.aws[:arn]
|
50
|
-
hash[:
|
51
|
-
hash[:
|
52
|
-
hash[:
|
53
|
-
hash[:
|
54
|
-
hash[:
|
55
|
-
hash[:
|
50
|
+
hash[:PREFIX_RESPONSE_BODY] = @transaction.context.prefix.response_body.to_s if @transaction.context.prefix && @transaction.context.prefix.response_body
|
51
|
+
hash[:PREFIX_RESPONSE_SIZE_BYTES] = @transaction.context.prefix.response_body.length.to_s if @transaction.context.prefix && @transaction.context.prefix.response_body
|
52
|
+
hash[:PREFIX_RESPONSE_HEADERS] = @transaction.context.prefix.response_headers.to_s if @transaction.context.prefix && @transaction.context.prefix.response_headers
|
53
|
+
hash[:PREFIX_REQUEST_BODY] = @transaction.context.prefix.request_body.to_s if @transaction.context.prefix && @transaction.context.prefix.request_body
|
54
|
+
hash[:PREFIX_REQUEST_SIZE_BYTES] = @transaction.context.prefix.request_body.length.to_s if @transaction.context.prefix && @transaction.context.prefix.request_body
|
55
|
+
hash[:PREFIX_REQUEST_HEADERS] = @transaction.context.prefix.request_headers.to_s if @transaction.context.prefix && @transaction.context.prefix.request_headers
|
56
56
|
hash
|
57
57
|
end
|
58
58
|
# rubocop:enable Metrics/CyclomaticComplexity
|
@@ -17,7 +17,8 @@ module StackifyRubyAPM
|
|
17
17
|
:COMPONENT_CATEGORY,
|
18
18
|
:COMPONENT_DETAIL,
|
19
19
|
:SQL,
|
20
|
-
:
|
20
|
+
:PREFIX_SQL_PARAMETERS,
|
21
|
+
:PREFIX_SQL_PARAMETER_COUNT,
|
21
22
|
:SQL_TRUNCATED,
|
22
23
|
:MONGODB_COLLECTION,
|
23
24
|
:METHOD,
|
@@ -33,33 +34,35 @@ module StackifyRubyAPM
|
|
33
34
|
:LEVEL,
|
34
35
|
:MESSAGE,
|
35
36
|
:EXCEPTION,
|
36
|
-
:
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:
|
37
|
+
:PREFIX_REQUEST_BODY,
|
38
|
+
:PREFIX_REQUEST_SIZE_BYTES,
|
39
|
+
:PREFIX_REQUEST_HEADERS,
|
40
|
+
:PREFIX_RESPONSE_BODY,
|
41
|
+
:PREFIX_RESPONSE_SIZE_BYTES,
|
42
|
+
:PREFIX_RESPONSE_HEADERS,
|
43
|
+
:PREFIX,
|
44
|
+
:ACTION
|
42
45
|
# rubocop:disable Style/VariableName
|
43
46
|
def update_status(status)
|
44
47
|
@STATUS = status
|
45
48
|
end
|
46
49
|
|
47
50
|
def update_request_body(body)
|
48
|
-
@
|
49
|
-
@
|
51
|
+
@PREFIX_REQUEST_BODY = body.to_s
|
52
|
+
@PREFIX_REQUEST_SIZE_BYTES = body.to_s.length.to_s
|
50
53
|
end
|
51
54
|
|
52
55
|
def update_request_headers(headers)
|
53
|
-
@
|
56
|
+
@PREFIX_REQUEST_HEADERS = to_json_list(headers)
|
54
57
|
end
|
55
58
|
|
56
59
|
def update_response_body(body)
|
57
|
-
@
|
58
|
-
@
|
60
|
+
@PREFIX_RESPONSE_BODY = body.to_s
|
61
|
+
@PREFIX_RESPONSE_SIZE_BYTES = body.to_s.length.to_s
|
59
62
|
end
|
60
63
|
|
61
64
|
def update_response_headers(headers)
|
62
|
-
@
|
65
|
+
@PREFIX_RESPONSE_HEADERS = to_json_list(headers)
|
63
66
|
end
|
64
67
|
|
65
68
|
private
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Monkey patch for the Aws::DynamoDB::Client class
|
2
|
+
|
3
|
+
module StackifyRubyAPM
|
4
|
+
# @api private
|
5
|
+
module Spies
|
6
|
+
# @api private
|
7
|
+
class DynamoDBSpy
|
8
|
+
TYPE = 'db.dynamo.aws'.freeze
|
9
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
10
|
+
def install
|
11
|
+
Aws::DynamoDB::Client.class_eval do
|
12
|
+
# Alias all available operations
|
13
|
+
api.operation_names.each do |operation_name|
|
14
|
+
alias_method "#{operation_name}_without_apm", "#{operation_name}"
|
15
|
+
|
16
|
+
define_method(operation_name) do |params = {}, options = {}|
|
17
|
+
original_method = method("#{operation_name}_without_apm")
|
18
|
+
return original_method.call(params, options) unless StackifyRubyAPM.current_transaction
|
19
|
+
|
20
|
+
result = nil
|
21
|
+
|
22
|
+
begin
|
23
|
+
name = operation_name
|
24
|
+
ctx = Span::Context.new(
|
25
|
+
CATEGORY: 'Database',
|
26
|
+
SUBCATEGORY: 'DynamoDB',
|
27
|
+
ACTION: operation_name,
|
28
|
+
URL: self.config.endpoint,
|
29
|
+
)
|
30
|
+
rescue Exception => e
|
31
|
+
StackifyRubyAPM.agent.error "[DynamoDBSpy] Error: creating span context."
|
32
|
+
StackifyRubyAPM.agent.error "[DynamoDBSpy] #{e.inspect}"
|
33
|
+
return original_method.call(params, options)
|
34
|
+
end
|
35
|
+
|
36
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
37
|
+
result = original_method.call(params, options)
|
38
|
+
return result
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
# rubocop:enable Metrics/MethodLength
|
45
|
+
end
|
46
|
+
|
47
|
+
# Registers Aws::DynamoDB::Client spy, go to: /stackify_apm/spies.rb
|
48
|
+
#
|
49
|
+
register 'Aws::DynamoDB::Client', 'aws-sdk-dynamodb', DynamoDBSpy.new
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# Monkey patch for the Faraday class
|
2
|
+
|
3
|
+
module StackifyRubyAPM
|
4
|
+
# @api private
|
5
|
+
module Spies
|
6
|
+
# @api private
|
7
|
+
class FaradaySpy
|
8
|
+
def install
|
9
|
+
Faraday::Connection.class_eval do
|
10
|
+
alias_method 'run_request_without_apm', 'run_request'
|
11
|
+
|
12
|
+
def run_request(method, url, body, headers, &block)
|
13
|
+
result = nil
|
14
|
+
return run_request_without_apm(method, url, body, headers, &block) unless StackifyRubyAPM.current_transaction
|
15
|
+
|
16
|
+
begin
|
17
|
+
uri = URI(build_url(url))
|
18
|
+
|
19
|
+
# url is not available yet if it is set inside block
|
20
|
+
# we need to build temporary request as of now
|
21
|
+
# NOTE: this could have a side effect doing yeild twice
|
22
|
+
unless uri.host
|
23
|
+
tmp_request = build_request(method) do |req|
|
24
|
+
yield(req) if block_given?
|
25
|
+
end
|
26
|
+
uri = URI(tmp_request.path)
|
27
|
+
end
|
28
|
+
|
29
|
+
host = uri.host
|
30
|
+
method_upcase = method.to_s.upcase
|
31
|
+
name = "#{method_upcase} #{host}"
|
32
|
+
type = "ext.faraday.#{method_upcase}"
|
33
|
+
|
34
|
+
# Builds span context
|
35
|
+
#
|
36
|
+
ctx = Span::Context.new(
|
37
|
+
CATEGORY: 'Web External',
|
38
|
+
SUBCATEGORY: 'Execute',
|
39
|
+
URL: uri,
|
40
|
+
STATUS: '',
|
41
|
+
METHOD: method_upcase
|
42
|
+
)
|
43
|
+
rescue Exception => e
|
44
|
+
StackifyRubyAPM.agent.error "[FaradaySpy] Error: creating span context."
|
45
|
+
StackifyRubyAPM.agent.error "[FaradaySpy] #{e.inspect}"
|
46
|
+
return run_request_without_apm(method, url, body, headers, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Creates new span from HTTP result
|
50
|
+
#
|
51
|
+
StackifyRubyAPM.span name, type, context: ctx do
|
52
|
+
# Submits HTTP request
|
53
|
+
#
|
54
|
+
result = run_request_without_apm(method, url, body, headers) do |req|
|
55
|
+
yield req if block_given?
|
56
|
+
|
57
|
+
if StackifyRubyAPM.agent.config.prefix_enabled
|
58
|
+
ctx.update_request_body(req.body || body || "")
|
59
|
+
ctx.update_request_headers(req.headers || headers || Hash.new)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
begin
|
64
|
+
status_code = result.status.to_s
|
65
|
+
ctx.update_status(status_code)
|
66
|
+
|
67
|
+
if StackifyRubyAPM.agent.config.prefix_enabled
|
68
|
+
ctx.update_response_body(result.body || "")
|
69
|
+
ctx.update_response_headers(result.headers || Hash.new)
|
70
|
+
end
|
71
|
+
rescue Exception => e
|
72
|
+
StackifyRubyAPM.agent.error '[FaradaySpy] Error: getting status code or updating request/response context.'
|
73
|
+
StackifyRubyAPM.agent.error "[FaradaySpy] #{e.inspect}"
|
74
|
+
end
|
75
|
+
return result
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
# rubocop:enable Metrics/MethodLength
|
81
|
+
end
|
82
|
+
|
83
|
+
# Registers Faraday spy, go to: /stackify_apm/spies.rb
|
84
|
+
#
|
85
|
+
register 'Faraday', 'faraday', FaradaySpy.new
|
86
|
+
end
|
87
|
+
end
|
@@ -18,11 +18,13 @@ module StackifyRubyAPM
|
|
18
18
|
name = command[0].upcase.to_s
|
19
19
|
type = 'db.redis'
|
20
20
|
redis_details = command[1].is_a?(String) ? command[1].split(':') : []
|
21
|
-
|
21
|
+
# use length instead of .blank?
|
22
|
+
# reason: will throw error if activesupport missing
|
23
|
+
redis_nspace = redis_details.length ? redis_details[0] : ''
|
22
24
|
redis_key = ''
|
23
25
|
|
24
26
|
# Checks CACHEKEY value
|
25
|
-
if
|
27
|
+
if redis_details.length && redis_details[1]
|
26
28
|
# Initially sets the CACHEKEY value
|
27
29
|
args = redis_details[1].split('/')
|
28
30
|
redis_key = args[0]
|
@@ -31,7 +33,11 @@ module StackifyRubyAPM
|
|
31
33
|
# Possible formats:
|
32
34
|
# `<namespace:key/method_name/expires_in=300/ttl=60/>`
|
33
35
|
# `<namespace:key/expires_in=300/ttl=60/>`
|
34
|
-
|
36
|
+
if redis_key.nil?
|
37
|
+
redis_key = redis_details[1]
|
38
|
+
else
|
39
|
+
redis_key = args[0..1].join('/') if args.length > 1 && !args[1].include?('=')
|
40
|
+
end
|
35
41
|
end
|
36
42
|
|
37
43
|
return call_without_apm(command, &block) if command[0] == :auth
|
@@ -43,10 +49,11 @@ module StackifyRubyAPM
|
|
43
49
|
COMPONENT_CATEGORY: 'Cache',
|
44
50
|
COMPONENT_DETAIL: 'Execute',
|
45
51
|
THREAD_ID: Thread.current.object_id,
|
46
|
-
OPERATION: name
|
52
|
+
OPERATION: name,
|
53
|
+
URL: "#{self.options[:host]}:#{self.options[:port]}"
|
47
54
|
}.tap do |hash|
|
48
|
-
hash[:CACHEKEY] = redis_key unless redis_key.empty?
|
49
|
-
hash[:CACHENAME] = redis_nspace unless redis_nspace.empty?
|
55
|
+
hash[:CACHEKEY] = redis_key unless redis_key.nil? || redis_key.empty?
|
56
|
+
hash[:CACHENAME] = redis_nspace unless redis_nspace.nil? || redis_nspace.empty?
|
50
57
|
end
|
51
58
|
|
52
59
|
ctx = Span::Context.new(context)
|
@@ -10,6 +10,7 @@ module StackifyRubyAPM
|
|
10
10
|
# @api private
|
11
11
|
class MysqlAdapterSpy
|
12
12
|
TYPE = 'db.sinatra_active_record.sql'.freeze
|
13
|
+
DEFAULT_PORT = 3306
|
13
14
|
if ActiveRecord::VERSION::MAJOR.to_i >= 5
|
14
15
|
def install
|
15
16
|
ActiveRecord::ConnectionAdapters::MySQL::DatabaseStatements.class_eval do
|
@@ -79,6 +80,7 @@ module StackifyRubyAPM
|
|
79
80
|
props = get_common_db_properties
|
80
81
|
props[:PROVIDER] = 'mysql'
|
81
82
|
props[:SQL] = payload[:sql]
|
83
|
+
props[:URL] = get_host unless !get_host
|
82
84
|
props
|
83
85
|
end
|
84
86
|
|
@@ -87,6 +89,13 @@ module StackifyRubyAPM
|
|
87
89
|
check_prepared_stmt_by_placeholder(payload[:sql].include?('?'), statement, payload)
|
88
90
|
end
|
89
91
|
end
|
92
|
+
|
93
|
+
def get_host
|
94
|
+
query_options = self.raw_connection.query_options.to_h
|
95
|
+
"#{query_options[:host]}:#{query_options[:port] || DEFAULT_PORT}"
|
96
|
+
rescue StandardError => error
|
97
|
+
nil
|
98
|
+
end
|
90
99
|
end
|
91
100
|
end
|
92
101
|
else
|
@@ -112,6 +121,7 @@ module StackifyRubyAPM
|
|
112
121
|
SQL: sql,
|
113
122
|
PROVIDER: 'mysql'
|
114
123
|
)
|
124
|
+
ctx[:URL] = get_host unless !get_host
|
115
125
|
|
116
126
|
result = exec_query_without_apm(sql, name, binds)
|
117
127
|
|
@@ -135,6 +145,7 @@ module StackifyRubyAPM
|
|
135
145
|
SQL: sql,
|
136
146
|
PROVIDER: 'mysql'
|
137
147
|
)
|
148
|
+
ctx[:URL] = get_host unless !get_host
|
138
149
|
|
139
150
|
result = exec_delete_without_apm(sql, name, binds)
|
140
151
|
|
@@ -158,6 +169,7 @@ module StackifyRubyAPM
|
|
158
169
|
SQL: sql,
|
159
170
|
PROVIDER: 'mysql'
|
160
171
|
)
|
172
|
+
ctx[:URL] = get_host unless !get_host
|
161
173
|
|
162
174
|
result = exec_update_without_apm(sql, name, binds)
|
163
175
|
|
@@ -181,6 +193,7 @@ module StackifyRubyAPM
|
|
181
193
|
SQL: sql,
|
182
194
|
PROVIDER: 'mysql'
|
183
195
|
)
|
196
|
+
ctx[:URL] = get_host unless !get_host
|
184
197
|
|
185
198
|
result = exec_insert_without_apm(sql, name, binds, _pk = nil, _sequence_name = nil)
|
186
199
|
|
@@ -188,6 +201,14 @@ module StackifyRubyAPM
|
|
188
201
|
return result
|
189
202
|
end
|
190
203
|
end
|
204
|
+
|
205
|
+
def get_host
|
206
|
+
config = self.config.to_h
|
207
|
+
"#{config[:host]}:#{config[:port] || DEFAULT_PORT}"
|
208
|
+
rescue StandardError => error
|
209
|
+
nil
|
210
|
+
end
|
211
|
+
|
191
212
|
end
|
192
213
|
end
|
193
214
|
end
|
@@ -80,6 +80,7 @@ module StackifyRubyAPM
|
|
80
80
|
props = get_common_db_properties
|
81
81
|
props[:PROVIDER] = 'postgresql'
|
82
82
|
props[:SQL] = payload[:sql]
|
83
|
+
props[:URL] = get_host unless !get_host
|
83
84
|
props
|
84
85
|
end
|
85
86
|
|
@@ -88,6 +89,13 @@ module StackifyRubyAPM
|
|
88
89
|
check_prepared_stmt_by_placeholder(!!payload[:sql].match(/\$\d/), statement, payload)
|
89
90
|
end
|
90
91
|
end
|
92
|
+
|
93
|
+
def get_host
|
94
|
+
connection = self.raw_connection
|
95
|
+
"#{connection.host}:#{connection.port}"
|
96
|
+
rescue StandardError => error
|
97
|
+
nil
|
98
|
+
end
|
91
99
|
end
|
92
100
|
end
|
93
101
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Monkey patch for the sucker_punch class for running async tasks.
|
4
|
+
#
|
5
|
+
|
6
|
+
module StackifyRubyAPM
|
7
|
+
# @api private
|
8
|
+
module Spies
|
9
|
+
# @api private
|
10
|
+
class SuckerPunchSpy
|
11
|
+
def install
|
12
|
+
SuckerPunch::Job::ClassMethods.class_eval do
|
13
|
+
alias_method '__run_perform_without_elastic_apm', '__run_perform'
|
14
|
+
|
15
|
+
def __run_perform(*args)
|
16
|
+
ret = nil
|
17
|
+
begin
|
18
|
+
name = "#{to_s}.perform"
|
19
|
+
ctx = StackifyRubyAPM::Context.new
|
20
|
+
ctx.category = 'SuckerPunch::Job'
|
21
|
+
transaction = StackifyRubyAPM.transaction name, 'TASK', context: ctx
|
22
|
+
ret = __run_perform_without_elastic_apm(*args)
|
23
|
+
rescue StackifyRubyAPM::InternalError
|
24
|
+
raise # Don't report StackifyRubyAPM errors
|
25
|
+
rescue StandardError => e
|
26
|
+
StackifyRubyAPM.report e
|
27
|
+
raise e
|
28
|
+
ensure
|
29
|
+
transaction.submit()
|
30
|
+
end
|
31
|
+
ret
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
register 'SuckerPunch', 'sucker_punch', SuckerPunchSpy.new
|
38
|
+
end
|
39
|
+
end
|
data/lib/stackify_apm/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stackify-ruby-apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.14.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stackify
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -474,6 +474,8 @@ files:
|
|
474
474
|
- lib/stackify_apm/spies/curb/multi.rb
|
475
475
|
- lib/stackify_apm/spies/custom_instrumenter.rb
|
476
476
|
- lib/stackify_apm/spies/delayed_job.rb
|
477
|
+
- lib/stackify_apm/spies/dynamo_db.rb
|
478
|
+
- lib/stackify_apm/spies/faraday.rb
|
477
479
|
- lib/stackify_apm/spies/httparty.rb
|
478
480
|
- lib/stackify_apm/spies/httpclient.rb
|
479
481
|
- lib/stackify_apm/spies/httprb.rb
|
@@ -490,6 +492,7 @@ files:
|
|
490
492
|
- lib/stackify_apm/spies/sinatra_activerecord/postgresql_adapter.rb
|
491
493
|
- lib/stackify_apm/spies/sinatra_activerecord/sqlite_adapter.rb
|
492
494
|
- lib/stackify_apm/spies/stackify_logger.rb
|
495
|
+
- lib/stackify_apm/spies/sucker_punch.rb
|
493
496
|
- lib/stackify_apm/spies/tilt.rb
|
494
497
|
- lib/stackify_apm/spies/yell.rb
|
495
498
|
- lib/stackify_apm/stacktrace.rb
|