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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ec496ca2f97d6531e0e5059845fb078d60e194f0b2896a5148cc570f8de66c13
4
- data.tar.gz: 5dbc4a02c01e54b3d1276932f5d7528da2751d734a15926517595528b00dd0a8
3
+ metadata.gz: 5d95a01fea8c43d40a4cf1f0f541f539e31d9e022d985e70096d3b01260cbab8
4
+ data.tar.gz: c4a871133a02ba479ceea744f9f868ab34910c291e947fe62cc644330f6935c0
5
5
  SHA512:
6
- metadata.gz: 76c13b39665912b23fa8bd42cb75af0cfa455e83735814f167c768f380b96f411f4267670b8708f15d0aa6de9698d58055fba04ba6f8286dfb1efe51fb724361
7
- data.tar.gz: 2aa04cf139250db11e987a38ad213863a0d4dab9427561a1a2f63240a42005b37ab1dd9e8ae62df54159d6a05f9d7039df116fa41eea71f00ed69adfc173ebc3
6
+ metadata.gz: d4ca5f2806b494bc98ecb9828a01dbb3e459328401c8a880a4239d0ff8ad16073ace3a7e52ec02fb93b633f14f1b6493dd46daa381ee0ef7fc9ac23a1a319cdb
7
+ data.tar.gz: 873b62a9ef92ef3ea222ea7ed2fbfff26e41b2114ea030ac668646db394e0093feab0588d08e390776fcc38b8d6ff152cf6df1d472b886be0f102a71f5d0ab90
@@ -214,7 +214,10 @@ module StackifyRubyAPM
214
214
  httparty
215
215
  stackify_logger
216
216
  sidekiq
217
- delayed_job
217
+ delayed_job
218
+ faraday
219
+ sucker_punch
220
+ dynamo_db
218
221
  ]
219
222
  end
220
223
 
@@ -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 SQL_PARAMETERS to the existing object properties.
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[:SQL_PARAMETERS] = sqlParam.to_json if sqlParam.count > 0
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[:RESPONSE_BODY] = @transaction.context.prefix.response_body.to_s if @transaction.context.prefix && @transaction.context.prefix.response_body
51
- hash[:RESPONSE_SIZE_BYTES] = @transaction.context.prefix.response_body.length.to_s if @transaction.context.prefix && @transaction.context.prefix.response_body
52
- hash[:RESPONSE_HEADERS] = @transaction.context.prefix.response_headers.to_s if @transaction.context.prefix && @transaction.context.prefix.response_headers
53
- hash[:REQUEST_BODY] = @transaction.context.prefix.request_body.to_s if @transaction.context.prefix && @transaction.context.prefix.request_body
54
- hash[:REQUEST_SIZE_BYTES] = @transaction.context.prefix.request_body.length.to_s if @transaction.context.prefix && @transaction.context.prefix.request_body
55
- hash[:REQUEST_HEADERS] = @transaction.context.prefix.request_headers.to_s if @transaction.context.prefix && @transaction.context.prefix.request_headers
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
- :SQL_PARAMETERS,
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
- :REQUEST_BODY,
37
- :REQUEST_SIZE_BYTES,
38
- :REQUEST_HEADERS,
39
- :RESPONSE_BODY,
40
- :RESPONSE_SIZE_BYTES,
41
- :RESPONSE_HEADERS
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
- @REQUEST_BODY = body.to_s
49
- @REQUEST_SIZE_BYTES = body.to_s.length.to_s
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
- @REQUEST_HEADERS = to_json_list(headers)
56
+ @PREFIX_REQUEST_HEADERS = to_json_list(headers)
54
57
  end
55
58
 
56
59
  def update_response_body(body)
57
- @RESPONSE_BODY = body.to_s
58
- @RESPONSE_SIZE_BYTES = body.to_s.length.to_s
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
- @RESPONSE_HEADERS = to_json_list(headers)
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
@@ -34,7 +34,8 @@ module StackifyRubyAPM
34
34
  CATEGORY: 'Log',
35
35
  SUBCATEGORY: 'Log4r',
36
36
  LEVEL: Log4r::LNAMES[logevent.level] || 'ANY',
37
- MESSAGE: log_message
37
+ MESSAGE: log_message,
38
+ PREFIX: 'TRUE'
38
39
  )
39
40
 
40
41
  if exception
@@ -96,7 +96,8 @@ module StackifyRubyAPM
96
96
  CATEGORY: 'Log',
97
97
  SUBCATEGORY: 'Logger',
98
98
  LEVEL: severity || 'ANY',
99
- MESSAGE: log_message
99
+ MESSAGE: log_message,
100
+ PREFIX: 'TRUE'
100
101
  )
101
102
 
102
103
  if exception
@@ -40,7 +40,8 @@ module StackifyRubyAPM
40
40
  CATEGORY: 'Log',
41
41
  SUBCATEGORY: 'Logging',
42
42
  LEVEL: LVL_LABEL[event.level] || 'ANY',
43
- MESSAGE: log_message
43
+ MESSAGE: log_message,
44
+ PREFIX: 'TRUE'
44
45
  )
45
46
 
46
47
  if exception
@@ -55,7 +55,9 @@ module StackifyRubyAPM
55
55
  #
56
56
  ctx = Span::Context.new(
57
57
  CATEGORY: 'MongoDB',
58
- MONGODB_COLLECTION: col
58
+ MONGODB_COLLECTION: col,
59
+ OPERATION: event.command_name.to_s,
60
+ URL: event.address.to_s
59
61
  )
60
62
 
61
63
  # Creates new span from Mongo event
@@ -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
- redis_nspace = !redis_details.blank? ? redis_details[0] : ''
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 !redis_details.blank? && redis_details[1]
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
- redis_key = args[0..1].join('/') if args.length > 1 && !args[1].include?('=')
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
@@ -39,7 +39,8 @@ module StackifyRubyAPM
39
39
  CATEGORY: 'Log',
40
40
  SUBCATEGORY: 'Yell',
41
41
  LEVEL: SEVERITIES[options.severity],
42
- MESSAGE: log_message.to_s
42
+ MESSAGE: log_message.to_s,
43
+ PREFIX: 'TRUE'
43
44
  )
44
45
 
45
46
  if exception.length > 0
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Sets the version of the APM
4
4
  module StackifyRubyAPM
5
- VERSION = '1.12.3'.freeze
5
+ VERSION = '1.14.4'.freeze
6
6
  end
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.12.3
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-07-30 00:00:00.000000000 Z
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