stackify-ruby-apm 0.9.0 → 1.0.0
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/Gemfile +18 -0
- data/Gemfile.lock +181 -8
- data/LICENSE.md +66 -0
- data/README.md +5 -3
- data/Rakefile +4 -0
- data/docker-compose.yml +46 -0
- data/lib/stackify/agent.rb +22 -9
- data/lib/stackify/config.rb +65 -29
- data/lib/stackify/context/response.rb +13 -0
- data/lib/stackify/context_builder.rb +0 -2
- data/lib/stackify/error.rb +2 -2
- data/lib/stackify/error_builder.rb +1 -1
- data/lib/stackify/instrumenter.rb +4 -4
- data/lib/stackify/logger/logger_high_version.rb +65 -0
- data/lib/stackify/logger/logger_lower_version.rb +63 -0
- data/lib/stackify/middleware.rb +0 -4
- data/lib/stackify/normalizers.rb +0 -1
- data/lib/stackify/normalizers/active_record.rb +3 -1
- data/lib/stackify/railtie.rb +0 -1
- data/lib/stackify/serializers/errors.rb +8 -7
- data/lib/stackify/serializers/transactions.rb +3 -2
- data/lib/stackify/span.rb +1 -2
- data/lib/stackify/span/context.rb +5 -1
- data/lib/stackify/spies/action_dispatch.rb +8 -1
- data/lib/stackify/spies/httpclient.rb +14 -5
- data/lib/stackify/spies/httprb.rb +45 -0
- data/lib/stackify/spies/mongo.rb +13 -1
- data/lib/stackify/spies/net_http.rb +14 -3
- data/lib/stackify/spies/redis.rb +66 -0
- data/lib/stackify/spies/sinatra.rb +3 -1
- data/lib/stackify/spies/sinatra_activerecord/mysql_adapter.rb +177 -0
- data/lib/stackify/spies/sinatra_activerecord/postgresql_adapter.rb +96 -0
- data/lib/stackify/spies/sinatra_activerecord/sqlite_adapter.rb +48 -0
- data/lib/stackify/spies/tilt.rb +8 -1
- data/lib/stackify/stacktrace_builder.rb +4 -3
- data/lib/stackify/subscriber.rb +4 -4
- data/lib/stackify/trace_logger.rb +6 -23
- data/lib/stackify/transaction.rb +10 -1
- data/lib/stackify/util.rb +0 -13
- data/lib/stackify/version.rb +1 -1
- data/lib/stackify/worker.rb +5 -5
- data/lib/stackify_ruby_apm.rb +2 -6
- data/run-test.sh +75 -0
- data/stackify-ruby-apm.gemspec +0 -1
- metadata +12 -17
- data/lib/stackify/logger.rb +0 -10
@@ -37,11 +37,13 @@ module StackifyRubyAPM
|
|
37
37
|
"oracle"
|
38
38
|
elsif driver.include? "db2"
|
39
39
|
"db2"
|
40
|
+
elsif driver.include? "sqlite"
|
41
|
+
"sqlite"
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
43
45
|
def query_variables(payload)
|
44
|
-
debug "
|
46
|
+
debug "[SqlNormalizer] query_variables payload:"
|
45
47
|
debug payload.inspect
|
46
48
|
|
47
49
|
if payload[:type_casted_binds]
|
data/lib/stackify/railtie.rb
CHANGED
@@ -24,7 +24,6 @@ module StackifyRubyAPM
|
|
24
24
|
# This will overwrite the default values of the config based from stackify_apm.yml initialized
|
25
25
|
|
26
26
|
initializer 'stackify_apm.initialize' do |app|
|
27
|
-
# puts '@stackify_ruby [Railtie] [lib/railtie.rb] initializer'
|
28
27
|
config = app.config.stackify.merge(app: app).tap do |c|
|
29
28
|
# Prepend Rails.root to log_path if present
|
30
29
|
if c.log_path && !c.log_path.start_with?('/')
|
@@ -10,14 +10,15 @@ module StackifyRubyAPM
|
|
10
10
|
def build(error)
|
11
11
|
|
12
12
|
if (exception = error.exception)
|
13
|
+
current_timestamp = error.timestamp
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
base = {
|
16
|
+
CaughtBy: exception.module,
|
17
|
+
Exception: exception.type,
|
18
|
+
Message: exception.message,
|
19
|
+
Timestamp: "#{current_timestamp.round}",
|
20
|
+
Frames: exception.stacktrace.to_a,
|
21
|
+
}
|
21
22
|
|
22
23
|
end
|
23
24
|
|
@@ -17,7 +17,9 @@ module StackifyRubyAPM
|
|
17
17
|
call: transaction.name,
|
18
18
|
reqBegin: transaction.timestamp,
|
19
19
|
reqEnd: transaction.duration,
|
20
|
-
props: RootInfo.build(config, transaction)
|
20
|
+
props: RootInfo.build(config, transaction),
|
21
|
+
exceptions: transaction.exceptions,
|
22
|
+
stacks: []
|
21
23
|
}
|
22
24
|
|
23
25
|
# serialize all the spans
|
@@ -27,7 +29,6 @@ module StackifyRubyAPM
|
|
27
29
|
end
|
28
30
|
|
29
31
|
add_children_spans(root_span_json, children_spans_json)
|
30
|
-
|
31
32
|
root_span_json
|
32
33
|
end
|
33
34
|
|
data/lib/stackify/span.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
#
|
2
|
+
#
|
3
|
+
# Monkey patch for the ActionDispatch::ShowExceptions class which handles exception events.
|
4
|
+
#
|
5
|
+
|
3
6
|
module StackifyRubyAPM
|
4
7
|
# @api private
|
5
8
|
module Spies
|
@@ -10,6 +13,8 @@ module StackifyRubyAPM
|
|
10
13
|
alias render_exception_without_apm render_exception
|
11
14
|
|
12
15
|
def render_exception(env, exception)
|
16
|
+
# Creates exception log report
|
17
|
+
#
|
13
18
|
StackifyRubyAPM.report(exception)
|
14
19
|
render_exception_without_apm env, exception
|
15
20
|
end
|
@@ -17,6 +22,8 @@ module StackifyRubyAPM
|
|
17
22
|
end
|
18
23
|
end
|
19
24
|
|
25
|
+
# Registers ActionDispatch spy, go to: /stackify/spies.rb
|
26
|
+
#
|
20
27
|
register(
|
21
28
|
'ActionDispatch::ShowExceptions',
|
22
29
|
'action_dispatch/show_exception',
|
@@ -1,14 +1,11 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Monkey patch for the HTTPClient class for sending & receiving HTTP responses.
|
2
|
+
#
|
3
3
|
|
4
4
|
module StackifyRubyAPM
|
5
5
|
# @api private
|
6
6
|
module Spies
|
7
7
|
# @api private
|
8
8
|
class HTTPClientSpy
|
9
|
-
include Log
|
10
|
-
|
11
|
-
# This class monkeypatches the HTTPClient class with request method.
|
12
9
|
def install
|
13
10
|
HTTPClient.class_eval do
|
14
11
|
alias request_without_apm request
|
@@ -18,12 +15,20 @@ module StackifyRubyAPM
|
|
18
15
|
unless StackifyRubyAPM.current_transaction
|
19
16
|
return request_without_apm(method, uri, *args, &block)
|
20
17
|
end
|
18
|
+
|
19
|
+
# Data configuration
|
20
|
+
#
|
21
21
|
method = method.upcase
|
22
22
|
uri = uri.strip
|
23
23
|
name = "#{method} #{uri}"
|
24
24
|
type = "ext.httpclient.#{method}"
|
25
25
|
|
26
|
+
# Submits HTTP request
|
27
|
+
#
|
26
28
|
req = request_without_apm(method, uri, *args, &block)
|
29
|
+
|
30
|
+
# Builds span context
|
31
|
+
#
|
27
32
|
ctx = Span::Context.new(
|
28
33
|
CATEGORY: 'Web External',
|
29
34
|
SUBCATEGORY: 'Execute',
|
@@ -32,6 +37,8 @@ module StackifyRubyAPM
|
|
32
37
|
METHOD: method
|
33
38
|
)
|
34
39
|
|
40
|
+
# Creates new span from HTTP result
|
41
|
+
#
|
35
42
|
StackifyRubyAPM.span name, type, context: ctx do
|
36
43
|
req
|
37
44
|
end
|
@@ -42,6 +49,8 @@ module StackifyRubyAPM
|
|
42
49
|
# rubocop:enable Metrics/MethodLength
|
43
50
|
end
|
44
51
|
|
52
|
+
# Registers HTTPClient spy, go to: /stackify/spies.rb
|
53
|
+
#
|
45
54
|
register 'HTTPClient', 'httpclient', HTTPClientSpy.new
|
46
55
|
end
|
47
56
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#
|
2
|
+
# This class monkey patch the http.rb gem with the request method.
|
3
|
+
#
|
4
|
+
module StackifyRubyAPM
|
5
|
+
# @api private
|
6
|
+
module Spies
|
7
|
+
# @api private
|
8
|
+
class HTTPRbSpy
|
9
|
+
|
10
|
+
def install
|
11
|
+
HTTP::Client.class_eval do
|
12
|
+
alias request_without_apm request
|
13
|
+
|
14
|
+
# Make HTTP request
|
15
|
+
def request(verb, uri, opts = {})
|
16
|
+
unless StackifyRubyAPM.current_transaction
|
17
|
+
return request_without_apm(verb, uri, opts = {})
|
18
|
+
end
|
19
|
+
|
20
|
+
method = verb.upcase
|
21
|
+
uri = uri.strip
|
22
|
+
name = "#{method} #{uri}"
|
23
|
+
type = "ext.httprb.#{method}"
|
24
|
+
|
25
|
+
req = request_without_apm(verb, uri, opts = {})
|
26
|
+
ctx = Span::Context.new(
|
27
|
+
CATEGORY: 'Web External',
|
28
|
+
SUBCATEGORY: 'Execute',
|
29
|
+
URL: uri,
|
30
|
+
STATUS: req.code,
|
31
|
+
METHOD: method
|
32
|
+
)
|
33
|
+
|
34
|
+
StackifyRubyAPM.span name, type, context: ctx do
|
35
|
+
req
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
# rubocop:enable Metrics/MethodLength
|
41
|
+
end
|
42
|
+
|
43
|
+
register 'HTTP::Client', 'http/client', HTTPRbSpy.new
|
44
|
+
end
|
45
|
+
end
|
data/lib/stackify/spies/mongo.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
+
# Monkey patch for the Mongo::Monitoring::Global module in mongoDB(http://api.mongodb.com/ruby/current/Mongo/Monitoring/Global.html)
|
2
|
+
# -> Allows subscribing to events for all Mongo clients.
|
3
|
+
#
|
4
|
+
|
1
5
|
module StackifyRubyAPM
|
2
6
|
# @api private
|
3
7
|
module Spies
|
4
8
|
# @api private
|
5
|
-
# This class monkeypatch the Mongo::Monitoring::Global module in mongoDB(http://api.mongodb.com/ruby/current/Mongo/Monitoring/Global.html)
|
6
9
|
class MongoSpy
|
7
10
|
def install
|
8
11
|
::Mongo::Monitoring::Global.subscribe(
|
@@ -36,6 +39,8 @@ module StackifyRubyAPM
|
|
36
39
|
def push_event(event)
|
37
40
|
return unless StackifyRubyAPM.current_transaction
|
38
41
|
|
42
|
+
# Fetches collection name from Mongo event
|
43
|
+
#
|
39
44
|
document = event.command.find
|
40
45
|
col = nil
|
41
46
|
if document
|
@@ -44,10 +49,15 @@ module StackifyRubyAPM
|
|
44
49
|
end
|
45
50
|
end
|
46
51
|
|
52
|
+
# Builds span context
|
53
|
+
#
|
47
54
|
ctx = Span::Context.new(
|
48
55
|
CATEGORY: 'MongoDB',
|
49
56
|
MONGODB_COLLECTION: col,
|
50
57
|
)
|
58
|
+
|
59
|
+
# Creates new span from Mongo event
|
60
|
+
#
|
51
61
|
span = StackifyRubyAPM.span(event.command_name, TYPE, context: ctx)
|
52
62
|
@events[event.operation_id] = span
|
53
63
|
end
|
@@ -61,6 +71,8 @@ module StackifyRubyAPM
|
|
61
71
|
end
|
62
72
|
end
|
63
73
|
|
74
|
+
# Registers Mongo spy, go to: /stackify/spies.rb
|
75
|
+
#
|
64
76
|
register 'Mongo', 'mongo', MongoSpy.new
|
65
77
|
end
|
66
78
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# Monkey patch for the Net::HTTP class for sending & receiving HTTP responses.
|
2
|
+
#
|
3
|
+
|
1
4
|
module StackifyRubyAPM
|
2
5
|
# @api private
|
3
6
|
module Spies
|
4
7
|
# @api private
|
5
8
|
class NetHTTPSpy
|
6
|
-
# This class monkeypatch the Net::HTTP class with request method.
|
7
9
|
def install
|
8
10
|
Net::HTTP.class_eval do
|
9
11
|
alias request_without_apm request
|
@@ -14,6 +16,8 @@ module StackifyRubyAPM
|
|
14
16
|
request_without_apm(req, body, &block)
|
15
17
|
end
|
16
18
|
|
19
|
+
# Data configuration
|
20
|
+
#
|
17
21
|
host, = req['host'] && req['host'].split(':')
|
18
22
|
method = req.method
|
19
23
|
|
@@ -22,16 +26,22 @@ module StackifyRubyAPM
|
|
22
26
|
name = "#{method} #{host}"
|
23
27
|
type = "ext.net_http.#{method}"
|
24
28
|
|
29
|
+
# Submits HTTP request
|
30
|
+
#
|
25
31
|
result = request_without_apm(req, body, &block)
|
26
32
|
|
33
|
+
# Builds span context
|
34
|
+
#
|
27
35
|
ctx = Span::Context.new(
|
28
36
|
CATEGORY: 'Web External',
|
29
37
|
SUBCATEGORY: 'Execute',
|
30
|
-
URL: req.uri,
|
38
|
+
URL: req.uri.nil? ? host : req.uri,
|
31
39
|
STATUS: result.code.to_i,
|
32
40
|
METHOD: method
|
33
41
|
)
|
34
42
|
|
43
|
+
# Creates new span from HTTP result
|
44
|
+
#
|
35
45
|
StackifyRubyAPM.span name, type, context: ctx do
|
36
46
|
return result
|
37
47
|
end
|
@@ -41,7 +51,8 @@ module StackifyRubyAPM
|
|
41
51
|
# rubocop:enable Metrics/MethodLength
|
42
52
|
end
|
43
53
|
|
44
|
-
|
54
|
+
# Registers Net::HTTP spy, go to: /stackify/spies.rb
|
55
|
+
#
|
45
56
|
register 'Net::HTTP', 'net/http', NetHTTPSpy.new
|
46
57
|
end
|
47
58
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Monkey patch for Redis.
|
2
|
+
#
|
3
|
+
|
4
|
+
module StackifyRubyAPM
|
5
|
+
# @api private
|
6
|
+
module Spies
|
7
|
+
# @api private
|
8
|
+
class RedisSpy
|
9
|
+
|
10
|
+
def install
|
11
|
+
::Redis::Client.class_eval do
|
12
|
+
alias call_without_apm call
|
13
|
+
|
14
|
+
def call(command, &block)
|
15
|
+
name = command[0].upcase.to_s
|
16
|
+
type = 'db.redis'
|
17
|
+
redis_details = command[1].is_a?(String) ? command[1].split(":") : []
|
18
|
+
redis_nspace = !redis_details.blank? ? redis_details[0] : ""
|
19
|
+
redis_key = ""
|
20
|
+
|
21
|
+
# Checks CACHEKEY value
|
22
|
+
if !redis_details.blank? && redis_details[1]
|
23
|
+
# Initially sets the CACHEKEY value
|
24
|
+
args = redis_details[1].split("/")
|
25
|
+
redis_key = args[0]
|
26
|
+
|
27
|
+
# If command has passed __method__, it will be included in the CACHEKEY value
|
28
|
+
# Possible formats:
|
29
|
+
# `<namespace:key/method_name/expires_in=300/ttl=60/>`
|
30
|
+
# `<namespace:key/expires_in=300/ttl=60/>`
|
31
|
+
if args.length > 1 && !args[1].include?("=")
|
32
|
+
redis_key = args[0..1].join("/")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
return call_without_apm(command, &block) if command[0] == :auth
|
37
|
+
|
38
|
+
context = {
|
39
|
+
PROVIDER: 'Redis',
|
40
|
+
CATEGORY: 'Cache',
|
41
|
+
SUBCATEGORY: 'Execute',
|
42
|
+
COMPONENT_CATEGORY: 'Cache',
|
43
|
+
COMPONENT_DETAIL: 'Execute',
|
44
|
+
THREAD_ID: Thread.current.object_id,
|
45
|
+
OPERATION: name
|
46
|
+
}.tap do |hash|
|
47
|
+
hash[:CACHEKEY] = redis_key unless redis_key.empty?
|
48
|
+
hash[:CACHENAME] = redis_nspace unless redis_nspace.empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
ctx = Span::Context.new(context)
|
52
|
+
|
53
|
+
StackifyRubyAPM.span name, type, context: ctx do
|
54
|
+
call_without_apm(command, &block)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
# Registers Redis spy, go to: /stackify/spies.rb
|
63
|
+
#
|
64
|
+
register 'Redis', 'redis', RedisSpy.new
|
65
|
+
end
|
66
|
+
end
|
@@ -25,7 +25,7 @@ module StackifyRubyAPM
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
# Tilt engine
|
28
|
+
# Tilt engine template
|
29
29
|
#
|
30
30
|
def compile_template(engine, data, opts, *args, &block)
|
31
31
|
opts[:__stackify_apm_template_name] =
|
@@ -45,6 +45,8 @@ module StackifyRubyAPM
|
|
45
45
|
#
|
46
46
|
register 'Sinatra::Base', 'sinatra/base', SinatraSpy.new
|
47
47
|
|
48
|
+
# Tilt template helper & span creator
|
49
|
+
#
|
48
50
|
require 'stackify/spies/tilt'
|
49
51
|
end
|
50
52
|
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Spies for active record when sinatra framework is used and active_record is being extended. (mysql adapter)
|
3
|
+
#
|
4
|
+
module StackifyRubyAPM
|
5
|
+
# @api private
|
6
|
+
module Spies
|
7
|
+
# @api private
|
8
|
+
class MysqlAdapterSpy
|
9
|
+
TYPE = 'db.sinatra_active_record.sql'.freeze
|
10
|
+
if ActiveRecord::VERSION::MAJOR.to_i >= 5
|
11
|
+
# rubocop:disable Metrics/MethodLength
|
12
|
+
def install
|
13
|
+
ActiveRecord::ConnectionAdapters::MySQL::DatabaseStatements.class_eval do
|
14
|
+
alias exec_query_without_apm exec_query
|
15
|
+
alias exec_delete_without_apm exec_delete
|
16
|
+
alias exec_update_without_apm exec_update
|
17
|
+
|
18
|
+
def exec_update(sql, name = nil, binds = [])
|
19
|
+
result = nil
|
20
|
+
unless StackifyRubyAPM.current_transaction
|
21
|
+
exec_update_without_apm(sql, name, binds)
|
22
|
+
end
|
23
|
+
|
24
|
+
ctx = Span::Context.new(
|
25
|
+
CATEGORY: 'Database',
|
26
|
+
SUBCATEGORY: 'Execute',
|
27
|
+
COMPONENT_CATEGORY: 'DB Query',
|
28
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
29
|
+
SQL: sql,
|
30
|
+
PROVIDER: "mysql"
|
31
|
+
)
|
32
|
+
result = exec_update_without_apm(sql, name, binds)
|
33
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
34
|
+
return result
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def exec_delete(sql, name = nil, binds = [])
|
39
|
+
result = nil
|
40
|
+
unless StackifyRubyAPM.current_transaction
|
41
|
+
exec_delete_without_apm(sql, name, binds)
|
42
|
+
end
|
43
|
+
|
44
|
+
ctx = Span::Context.new(
|
45
|
+
CATEGORY: 'Database',
|
46
|
+
SUBCATEGORY: 'Execute',
|
47
|
+
COMPONENT_CATEGORY: 'DB Query',
|
48
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
49
|
+
SQL: sql,
|
50
|
+
PROVIDER: "mysql"
|
51
|
+
)
|
52
|
+
|
53
|
+
result = exec_delete_without_apm(sql, name, binds)
|
54
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
55
|
+
return result
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def exec_query(sql, name = "SQL", binds = [], prepare: false)
|
60
|
+
result = nil
|
61
|
+
unless StackifyRubyAPM.current_transaction
|
62
|
+
exec_query_without_apm(sql, name, binds)
|
63
|
+
end
|
64
|
+
|
65
|
+
ctx = Span::Context.new(
|
66
|
+
CATEGORY: 'Database',
|
67
|
+
SUBCATEGORY: 'Execute',
|
68
|
+
COMPONENT_CATEGORY: 'DB Query',
|
69
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
70
|
+
SQL: sql,
|
71
|
+
PROVIDER: "mysql"
|
72
|
+
)
|
73
|
+
|
74
|
+
result = exec_query_without_apm(sql, name, binds)
|
75
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
76
|
+
return result
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
# rubocop:enable Metrics/MethodLength
|
82
|
+
else
|
83
|
+
# rubocop:disable Metrics/MethodLength
|
84
|
+
def install
|
85
|
+
ActiveRecord::ConnectionAdapters::Mysql2Adapter.class_eval do
|
86
|
+
alias exec_query_without_apm exec_query
|
87
|
+
alias exec_delete_without_apm exec_delete
|
88
|
+
alias exec_update_without_apm exec_update
|
89
|
+
alias exec_insert_without_apm exec_insert
|
90
|
+
|
91
|
+
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
|
92
|
+
result = nil
|
93
|
+
unless StackifyRubyAPM.current_transaction
|
94
|
+
exec_insert_without_apm(sql, name, binds, pk = nil, sequence_name = nil)
|
95
|
+
end
|
96
|
+
ctx = Span::Context.new(
|
97
|
+
CATEGORY: 'Database',
|
98
|
+
SUBCATEGORY: 'Execute',
|
99
|
+
COMPONENT_CATEGORY: 'DB Query',
|
100
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
101
|
+
SQL: sql,
|
102
|
+
PROVIDER: "mysql"
|
103
|
+
)
|
104
|
+
result = exec_insert_without_apm(sql, name, binds, pk = nil, sequence_name = nil)
|
105
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
106
|
+
return result
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def exec_update(sql, name, binds)
|
111
|
+
result = nil
|
112
|
+
unless StackifyRubyAPM.current_transaction
|
113
|
+
exec_update_without_apm(sql, name, binds)
|
114
|
+
end
|
115
|
+
ctx = Span::Context.new(
|
116
|
+
CATEGORY: 'Database',
|
117
|
+
SUBCATEGORY: 'Execute',
|
118
|
+
COMPONENT_CATEGORY: 'DB Query',
|
119
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
120
|
+
SQL: sql,
|
121
|
+
PROVIDER: "mysql"
|
122
|
+
)
|
123
|
+
result = exec_update_without_apm(sql, name, binds)
|
124
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
125
|
+
return result
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def exec_delete(sql, name, binds)
|
130
|
+
result = nil
|
131
|
+
unless StackifyRubyAPM.current_transaction
|
132
|
+
exec_delete_without_apm(sql, name, binds)
|
133
|
+
end
|
134
|
+
ctx = Span::Context.new(
|
135
|
+
CATEGORY: 'Database',
|
136
|
+
SUBCATEGORY: 'Execute',
|
137
|
+
COMPONENT_CATEGORY: 'DB Query',
|
138
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
139
|
+
SQL: sql,
|
140
|
+
PROVIDER: "mysql"
|
141
|
+
)
|
142
|
+
result = exec_delete_without_apm(sql, name, binds)
|
143
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
144
|
+
return result
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def exec_query(sql, name = "SQL", binds = [], prepare: false)
|
149
|
+
result = nil
|
150
|
+
unless StackifyRubyAPM.current_transaction
|
151
|
+
exec_query_without_apm(sql, name, binds)
|
152
|
+
end
|
153
|
+
ctx = Span::Context.new(
|
154
|
+
CATEGORY: 'Database',
|
155
|
+
SUBCATEGORY: 'Execute',
|
156
|
+
COMPONENT_CATEGORY: 'DB Query',
|
157
|
+
COMPONENT_DETAIL: 'Execute SQL Query',
|
158
|
+
SQL: sql,
|
159
|
+
PROVIDER: "mysql"
|
160
|
+
)
|
161
|
+
result = exec_query_without_apm(sql, name, binds)
|
162
|
+
StackifyRubyAPM.span name, TYPE, context: ctx do
|
163
|
+
return result
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
# rubocop:enable Metrics/MethodLength
|
169
|
+
end
|
170
|
+
end
|
171
|
+
if ActiveRecord::VERSION::MAJOR.to_i >= 5
|
172
|
+
register 'ActiveRecord::ConnectionAdapters::MySQL::DatabaseStatements', 'active_record/connection_adapters/mysql/database_statements', MysqlAdapterSpy.new
|
173
|
+
else
|
174
|
+
register 'ActiveRecord::ConnectionAdapters::Mysql2Adapter', 'active_record/connection_adapters/mysql2_adapter', MysqlAdapterSpy.new
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|