stackify-ruby-apm 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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