stackify-ruby-apm 1.10.0 → 1.12.3

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/stackify_apm/agent.rb +0 -2
  3. data/lib/stackify_apm/config.rb +33 -5
  4. data/lib/stackify_apm/context.rb +4 -1
  5. data/lib/stackify_apm/context/prefix.rb +30 -0
  6. data/lib/stackify_apm/context/request/headers.rb +30 -0
  7. data/lib/stackify_apm/context_builder.rb +1 -0
  8. data/lib/stackify_apm/helper/database_helper.rb +39 -1
  9. data/lib/stackify_apm/instrumenter_helper.rb +90 -4
  10. data/lib/stackify_apm/logger/log_device.rb +7 -5
  11. data/lib/stackify_apm/logger/logger_high_version.rb +5 -1
  12. data/lib/stackify_apm/logger/logger_lower_version.rb +5 -1
  13. data/lib/stackify_apm/middleware.rb +21 -3
  14. data/lib/stackify_apm/normalizers/active_record.rb +16 -8
  15. data/lib/stackify_apm/root_info.rb +7 -1
  16. data/lib/stackify_apm/serializers/transactions.rb +5 -0
  17. data/lib/stackify_apm/span/context.rb +39 -1
  18. data/lib/stackify_apm/spies.rb +4 -2
  19. data/lib/stackify_apm/spies/action_dispatch.rb +6 -1
  20. data/lib/stackify_apm/spies/curb.rb +41 -20
  21. data/lib/stackify_apm/spies/curb/easy.rb +220 -92
  22. data/lib/stackify_apm/spies/curb/multi.rb +26 -12
  23. data/lib/stackify_apm/spies/custom_instrumenter.rb +25 -4
  24. data/lib/stackify_apm/spies/delayed_job.rb +49 -0
  25. data/lib/stackify_apm/spies/httparty.rb +45 -24
  26. data/lib/stackify_apm/spies/httpclient.rb +41 -20
  27. data/lib/stackify_apm/spies/httprb.rb +39 -18
  28. data/lib/stackify_apm/spies/log4r.rb +59 -0
  29. data/lib/stackify_apm/spies/logger.rb +116 -0
  30. data/lib/stackify_apm/spies/logging.rb +65 -0
  31. data/lib/stackify_apm/spies/net_http.rb +38 -20
  32. data/lib/stackify_apm/spies/redis.rb +36 -30
  33. data/lib/stackify_apm/spies/sequel.rb +28 -11
  34. data/lib/stackify_apm/spies/sinatra_activerecord/mysql_adapter.rb +27 -25
  35. data/lib/stackify_apm/spies/sinatra_activerecord/postgresql_adapter.rb +27 -24
  36. data/lib/stackify_apm/spies/sinatra_activerecord/sqlite_adapter.rb +18 -8
  37. data/lib/stackify_apm/spies/stackify_logger.rb +28 -16
  38. data/lib/stackify_apm/spies/yell.rb +64 -0
  39. data/lib/stackify_apm/util.rb +10 -9
  40. data/lib/stackify_apm/version.rb +1 -1
  41. data/stackify-ruby-apm.gemspec +1 -0
  42. metadata +23 -2
@@ -39,7 +39,8 @@ module StackifyRubyAPM
39
39
  # rubocop:disable Metrics/PerceivedComplexity
40
40
  def call(env)
41
41
  begin
42
- transaction = build_transaction(env) if running?
42
+ context = StackifyRubyAPM.build_context(env)
43
+ transaction = build_transaction(env, context) if running?
43
44
  resp = @app.call env
44
45
 
45
46
  @rack_status = resp[0].to_i
@@ -47,6 +48,8 @@ module StackifyRubyAPM
47
48
  @rack_body = resp[2]
48
49
  @configuration = config
49
50
 
51
+ build_prefix_context(transaction, context)
52
+
50
53
  if okay_to_modify?
51
54
  @configuration.already_instrumented_flag = true
52
55
  if @configuration.rum_enabled.is_a?(TrueClass)
@@ -92,8 +95,9 @@ module StackifyRubyAPM
92
95
 
93
96
  # Start of transaction building with params: name, type, context
94
97
  #
95
- def build_transaction(env)
96
- StackifyRubyAPM.transaction 'Rack', 'WEBAPP', context: StackifyRubyAPM.build_context(env)
98
+ def build_transaction(env, context=nil)
99
+ context = context || StackifyRubyAPM.build_context(env)
100
+ StackifyRubyAPM.transaction 'Rack', 'WEBAPP', context: context
97
101
  end
98
102
 
99
103
  def running?
@@ -129,5 +133,19 @@ module StackifyRubyAPM
129
133
  def xhr?
130
134
  @rack_headers['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'
131
135
  end
136
+
137
+ # Add prefix instrument data to transaction context if enabled
138
+ def build_prefix_context(transaction, context)
139
+ return nil unless @configuration.prefix_enabled.is_a?(TrueClass)
140
+
141
+ source = nil
142
+ body = @rack_body
143
+ body.each { |fragment| source ? (source << fragment.to_s) : (source = fragment.to_s) }
144
+
145
+ transaction.context.prefix.request_body = context && context.request && context.request.body || ""
146
+ transaction.context.prefix.request_headers = context && context.request && context.request.headers || Hash.new
147
+ transaction.context.prefix.response_body = source || ""
148
+ transaction.context.prefix.response_headers = @rack_headers || Hash.new
149
+ end
132
150
  end
133
151
  end
@@ -20,6 +20,7 @@ module StackifyRubyAPM
20
20
  return :skip if %w[SCHEMA CACHE].include?(payload[:name])
21
21
 
22
22
  statement = query_variables(payload)
23
+ check_prepared_stmt(statement, payload)
23
24
  name = payload[:sql] || payload[:name] || 'Default'
24
25
  context = Span::Context.new(statement)
25
26
  [name, @type, context]
@@ -28,14 +29,10 @@ module StackifyRubyAPM
28
29
  private
29
30
 
30
31
  def query_variables(payload)
31
- {
32
- CATEGORY: 'Database',
33
- SUBCATEGORY: 'Execute',
34
- COMPONENT_CATEGORY: 'DB Query',
35
- COMPONENT_DETAIL: 'Execute SQL Query',
36
- SQL: payload[:sql],
37
- PROVIDER: get_profiler(lookup_adapter)
38
- }
32
+ props = get_common_db_properties
33
+ props[:PROVIDER] = get_profiler(lookup_adapter)
34
+ props[:SQL] = payload[:sql]
35
+ props
39
36
  end
40
37
 
41
38
  def lookup_adapter
@@ -44,6 +41,17 @@ module StackifyRubyAPM
44
41
  debug '[SqlNormalizer] lookup_adapter err: ' + error.inspect.to_s
45
42
  nil
46
43
  end
44
+
45
+ def check_prepared_stmt(statement, payload)
46
+ if StackifyRubyAPM.agent.config.prefix_enabled
47
+ case get_profiler(lookup_adapter)
48
+ when 'generic', 'mysql', 'sqlite', 'oracle', 'db2'
49
+ check_prepared_stmt_by_placeholder(payload[:sql].include?('?'), statement, payload)
50
+ when 'postgresql'
51
+ check_prepared_stmt_by_placeholder(!!payload[:sql].match(/\$\d/), statement, payload)
52
+ end
53
+ end
54
+ end
47
55
  end
48
56
  end
49
57
  end
@@ -26,7 +26,7 @@ module StackifyRubyAPM
26
26
 
27
27
  hash = {
28
28
  PROFILER_VERSION: StackifyRubyAPM::VERSION,
29
- CATEGORY: 'Ruby',
29
+ CATEGORY: @transaction.context.category || 'Ruby',
30
30
  APPLICATION_PATH: '/',
31
31
  APPLICATION_FILESYSTEM_PATH: @config.root_path,
32
32
  APPLICATION_NAME: @config.application_name.strip,
@@ -47,6 +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
56
  hash
51
57
  end
52
58
  # rubocop:enable Metrics/CyclomaticComplexity
@@ -125,6 +125,11 @@ module StackifyRubyAPM
125
125
 
126
126
  span_context = span.context && span.context.to_h
127
127
 
128
+ if span_context && !span_context[:SQL].nil? && span_context[:SQL].length > 100_000
129
+ span_context[:SQL] = span_context[:SQL][0..99_999]
130
+ span_context[:SQL_TRUNCATED] = 'true'
131
+ end
132
+
128
133
  {
129
134
  id: span.id,
130
135
  parent_id: span.parent_id,
@@ -17,6 +17,8 @@ module StackifyRubyAPM
17
17
  :COMPONENT_CATEGORY,
18
18
  :COMPONENT_DETAIL,
19
19
  :SQL,
20
+ :SQL_PARAMETERS,
21
+ :SQL_TRUNCATED,
20
22
  :MONGODB_COLLECTION,
21
23
  :METHOD,
22
24
  :URL,
@@ -27,11 +29,47 @@ module StackifyRubyAPM
27
29
  :CACHENAME,
28
30
  :THREAD_ID,
29
31
  :ID,
30
- :TRACKED_FUNC
32
+ :TRACKED_FUNC,
33
+ :LEVEL,
34
+ :MESSAGE,
35
+ :EXCEPTION,
36
+ :REQUEST_BODY,
37
+ :REQUEST_SIZE_BYTES,
38
+ :REQUEST_HEADERS,
39
+ :RESPONSE_BODY,
40
+ :RESPONSE_SIZE_BYTES,
41
+ :RESPONSE_HEADERS
31
42
  # rubocop:disable Style/VariableName
32
43
  def update_status(status)
33
44
  @STATUS = status
34
45
  end
46
+
47
+ def update_request_body(body)
48
+ @REQUEST_BODY = body.to_s
49
+ @REQUEST_SIZE_BYTES = body.to_s.length.to_s
50
+ end
51
+
52
+ def update_request_headers(headers)
53
+ @REQUEST_HEADERS = to_json_list(headers)
54
+ end
55
+
56
+ def update_response_body(body)
57
+ @RESPONSE_BODY = body.to_s
58
+ @RESPONSE_SIZE_BYTES = body.to_s.length.to_s
59
+ end
60
+
61
+ def update_response_headers(headers)
62
+ @RESPONSE_HEADERS = to_json_list(headers)
63
+ end
64
+
65
+ private
66
+ def to_json_list(header)
67
+ list_header = []
68
+ header.each do |key, value|
69
+ list_header << {key => value}
70
+ end
71
+ list_header.to_json
72
+ end
35
73
  # rubocop:enable Style/VariableName
36
74
  end
37
75
  end
@@ -85,8 +85,10 @@ module StackifyRubyAPM
85
85
  end
86
86
 
87
87
  def self.class_exists?(class_name)
88
- klass = Module.const_get(class_name)
89
- return klass.is_a?(Class)
88
+ if class_name
89
+ klass = Module.const_get(class_name)
90
+ return klass.is_a?(Class)
91
+ end
90
92
  rescue NameError
91
93
  return false
92
94
  end
@@ -14,7 +14,12 @@ module StackifyRubyAPM
14
14
  def render_exception(env, exception)
15
15
  # Creates exception log report
16
16
  #
17
- StackifyRubyAPM.report(exception)
17
+ begin
18
+ StackifyRubyAPM.report(exception)
19
+ rescue Exception => e
20
+ StackifyRubyAPM.agent.error '[ActionDispatchSpy] Error: repoting exception.'
21
+ StackifyRubyAPM.agent.error "[ActionDispatchSpy] #{e.inspect}"
22
+ end
18
23
  render_exception_without_apm env, exception
19
24
  end
20
25
  end
@@ -13,30 +13,51 @@ module StackifyRubyAPM
13
13
  def self.http(verb, url, _post_body = nil, _put_data = nil, &block)
14
14
  req = nil
15
15
  return http_without_apm(verb, url, _post_body = nil, _put_data = nil, &block) unless StackifyRubyAPM.current_transaction
16
- # Data configuration
17
- #
18
- method = verb
19
- uri = url.strip
20
- name = "#{method} #{uri}"
21
- type = "ext.Curb.#{method}"
22
- # Submits HTTP request
23
- #
24
- req = http_without_apm(verb, url, _post_body = nil, _put_data = nil, &block)
25
- # Builds span context
26
- #
27
- status_code = req.status.sub(/^0-9/, '').to_i
28
16
 
29
- ctx = Span::Context.new(
30
- CATEGORY: 'Web External',
31
- SUBCATEGORY: 'Execute',
32
- URL: uri,
33
- STATUS: status_code,
34
- METHOD: method
35
- )
17
+ begin
18
+ # Data configuration
19
+ #
20
+ method = verb
21
+ uri = url.strip
22
+ name = "#{method} #{uri}"
23
+ type = "ext.Curb.#{method}"
24
+
25
+ ctx = Span::Context.new(
26
+ CATEGORY: 'Web External',
27
+ SUBCATEGORY: 'Execute',
28
+ URL: uri,
29
+ STATUS: '',
30
+ METHOD: method
31
+ )
32
+ rescue Exception => e
33
+ StackifyRubyAPM.agent.error "[CurbSpy] Error: creating span context."
34
+ StackifyRubyAPM.agent.error "[CurbSpy] #{e.inspect}"
35
+ return http_without_apm(verb, url, _post_body = nil, _put_data = nil, &block)
36
+ end
37
+
36
38
  # Creates new span from HTTP result
37
39
  #
38
40
  StackifyRubyAPM.span name, type, context: ctx do
39
- req
41
+ # Submits HTTP request
42
+ #
43
+ res = http_without_apm(verb, url, _post_body = nil, _put_data = nil, &block)
44
+ begin
45
+ # Builds span context
46
+ #
47
+ status_code = res.status.sub(/^0-9/, '').to_i
48
+ ctx.update_status(status_code)
49
+
50
+ if StackifyRubyAPM.agent.config.prefix_enabled
51
+ ctx.update_request_body(_post_body || _put_data || "")
52
+ ctx.update_request_headers(res.headers || Hash.new)
53
+ ctx.update_response_body(res.body || "")
54
+ ctx.update_response_headers(res.proxy_headers || Hash.new)
55
+ end
56
+ rescue Exception => e
57
+ StackifyRubyAPM.agent.error '[NetHTTPSpy] Error: getting status code or updating request/response context.'
58
+ StackifyRubyAPM.agent.error "[NetHTTPSpy] #{e.inspect}"
59
+ end
60
+ res
40
61
  end
41
62
  end
42
63
  end
@@ -19,132 +19,260 @@ module StackifyRubyAPM
19
19
  def self.perform(*args)
20
20
  req = nil
21
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.sub(/^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
- )
22
+
23
+ begin
24
+ # Data configuration
25
+ @_apm_http_verb ||= :GET
26
+ method = @_apm_http_verb
27
+ uri = args[0].strip
28
+ name = "#{method} #{uri}"
29
+ type = "ext.Curb.Easy.#{method}"
30
+
31
+ # Builds span context
32
+ #
33
+ ctx = Span::Context.new(
34
+ CATEGORY: 'Web External',
35
+ SUBCATEGORY: 'Execute',
36
+ URL: uri,
37
+ STATUS: '',
38
+ METHOD: method
39
+ )
40
+ rescue Exception => e
41
+ StackifyRubyAPM.agent.error "[CurbEasySpy] Error: creating span context."
42
+ StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
43
+ return perform_without_apm(*args)
44
+ end
45
+
41
46
  # Creates new span from HTTP result
42
47
  StackifyRubyAPM.span name, type, context: ctx do
43
- req
48
+ # Submits HTTP request
49
+ #
50
+ res = perform_without_apm(*args)
51
+
52
+ begin
53
+ status_code = res.status.sub(/^0-9/, '').to_i
54
+ ctx.update_status(status_code)
55
+
56
+ if StackifyRubyAPM.agent.config.prefix_enabled
57
+ ctx.update_request_body("")
58
+ ctx.update_request_headers(res.headers || Hash.new)
59
+ ctx.update_response_body(res.body || "")
60
+ ctx.update_response_headers(res.proxy_headers || Hash.new)
61
+ end
62
+ rescue Exception => e
63
+ StackifyRubyAPM.agent.error '[CurbEasySpy] Error: getting status code or updating request/response context.'
64
+ StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
65
+ end
66
+ res
44
67
  end
45
68
  end
46
69
 
47
70
  def self.http_post(*args)
48
71
  req = nil
49
72
  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.sub(/^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
- )
73
+
74
+ begin
75
+ # Data configuration
76
+ #
77
+ @_apm_http_verb = :POST
78
+ method = @_apm_http_verb
79
+ uri = args[0].strip
80
+ name = "#{method} #{uri}"
81
+ type = "ext.Curb.Easy.#{method}"
82
+
83
+ ctx = Span::Context.new(
84
+ CATEGORY: 'Web External',
85
+ SUBCATEGORY: 'Execute',
86
+ URL: uri,
87
+ STATUS: '',
88
+ METHOD: method
89
+ )
90
+ rescue Exception => e
91
+ StackifyRubyAPM.agent.error "[CurbEasySpy] Error: creating span context."
92
+ StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
93
+ return http_post_without_apm(*args)
94
+ end
95
+
67
96
  # Creates new span from HTTP result
68
97
  StackifyRubyAPM.span name, type, context: ctx do
69
- req
98
+ res = http_post_without_apm(*args)
99
+
100
+ begin
101
+ status_code = res.status.sub(/^0-9/, '').to_i
102
+ ctx.update_status(status_code)
103
+
104
+ if StackifyRubyAPM.agent.config.prefix_enabled
105
+ if args.length == 2
106
+ request_body = args[1].to_s
107
+ elsif args.length > 2
108
+ request_body = {}
109
+ contents = args[1..-1]
110
+ contents.each do |data|
111
+ request_body[data.name] = data.content
112
+ end
113
+ request_body = request_body.to_json
114
+ else
115
+ request_body = ""
116
+ end
117
+
118
+ ctx.update_request_body(request_body)
119
+ ctx.update_request_headers(res.headers || Hash.new)
120
+ ctx.update_response_body(res.body || "")
121
+ ctx.update_response_headers(res.proxy_headers || Hash.new)
122
+ end
123
+ rescue Exception => e
124
+ StackifyRubyAPM.agent.error '[CurbEasySpy] Error: getting status code or updating request/response context.'
125
+ StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
126
+ end
127
+
128
+ res
70
129
  end
71
130
  end
72
131
 
73
132
  def self.http_put(url, data)
74
133
  req = nil
75
134
  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.sub(/^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
- )
135
+
136
+ begin
137
+ # Data configuration
138
+ #
139
+ @_apm_http_verb = :PUT
140
+ method = @_apm_http_verb
141
+ uri = url.strip
142
+ name = "#{method} #{uri}"
143
+ type = "ext.Curb.Easy.#{method}"
144
+
145
+ ctx = Span::Context.new(
146
+ CATEGORY: 'Web External',
147
+ SUBCATEGORY: 'Execute',
148
+ URL: uri,
149
+ STATUS: '',
150
+ METHOD: method
151
+ )
152
+ rescue Exception => e
153
+ StackifyRubyAPM.agent.error "[CurbEasySpy] Error: creating span context."
154
+ StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
155
+ return http_put_without_apm(url, data)
156
+ end
157
+
93
158
  # Creates new span from HTTP result
94
159
  StackifyRubyAPM.span name, type, context: ctx do
95
- req
160
+ res = http_put_without_apm(url, data)
161
+
162
+ begin
163
+ status_code = res.status.sub(/^0-9/, '').to_i
164
+ ctx.update_status(status_code)
165
+
166
+ if StackifyRubyAPM.agent.config.prefix_enabled
167
+ ctx.update_request_body(data)
168
+ ctx.update_request_headers(res.headers || Hash.new)
169
+ ctx.update_response_body(res.body || "")
170
+ ctx.update_response_headers(res.proxy_headers || Hash.new)
171
+ end
172
+ rescue Exception => e
173
+ StackifyRubyAPM.agent.error '[CurbEasySpy] Error: getting status code or updating request/response context.'
174
+ StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
175
+ end
176
+
177
+ res
96
178
  end
97
179
  end
98
180
 
99
181
  def self.http_get(*args)
100
182
  req = nil
101
183
  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.sub(/^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
- )
184
+
185
+ begin
186
+ # Data configuration
187
+ #
188
+ @_apm_http_verb = :GET
189
+ method = @_apm_http_verb
190
+ uri = args[0].strip
191
+ name = "#{method} #{uri}"
192
+ type = "ext.Curb.Easy.#{method}"
193
+
194
+ ctx = Span::Context.new(
195
+ CATEGORY: 'Web External',
196
+ SUBCATEGORY: 'Execute',
197
+ URL: uri,
198
+ STATUS: '',
199
+ METHOD: method
200
+ )
201
+ rescue Exception => e
202
+ StackifyRubyAPM.agent.error "[CurbEasySpy] Error: creating span context."
203
+ StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
204
+ return http_get_without_apm(*args)
205
+ end
206
+
119
207
  # Creates new span from HTTP result
120
208
  StackifyRubyAPM.span name, type, context: ctx do
121
- req
209
+ res = http_get_without_apm(*args)
210
+
211
+ begin
212
+ status_code = res.status.sub(/^0-9/, '').to_i
213
+ ctx.update_status(status_code)
214
+
215
+ if StackifyRubyAPM.agent.config.prefix_enabled
216
+ ctx.update_request_body("")
217
+ ctx.update_request_headers(res.headers || Hash.new)
218
+ ctx.update_response_body(res.body || "")
219
+ ctx.update_response_headers(res.proxy_headers || Hash.new)
220
+ end
221
+ rescue Exception => e
222
+ StackifyRubyAPM.agent.error '[CurbEasySpy] Error: getting status code or updating request/response context.'
223
+ StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
224
+ end
225
+
226
+ res
122
227
  end
123
228
  end
124
229
 
125
230
  def self.http_delete(*args)
126
231
  req = nil
127
232
  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.sub(/^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
- )
233
+
234
+ begin
235
+ # Data configuration
236
+ #
237
+ @_apm_http_verb = :DELETE
238
+ method = @_apm_http_verb
239
+ uri = args[0].strip
240
+ name = "#{method} #{uri}"
241
+ type = "ext.Curb.Easy.#{method}"
242
+
243
+ ctx = Span::Context.new(
244
+ CATEGORY: 'Web External',
245
+ SUBCATEGORY: 'Execute',
246
+ URL: uri,
247
+ STATUS: '',
248
+ METHOD: method
249
+ )
250
+ rescue Exception => e
251
+ StackifyRubyAPM.agent.error "[CurbEasySpy] Error: creating span context."
252
+ StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
253
+ return http_delete_without_apm(*args)
254
+ end
255
+
145
256
  # Creates new span from HTTP result
146
257
  StackifyRubyAPM.span name, type, context: ctx do
147
- req
258
+ res = http_delete_without_apm(*args)
259
+
260
+ begin
261
+ status_code = res.status.sub(/^0-9/, '').to_i
262
+ ctx.update_status(status_code)
263
+
264
+ if StackifyRubyAPM.agent.config.prefix_enabled
265
+ ctx.update_request_body("")
266
+ ctx.update_request_headers(res.headers || Hash.new)
267
+ ctx.update_response_body(res.body || "")
268
+ ctx.update_response_headers(res.proxy_headers || Hash.new)
269
+ end
270
+ rescue Exception => e
271
+ StackifyRubyAPM.agent.error '[CurbEasySpy] Error: getting status code or updating request/response context.'
272
+ StackifyRubyAPM.agent.error "[CurbEasySpy] #{e.inspect}"
273
+ end
274
+
275
+ res
148
276
  end
149
277
  end
150
278
  end