stackify-ruby-apm 1.0.1 → 1.1.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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +38 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +17 -11
  5. data/Gemfile.lock +98 -95
  6. data/Rakefile +7 -5
  7. data/docker/stackify-ruby +8 -0
  8. data/docker/stackify-ruby-rvm +10 -0
  9. data/docker/stackify-ruby-test +28 -0
  10. data/lib/{stackify → stackify_apm}/agent.rb +42 -33
  11. data/lib/{stackify → stackify_apm}/config.rb +56 -39
  12. data/lib/{stackify → stackify_apm}/context.rb +5 -6
  13. data/lib/{stackify → stackify_apm}/context/request.rb +0 -0
  14. data/lib/{stackify → stackify_apm}/context/request/socket.rb +0 -0
  15. data/lib/{stackify → stackify_apm}/context/request/url.rb +2 -6
  16. data/lib/stackify_apm/context/response.rb +33 -0
  17. data/lib/{stackify → stackify_apm}/context_builder.rb +2 -5
  18. data/lib/{stackify → stackify_apm}/error.rb +7 -6
  19. data/lib/stackify_apm/error/exception.rb +37 -0
  20. data/lib/stackify_apm/error/log.rb +24 -0
  21. data/lib/stackify_apm/error_builder.rb +61 -0
  22. data/lib/stackify_apm/helper/database_helper.rb +27 -0
  23. data/lib/{stackify → stackify_apm}/instrumenter.rb +12 -19
  24. data/lib/{stackify → stackify_apm}/internal_error.rb +0 -0
  25. data/lib/{stackify → stackify_apm}/log.rb +0 -0
  26. data/lib/{stackify → stackify_apm}/logger/log_device.rb +22 -11
  27. data/lib/{stackify → stackify_apm}/logger/logger_high_version.rb +1 -6
  28. data/lib/{stackify → stackify_apm}/logger/logger_lower_version.rb +2 -1
  29. data/lib/stackify_apm/middleware.rb +70 -0
  30. data/lib/{stackify → stackify_apm}/naively_hashable.rb +1 -3
  31. data/lib/{stackify → stackify_apm}/normalizers.rb +3 -2
  32. data/lib/{stackify → stackify_apm}/normalizers/action_controller.rb +0 -0
  33. data/lib/{stackify → stackify_apm}/normalizers/action_mailer.rb +0 -0
  34. data/lib/{stackify → stackify_apm}/normalizers/action_view.rb +0 -0
  35. data/lib/{stackify → stackify_apm}/normalizers/active_record.rb +3 -25
  36. data/lib/{stackify → stackify_apm}/railtie.rb +5 -7
  37. data/lib/{stackify → stackify_apm}/root_info.rb +2 -6
  38. data/lib/{stackify → stackify_apm}/serializers.rb +3 -2
  39. data/lib/{stackify → stackify_apm}/serializers/errors.rb +7 -10
  40. data/lib/{stackify → stackify_apm}/serializers/transactions.rb +11 -18
  41. data/lib/{stackify → stackify_apm}/span.rb +8 -9
  42. data/lib/{stackify → stackify_apm}/span/context.rb +3 -1
  43. data/lib/{stackify → stackify_apm}/spies.rb +3 -2
  44. data/lib/{stackify → stackify_apm}/spies/action_dispatch.rb +3 -4
  45. data/lib/stackify_apm/spies/curb.rb +49 -0
  46. data/lib/stackify_apm/spies/curb/easy.rb +157 -0
  47. data/lib/stackify_apm/spies/curb/multi.rb +43 -0
  48. data/lib/{stackify → stackify_apm}/spies/httpclient.rb +10 -8
  49. data/lib/{stackify → stackify_apm}/spies/httprb.rb +7 -9
  50. data/lib/{stackify → stackify_apm}/spies/mongo.rb +5 -3
  51. data/lib/{stackify → stackify_apm}/spies/net_http.rb +4 -5
  52. data/lib/{stackify → stackify_apm}/spies/redis.rb +19 -18
  53. data/lib/stackify_apm/spies/sequel.rb +65 -0
  54. data/lib/{stackify → stackify_apm}/spies/sinatra.rb +7 -10
  55. data/lib/stackify_apm/spies/sinatra_activerecord/mysql_adapter.rb +201 -0
  56. data/lib/stackify_apm/spies/sinatra_activerecord/postgresql_adapter.rb +94 -0
  57. data/lib/stackify_apm/spies/sinatra_activerecord/sqlite_adapter.rb +46 -0
  58. data/lib/stackify_apm/spies/stackify_logger.rb +60 -0
  59. data/lib/{stackify → stackify_apm}/spies/tilt.rb +3 -3
  60. data/lib/stackify_apm/stacktrace.rb +18 -0
  61. data/lib/stackify_apm/stacktrace/frame.rb +47 -0
  62. data/lib/{stackify → stackify_apm}/stacktrace_builder.rb +10 -11
  63. data/lib/{stackify → stackify_apm}/subscriber.rb +20 -14
  64. data/lib/{stackify → stackify_apm}/trace_logger.rb +10 -16
  65. data/lib/stackify_apm/transaction.rb +127 -0
  66. data/lib/{stackify → stackify_apm}/util.rb +3 -1
  67. data/lib/{stackify → stackify_apm}/util/dig.rb +1 -1
  68. data/lib/{stackify → stackify_apm}/util/inflector.rb +0 -0
  69. data/lib/{stackify → stackify_apm}/util/inspector.rb +1 -3
  70. data/lib/stackify_apm/util/lru_cache.rb +49 -0
  71. data/lib/stackify_apm/util/trace_log_watcher.rb +37 -0
  72. data/lib/stackify_apm/version.rb +6 -0
  73. data/lib/{stackify → stackify_apm}/worker.rb +8 -7
  74. data/lib/stackify_ruby_apm.rb +18 -15
  75. data/run-test-docker.sh +50 -0
  76. data/run-test.sh +1 -3
  77. data/stackify-ruby-apm.gemspec +14 -11
  78. metadata +86 -59
  79. data/lib/stackify/context/response.rb +0 -37
  80. data/lib/stackify/error/exception.rb +0 -36
  81. data/lib/stackify/error/log.rb +0 -25
  82. data/lib/stackify/error_builder.rb +0 -65
  83. data/lib/stackify/middleware.rb +0 -74
  84. data/lib/stackify/spies/sinatra_activerecord/mysql_adapter.rb +0 -177
  85. data/lib/stackify/spies/sinatra_activerecord/postgresql_adapter.rb +0 -96
  86. data/lib/stackify/spies/sinatra_activerecord/sqlite_adapter.rb +0 -48
  87. data/lib/stackify/stacktrace.rb +0 -19
  88. data/lib/stackify/stacktrace/frame.rb +0 -50
  89. data/lib/stackify/transaction.rb +0 -132
  90. data/lib/stackify/util/lru_cache.rb +0 -49
  91. data/lib/stackify/version.rb +0 -4
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Monkey patch for the CurbSpy class for sending & receiving Curb responses.
4
+ #
5
+ module StackifyRubyAPM
6
+ # @api private
7
+ module Spies
8
+ # @api private
9
+ class CurbEasySpy
10
+ attr_accessor :_apm_http_verb
11
+ def install
12
+ Curl::Easy.class_eval do
13
+ singleton_class.send(:alias_method, :perform_without_apm, :perform)
14
+ singleton_class.send(:alias_method, :http_head_without_apm, :http_head)
15
+ singleton_class.send(:alias_method, :http_post_without_apm, :http_post)
16
+ singleton_class.send(:alias_method, :http_put_without_apm, :http_put)
17
+ singleton_class.send(:alias_method, :http_get_without_apm, :http_get)
18
+ singleton_class.send(:alias_method, :http_delete_without_apm, :http_delete)
19
+ def self.perform(*args)
20
+ req = nil
21
+ return perform_without_apm(*args) unless StackifyRubyAPM.current_transaction
22
+ # Data configuration
23
+ @_apm_http_verb ||= :GET
24
+ method = @_apm_http_verb
25
+ uri = args[0].strip
26
+ name = "#{method} #{uri}"
27
+ type = "ext.Curb.Easy.#{method}"
28
+ # Submits HTTP request
29
+ #
30
+ req = perform_without_apm(*args)
31
+ # Builds span context
32
+ #
33
+ status_code = req.status.gsub(/^0-9/, '').to_i
34
+ ctx = Span::Context.new(
35
+ CATEGORY: 'Web External',
36
+ SUBCATEGORY: 'Execute',
37
+ URL: uri,
38
+ STATUS: status_code,
39
+ METHOD: method
40
+ )
41
+ # Creates new span from HTTP result
42
+ StackifyRubyAPM.span name, type, context: ctx do
43
+ req
44
+ end
45
+ end
46
+
47
+ def self.http_post(*args)
48
+ req = nil
49
+ return http_post_without_apm(*args) unless StackifyRubyAPM.current_transaction
50
+ # Data configuration
51
+ #
52
+ @_apm_http_verb = :POST
53
+ method = @_apm_http_verb
54
+ uri = args[0].strip
55
+ name = "#{method} #{uri}"
56
+ type = "ext.Curb.Easy.#{method}"
57
+ req = http_post_without_apm(*args)
58
+ status_code = req.status.gsub(/^0-9/, '').to_i
59
+
60
+ ctx = Span::Context.new(
61
+ CATEGORY: 'Web External',
62
+ SUBCATEGORY: 'Execute',
63
+ URL: uri,
64
+ STATUS: status_code,
65
+ METHOD: method
66
+ )
67
+ # Creates new span from HTTP result
68
+ StackifyRubyAPM.span name, type, context: ctx do
69
+ req
70
+ end
71
+ end
72
+
73
+ def self.http_put(url, data)
74
+ req = nil
75
+ return http_put_without_apm(url, data) unless StackifyRubyAPM.current_transaction
76
+ # Data configuration
77
+ #
78
+ @_apm_http_verb = :PUT
79
+ method = @_apm_http_verb
80
+ uri = url.strip
81
+ name = "#{method} #{uri}"
82
+ type = "ext.Curb.Easy.#{method}"
83
+ req = http_put_without_apm(url, data)
84
+ status_code = req.status.gsub(/^0-9/, '').to_i
85
+
86
+ ctx = Span::Context.new(
87
+ CATEGORY: 'Web External',
88
+ SUBCATEGORY: 'Execute',
89
+ URL: uri,
90
+ STATUS: status_code,
91
+ METHOD: method
92
+ )
93
+ # Creates new span from HTTP result
94
+ StackifyRubyAPM.span name, type, context: ctx do
95
+ req
96
+ end
97
+ end
98
+
99
+ def self.http_get(*args)
100
+ req = nil
101
+ return http_get_without_apm(*args) unless StackifyRubyAPM.current_transaction
102
+ # Data configuration
103
+ #
104
+ @_apm_http_verb = :GET
105
+ method = @_apm_http_verb
106
+ uri = args[0].strip
107
+ name = "#{method} #{uri}"
108
+ type = "ext.Curb.Easy.#{method}"
109
+ req = http_get_without_apm(*args)
110
+ status_code = req.status.gsub(/^0-9/, '').to_i
111
+
112
+ ctx = Span::Context.new(
113
+ CATEGORY: 'Web External',
114
+ SUBCATEGORY: 'Execute',
115
+ URL: uri,
116
+ STATUS: status_code,
117
+ METHOD: method
118
+ )
119
+ # Creates new span from HTTP result
120
+ StackifyRubyAPM.span name, type, context: ctx do
121
+ req
122
+ end
123
+ end
124
+
125
+ def self.http_delete(*args)
126
+ req = nil
127
+ return http_delete_without_apm(*args) unless StackifyRubyAPM.current_transaction
128
+ # Data configuration
129
+ #
130
+ @_apm_http_verb = :DELETE
131
+ method = @_apm_http_verb
132
+ uri = args[0].strip
133
+ name = "#{method} #{uri}"
134
+ type = "ext.Curb.Easy.#{method}"
135
+ req = http_delete_without_apm(*args)
136
+ status_code = req.status.gsub(/^0-9/, '').to_i
137
+
138
+ ctx = Span::Context.new(
139
+ CATEGORY: 'Web External',
140
+ SUBCATEGORY: 'Execute',
141
+ URL: uri,
142
+ STATUS: status_code,
143
+ METHOD: method
144
+ )
145
+ # Creates new span from HTTP result
146
+ StackifyRubyAPM.span name, type, context: ctx do
147
+ req
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+ # Registers CurbSpy spy, go to: /stackify/spies.rb
154
+ #
155
+ register 'Curl::Easy', 'curl/easy', CurbEasySpy.new
156
+ end
157
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Monkey patch for the CurbSpy class for sending & receiving Curb responses.
4
+ #
5
+ module StackifyRubyAPM
6
+ # @api private
7
+ module Spies
8
+ # @api private
9
+ class CurbMultiSpy
10
+ def install
11
+ Curl::Multi.class_eval do
12
+ singleton_class.send(:alias_method, :http_without_apm, :http)
13
+
14
+ def self.http(urls_with_config, _multi_options = {}, &blk)
15
+ return http_without_apm(urls_with_config, _multi_options = {}, &blk) unless StackifyRubyAPM.current_transaction
16
+ http_without_apm(urls_with_config, _multi_options = {}) do |c, code, method|
17
+ status_code = code.zero? ? 404 : code
18
+ method = method.upcase
19
+ uri = c.url.to_s.strip
20
+ name = "#{method} #{uri}"
21
+ type = "ext.Curb.Multi.#{method}"
22
+
23
+ ctx = Span::Context.new(
24
+ CATEGORY: 'Web External',
25
+ SUBCATEGORY: 'Execute',
26
+ URL: uri,
27
+ STATUS: status_code,
28
+ METHOD: method
29
+ )
30
+ # Creates new span from HTTP result
31
+ StackifyRubyAPM.span name, type, context: ctx do
32
+ blk.call(c, code, method)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ # Registers CurbSpy spy, go to: /stackify/spies.rb
40
+ #
41
+ register 'Curl::Multi', 'curl/multi', CurbMultiSpy.new
42
+ end
43
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Monkey patch for the HTTPClient class for sending & receiving HTTP responses.
2
4
  #
3
5
 
@@ -8,13 +10,15 @@ module StackifyRubyAPM
8
10
  class HTTPClientSpy
9
11
  def install
10
12
  HTTPClient.class_eval do
11
- alias request_without_apm request
13
+ alias_method 'request_without_apm', 'request'
12
14
 
13
15
  def request(method, uri, *args, &block)
14
16
  req = nil
15
- unless StackifyRubyAPM.current_transaction
16
- return request_without_apm(method, uri, *args, &block)
17
- end
17
+ return request_without_apm(method, uri, *args, &block) unless StackifyRubyAPM.current_transaction
18
+
19
+ # unless StackifyRubyAPM.current_transaction
20
+ # return request_without_apm(method, uri, *args, &block)
21
+ # end
18
22
 
19
23
  # Data configuration
20
24
  #
@@ -42,15 +46,13 @@ module StackifyRubyAPM
42
46
  StackifyRubyAPM.span name, type, context: ctx do
43
47
  req
44
48
  end
45
-
46
49
  end
47
50
  end
48
51
  end
49
- # rubocop:enable Metrics/MethodLength
50
52
  end
51
53
 
52
- # Registers HTTPClient spy, go to: /stackify/spies.rb
54
+ # Registers HTTPClient spy, go to: /stackify_apm/spies.rb
53
55
  #
54
56
  register 'HTTPClient', 'httpclient', HTTPClientSpy.new
55
57
  end
56
- end
58
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # This class monkey patch the http.rb gem with the request method.
3
5
  #
@@ -6,23 +8,20 @@ module StackifyRubyAPM
6
8
  module Spies
7
9
  # @api private
8
10
  class HTTPRbSpy
9
-
10
11
  def install
11
12
  HTTP::Client.class_eval do
12
- alias request_without_apm request
13
+ alias_method 'request_without_apm', 'request'
13
14
 
14
15
  # Make HTTP request
15
- def request(verb, uri, opts = {})
16
- unless StackifyRubyAPM.current_transaction
17
- return request_without_apm(verb, uri, opts = {})
18
- end
16
+ def request(verb, uri, _opts = {})
17
+ return request_without_apm(verb, uri, _opts = {}) unless StackifyRubyAPM.current_transaction
19
18
 
20
19
  method = verb.upcase
21
20
  uri = uri.strip
22
21
  name = "#{method} #{uri}"
23
22
  type = "ext.httprb.#{method}"
24
23
 
25
- req = request_without_apm(verb, uri, opts = {})
24
+ req = request_without_apm(verb, uri, _opts = {})
26
25
  ctx = Span::Context.new(
27
26
  CATEGORY: 'Web External',
28
27
  SUBCATEGORY: 'Execute',
@@ -37,9 +36,8 @@ module StackifyRubyAPM
37
36
  end
38
37
  end
39
38
  end
40
- # rubocop:enable Metrics/MethodLength
41
39
  end
42
40
 
43
41
  register 'HTTP::Client', 'http/client', HTTPRbSpy.new
44
42
  end
45
- end
43
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Monkey patch for the Mongo::Monitoring::Global module in mongoDB(http://api.mongodb.com/ruby/current/Mongo/Monitoring/Global.html)
2
4
  # -> Allows subscribing to events for all Mongo clients.
3
5
  #
@@ -45,7 +47,7 @@ module StackifyRubyAPM
45
47
  col = nil
46
48
  if document
47
49
  document.each_with_index do |val, idx|
48
- col = val[1] if idx == 0
50
+ col = val[1] if idx.zero?
49
51
  end
50
52
  end
51
53
 
@@ -53,7 +55,7 @@ module StackifyRubyAPM
53
55
  #
54
56
  ctx = Span::Context.new(
55
57
  CATEGORY: 'MongoDB',
56
- MONGODB_COLLECTION: col,
58
+ MONGODB_COLLECTION: col
57
59
  )
58
60
 
59
61
  # Creates new span from Mongo event
@@ -71,7 +73,7 @@ module StackifyRubyAPM
71
73
  end
72
74
  end
73
75
 
74
- # Registers Mongo spy, go to: /stackify/spies.rb
76
+ # Registers Mongo spy, go to: /stackify_apm/spies.rb
75
77
  #
76
78
  register 'Mongo', 'mongo', MongoSpy.new
77
79
  end
@@ -1,5 +1,4 @@
1
1
  # Monkey patch for the Net::HTTP class for sending & receiving HTTP responses.
2
- #
3
2
 
4
3
  module StackifyRubyAPM
5
4
  # @api private
@@ -8,7 +7,7 @@ module StackifyRubyAPM
8
7
  class NetHTTPSpy
9
8
  def install
10
9
  Net::HTTP.class_eval do
11
- alias request_without_apm request
10
+ alias_method 'request_without_apm', 'request'
12
11
 
13
12
  def request(req, body = nil, &block)
14
13
  result = nil
@@ -50,9 +49,9 @@ module StackifyRubyAPM
50
49
  end
51
50
  # rubocop:enable Metrics/MethodLength
52
51
  end
53
-
54
- # Registers Net::HTTP spy, go to: /stackify/spies.rb
52
+
53
+ # Registers Net::HTTP spy, go to: /stackify_apm/spies.rb
55
54
  #
56
55
  register 'Net::HTTP', 'net/http', NetHTTPSpy.new
57
56
  end
58
- end
57
+ end
@@ -1,36 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Monkey patch for Redis.
2
4
  #
3
-
4
5
  module StackifyRubyAPM
5
6
  # @api private
6
7
  module Spies
7
8
  # @api private
8
9
  class RedisSpy
9
-
10
+ # rubocop:disable Metrics/CyclomaticComplexity
11
+ # rubocop:disable Metrics/PerceivedComplexity
10
12
  def install
11
13
  ::Redis::Client.class_eval do
12
- alias call_without_apm call
13
-
14
+ alias_method 'call_without_apm', 'call'
15
+
14
16
  def call(command, &block)
15
17
  name = command[0].upcase.to_s
16
18
  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
-
19
+ redis_details = command[1].is_a?(String) ? command[1].split(':') : []
20
+ redis_nspace = !redis_details.blank? ? redis_details[0] : ''
21
+ redis_key = ''
22
+
21
23
  # Checks CACHEKEY value
22
24
  if !redis_details.blank? && redis_details[1]
23
25
  # Initially sets the CACHEKEY value
24
- args = redis_details[1].split("/")
26
+ args = redis_details[1].split('/')
25
27
  redis_key = args[0]
26
28
 
27
29
  # If command has passed __method__, it will be included in the CACHEKEY value
28
30
  # Possible formats:
29
- # `<namespace:key/method_name/expires_in=300/ttl=60/>`
31
+ # `<namespace:key/method_name/expires_in=300/ttl=60/>`
30
32
  # `<namespace:key/expires_in=300/ttl=60/>`
31
- if args.length > 1 && !args[1].include?("=")
32
- redis_key = args[0..1].join("/")
33
- end
33
+ redis_key = args[0..1].join('/') if args.length > 1 && !args[1].include?('=')
34
34
  end
35
35
 
36
36
  return call_without_apm(command, &block) if command[0] == :auth
@@ -43,24 +43,25 @@ module StackifyRubyAPM
43
43
  COMPONENT_DETAIL: 'Execute',
44
44
  THREAD_ID: Thread.current.object_id,
45
45
  OPERATION: name
46
- }.tap do |hash|
46
+ }.tap do |hash|
47
47
  hash[:CACHEKEY] = redis_key unless redis_key.empty?
48
48
  hash[:CACHENAME] = redis_nspace unless redis_nspace.empty?
49
49
  end
50
50
 
51
51
  ctx = Span::Context.new(context)
52
-
52
+
53
53
  StackifyRubyAPM.span name, type, context: ctx do
54
54
  call_without_apm(command, &block)
55
55
  end
56
56
  end
57
57
  end
58
58
  end
59
-
59
+ # rubocop:enable Metrics/PerceivedComplexity
60
+ # rubocop:enable Metrics/CyclomaticComplexity
60
61
  end
61
62
 
62
- # Registers Redis spy, go to: /stackify/spies.rb
63
+ # Registers Redis spy, go to: /stackify_apm/spies.rb
63
64
  #
64
65
  register 'Redis', 'redis', RedisSpy.new
65
66
  end
66
- end
67
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # This class monkey patch the sequel.rb gem with the request method.
5
+ #
6
+ module StackifyRubyAPM
7
+ # @api private
8
+ module Spies
9
+ # @api private
10
+ class SequelSpy
11
+ DEFAULT = 'SQL'.freeze
12
+ TYPE = 'db.sequel.sql'.freeze
13
+ TABLE_REGEX = %{["'`]?([A-Za-z0-9]+)}.freeze
14
+ REGEXES = {
15
+ /^BEGIN/i => 'BEGIN',
16
+ /^COMMIT/i => 'COMMIT',
17
+ /^SELECT .* FROM #{TABLE_REGEX}/i => 'SELECT FROM ',
18
+ /^INSERT INTO #{TABLE_REGEX}/i => 'INSERT INTO ',
19
+ /^UPDATE #{TABLE_REGEX}/i => 'UPDATE ',
20
+ /^DELETE FROM #{TABLE_REGEX}/i => 'DELETE FROM '
21
+ }.freeze
22
+ FORMAT = '%s%s'.freeze
23
+
24
+ def install
25
+ require 'sequel/database/logging'
26
+
27
+ ::Sequel::Database.class_eval do
28
+ alias_method 'log_connection_yield_without_apm', 'log_connection_yield'
29
+
30
+ def log_connection_yield(sql, *args, &block)
31
+ return log_connection_yield_without_apm(sql, *args, &block) unless StackifyRubyAPM.current_transaction
32
+
33
+ name = summarize sql
34
+ db_adapter = ''
35
+ db_adapter = args[0].class.to_s.gsub('::Database', '').downcase if args[0]
36
+
37
+ context = Span::Context.new(
38
+ CATEGORY: 'Database',
39
+ SUBCATEGORY: 'Execute',
40
+ COMPONENT_CATEGORY: 'DB Query',
41
+ COMPONENT_DETAIL: 'Execute SQL Query',
42
+ SQL: sql,
43
+ PROVIDER: get_profiler(db_adapter)
44
+ )
45
+
46
+ StackifyRubyAPM.span(name, TYPE, context: context, &block)
47
+ end
48
+
49
+ # rubocop:disable Lint/UselessAssignment
50
+ def summarize(sql)
51
+ current_sql ||=
52
+ REGEXES.find do |regex, sig|
53
+ if (match = sql.match(regex))
54
+ break format(FORMAT, sig, match[1] && match[1].gsub(/["']/, ''))
55
+ end
56
+ end || DEFAULT
57
+ end
58
+ require 'stackify_apm/helper/database_helper'
59
+ end
60
+ # rubocop:enable Lint/UselessAssignment
61
+ end
62
+ end
63
+ register 'Sequel', 'sequel', SequelSpy.new
64
+ end
65
+ end