stackify-ruby-apm 1.12.3 → 1.13.2
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/config.rb +4 -1
- data/lib/stackify_apm/helper/database_helper.rb +6 -5
- 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 +50 -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/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: 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/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
|
@@ -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,50 @@
|
|
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
|
+
)
|
29
|
+
rescue Exception => e
|
30
|
+
StackifyRubyAPM.agent.error "[DynamoDBSpy] Error: creating span context."
|
31
|
+
StackifyRubyAPM.agent.error "[DynamoDBSpy] #{e.inspect}"
|
32
|
+
return original_method.call(params, options)
|
33
|
+
end
|
34
|
+
|
35
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
36
|
+
result = original_method.call(params, options)
|
37
|
+
return result
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
# rubocop:enable Metrics/MethodLength
|
44
|
+
end
|
45
|
+
|
46
|
+
# Registers Aws::DynamoDB::Client spy, go to: /stackify_apm/spies.rb
|
47
|
+
#
|
48
|
+
register 'Aws::DynamoDB::Client', 'aws-sdk-dynamodb', DynamoDBSpy.new
|
49
|
+
end
|
50
|
+
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
|
@@ -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.13.2
|
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-09-01 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
|