newrelic_rpm 3.9.9.275 → 3.10.0.279
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +51 -0
- data/config.dot +0 -3
- data/lib/new_relic/agent.rb +7 -5
- data/lib/new_relic/agent/agent.rb +4 -4
- data/lib/new_relic/agent/instrumentation/active_job.rb +5 -8
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +17 -34
- data/lib/new_relic/agent/instrumentation/grape.rb +60 -23
- data/lib/new_relic/agent/instrumentation/merb/controller.rb +10 -2
- data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +33 -21
- data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +7 -3
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +0 -9
- data/lib/new_relic/agent/instrumentation/sinatra.rb +9 -12
- data/lib/new_relic/agent/javascript_instrumentor.rb +1 -0
- data/lib/new_relic/agent/new_relic_service.rb +9 -6
- data/lib/new_relic/agent/parameter_filtering.rb +37 -0
- data/lib/new_relic/agent/supported_versions.rb +7 -0
- data/lib/new_relic/agent/traced_method_stack.rb +1 -1
- data/lib/new_relic/agent/transaction.rb +182 -186
- data/lib/new_relic/agent/vm/rubinius_vm.rb +93 -3
- data/lib/new_relic/control/frameworks/rails.rb +1 -0
- data/lib/new_relic/rack/agent_hooks.rb +15 -23
- data/lib/new_relic/version.rb +2 -2
- data/newrelic_rpm.gemspec +12 -5
- data/test/agent_helper.rb +26 -14
- data/test/multiverse/lib/multiverse/suite.rb +1 -5
- data/test/multiverse/suites/activemerchant/Envfile +4 -1
- data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +2 -12
- data/test/multiverse/suites/agent_only/logging_test.rb +1 -1
- data/test/multiverse/suites/agent_only/set_transaction_name_test.rb +4 -0
- data/test/multiverse/suites/agent_only/synthetics_test.rb +1 -8
- data/test/multiverse/suites/agent_only/testing_app.rb +1 -7
- data/test/multiverse/suites/agent_only/xray_sessions_test.rb +11 -11
- data/test/multiverse/suites/deferred_instrumentation/sinatra_test.rb +4 -0
- data/test/multiverse/suites/grape/Envfile +1 -3
- data/test/multiverse/suites/grape/grape_test.rb +87 -6
- data/test/multiverse/suites/grape/grape_test_api.rb +5 -0
- data/test/multiverse/suites/grape/grape_versioning_test.rb +67 -0
- data/test/multiverse/suites/grape/grape_versioning_test_api.rb +72 -0
- data/test/multiverse/suites/rack/example_app.rb +31 -1
- data/test/multiverse/suites/rack/rack_auto_instrumentation_test.rb +11 -10
- data/test/multiverse/suites/rack/rack_cascade_test.rb +46 -0
- data/test/multiverse/suites/rack/rack_parameter_filtering_test.rb +40 -0
- data/test/multiverse/suites/rails/Envfile +8 -0
- data/test/multiverse/suites/rails/activejob_test.rb +16 -0
- data/test/multiverse/suites/rails/gc_instrumentation_test.rb +4 -2
- data/test/multiverse/suites/rails/parameter_capture_test.rb +49 -0
- data/test/multiverse/suites/rails/rails3_app/app_rails3_plus.rb +12 -1
- data/test/multiverse/suites/sinatra/sinatra_classic_test.rb +4 -0
- data/test/multiverse/suites/sinatra/sinatra_modular_test.rb +4 -0
- data/test/multiverse/suites/sinatra/sinatra_test_cases.rb +11 -0
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +0 -58
- data/test/new_relic/agent/instrumentation/middleware_proxy_test.rb +49 -0
- data/test/new_relic/agent/instrumentation/middleware_tracing_test.rb +26 -14
- data/test/new_relic/agent/parameter_filtering_test.rb +39 -0
- data/test/new_relic/agent/stats_engine/gc_profiler_test.rb +1 -1
- data/test/new_relic/agent/transaction_test.rb +106 -2
- data/test/new_relic/agent/vm/rubinius_vm_test.rb +38 -37
- data/test/new_relic/agent_test.rb +8 -3
- data/test/new_relic/filtering_test_app.rb +18 -0
- data/test/new_relic/latest_changes_test.rb +1 -1
- data/test/new_relic/rack/browser_monitoring_test.rb +4 -4
- data/test/performance/lib/performance/instrumentation/gc_stats.rb +6 -4
- data/test/performance/lib/performance/platform.rb +1 -0
- data/test/performance/suites/thread_profiling.rb +12 -0
- metadata +38 -15
- metadata.gz.sig +2 -1
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
@@ -1,5 +1,56 @@
|
|
1
1
|
# New Relic Ruby Agent Release Notes #
|
2
2
|
|
3
|
+
## v3.10.0 ##
|
4
|
+
|
5
|
+
* Support for the Grape framework
|
6
|
+
|
7
|
+
We now instrument the Grape REST API framework! To avoid conflicts with the
|
8
|
+
third-party newrelic-grape gem, our instrumentation will not be installed if
|
9
|
+
newrelic-grape is present in the Gemfile.
|
10
|
+
|
11
|
+
For more details, see https://docs.newrelic.com/docs/agents/ruby-agent/frameworks/grape-instrumentation
|
12
|
+
|
13
|
+
* Automatic Cross Application Tracing support for all Rack applications
|
14
|
+
|
15
|
+
Previously Rack apps not using Rails or Sinatra needed to include the
|
16
|
+
AgentHooks middleware to get Cross Application Tracing support. With
|
17
|
+
these changes, this is no longer necessary. Any explicit references to
|
18
|
+
AgentHooks can be removed unless the `disable_middleware_instrumentation`
|
19
|
+
setting is set to `true`.
|
20
|
+
|
21
|
+
* Metrics no longer reported from Puma master processes
|
22
|
+
|
23
|
+
When using Puma's cluster mode with the preload_app! configuration directive,
|
24
|
+
the agent will no longer start its reporting thread in the Puma master
|
25
|
+
process. This should result in more accurate instance counts, and more
|
26
|
+
accurate stats on the Ruby VMs page (since the master process will be
|
27
|
+
excluded).
|
28
|
+
|
29
|
+
* Better support for Sinatra apps used with Rack::Cascade
|
30
|
+
|
31
|
+
Previously, using a Sinatra application as part of a Rack::Cascade chain would
|
32
|
+
cause all transactions to be named after the Sinatra application, rather than
|
33
|
+
allowing downstream applications to set the transaction name when the Sinatra
|
34
|
+
application returned a 404 response. This has been fixed.
|
35
|
+
|
36
|
+
* Updated support for Rubinius 2.3+ metrics
|
37
|
+
|
38
|
+
Rubinius 2.3 introduced a new system for gathering metrics from the
|
39
|
+
underlying VM. Data capture for the Ruby VM's page has been updated to take
|
40
|
+
advantage of these. Thanks Yorick Peterse for the contribution!
|
41
|
+
|
42
|
+
* Fix for missing ActiveJob traced errors
|
43
|
+
|
44
|
+
ActiveJobs processed by backends where the Ruby agent lacked existing
|
45
|
+
instrumentation missed reporting traced errors. This did not impact
|
46
|
+
ActiveJobs used with Sidekiq or Resque, and has been fixed.
|
47
|
+
|
48
|
+
* Fix possible crash in middleware tracing
|
49
|
+
|
50
|
+
In rare circumstances, a failure in the agent early during tracing of a web
|
51
|
+
request could lead to a cascading error when trying to capture the HTTP status
|
52
|
+
code of the request. This has been fixed. Thanks to Michal Cichra for the fix!
|
53
|
+
|
3
54
|
## v3.9.9 ##
|
4
55
|
|
5
56
|
* Support for Ruby 2.2
|
data/config.dot
CHANGED
@@ -42,7 +42,6 @@ digraph AgentEnabled {
|
|
42
42
|
"[log_file_path]"
|
43
43
|
"[dispatcher]"
|
44
44
|
"[force_send]"
|
45
|
-
"[disable_mobile_headers]"
|
46
45
|
"[textmate]"
|
47
46
|
"[post_size_limit]"
|
48
47
|
"[sync_startup]"
|
@@ -224,8 +223,6 @@ digraph AgentEnabled {
|
|
224
223
|
"ErrorCollector#initialize" -> "[error_collector.ignore_errors]"
|
225
224
|
"ErrorCollector#request_params_from_opts" -> "[capture_params]"
|
226
225
|
|
227
|
-
"ControllerInstrumentation#perform_action_with_newrelic_trace" -> "[disable_mobile_headers]"
|
228
|
-
|
229
226
|
"NewRelicService#initialize" -> "[timeout]"
|
230
227
|
"NewRelicService#initialize" -> "[license_key]"
|
231
228
|
"NewRelicService#initialize" -> "Control#server"
|
data/lib/new_relic/agent.rb
CHANGED
@@ -543,11 +543,13 @@ module NewRelic
|
|
543
543
|
nil # don't return a noticed error datastructure. it can only hurt.
|
544
544
|
end
|
545
545
|
|
546
|
-
# Add parameters to
|
547
|
-
#
|
546
|
+
# Add parameters to the transaction trace, Insights Transaction event, and
|
547
|
+
# any traced errors recorded for the current transaction.
|
548
548
|
#
|
549
|
-
# If
|
550
|
-
#
|
549
|
+
# If Browser Monitoring is enabled, and the
|
550
|
+
# browser_monitoring.capture_attributes configuration setting is enabled,
|
551
|
+
# these custom parameters will also be present in the RUM script injected
|
552
|
+
# into the response body, making them available on Insights PageView events.
|
551
553
|
#
|
552
554
|
# @api public
|
553
555
|
#
|
@@ -590,7 +592,7 @@ module NewRelic
|
|
590
592
|
# @api public
|
591
593
|
#
|
592
594
|
def set_transaction_name(name, options={})
|
593
|
-
Transaction.set_overriding_transaction_name(name, options)
|
595
|
+
Transaction.set_overriding_transaction_name(name, options[:category])
|
594
596
|
end
|
595
597
|
|
596
598
|
# Get the name of the current running transaction. This is useful if you
|
@@ -403,7 +403,7 @@ module NewRelic
|
|
403
403
|
true
|
404
404
|
else
|
405
405
|
::NewRelic::Agent.logger.warn("No license key found. " +
|
406
|
-
"This often means your newrelic.yml file was not found, or it lacks a section for the running environment, '#{NewRelic::Control.instance.env}'.")
|
406
|
+
"This often means your newrelic.yml file was not found, or it lacks a section for the running environment, '#{NewRelic::Control.instance.env}'. You may also want to try linting your newrelic.yml to ensure it is valid YML.")
|
407
407
|
false
|
408
408
|
end
|
409
409
|
end
|
@@ -428,10 +428,10 @@ module NewRelic
|
|
428
428
|
|
429
429
|
# If we're using a dispatcher that forks before serving
|
430
430
|
# requests, we need to wait until the children are forked
|
431
|
-
# before connecting, otherwise the parent process sends
|
431
|
+
# before connecting, otherwise the parent process sends useless data
|
432
432
|
def using_forking_dispatcher?
|
433
|
-
if [:passenger, :rainbows, :unicorn].include? Agent.config[:dispatcher]
|
434
|
-
::NewRelic::Agent.logger.info
|
433
|
+
if [:puma, :passenger, :rainbows, :unicorn].include? Agent.config[:dispatcher]
|
434
|
+
::NewRelic::Agent.logger.info "Deferring startup of agent reporting thread because #{Agent.config[:dispatcher]} may fork."
|
435
435
|
true
|
436
436
|
else
|
437
437
|
false
|
@@ -42,7 +42,7 @@ module NewRelic
|
|
42
42
|
elsif state.in_background_transaction?
|
43
43
|
::NewRelic::Agent::Transaction.set_default_transaction_name(
|
44
44
|
transaction_name_suffix_for_job(job),
|
45
|
-
|
45
|
+
transaction_category)
|
46
46
|
block.call
|
47
47
|
else
|
48
48
|
run_in_transaction(state, job, block)
|
@@ -56,13 +56,10 @@ module NewRelic
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def self.run_in_transaction(state, job, block)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
ensure
|
64
|
-
::NewRelic::Agent::Transaction.stop(state)
|
65
|
-
end
|
59
|
+
::NewRelic::Agent::Transaction.wrap(state,
|
60
|
+
transaction_name_for_job(job),
|
61
|
+
:other,
|
62
|
+
&block)
|
66
63
|
end
|
67
64
|
|
68
65
|
def self.transaction_category
|
@@ -218,7 +218,7 @@ module NewRelic
|
|
218
218
|
end
|
219
219
|
|
220
220
|
def self.prefix_for_category(txn, category = nil)
|
221
|
-
category ||= (txn && txn.
|
221
|
+
category ||= (txn && txn.category)
|
222
222
|
case category
|
223
223
|
when :controller then ::NewRelic::Agent::Transaction::CONTROLLER_PREFIX
|
224
224
|
when :task then ::NewRelic::Agent::Transaction::TASK_PREFIX
|
@@ -226,6 +226,7 @@ module NewRelic
|
|
226
226
|
when :uri then ::NewRelic::Agent::Transaction::CONTROLLER_PREFIX
|
227
227
|
when :sinatra then ::NewRelic::Agent::Transaction::SINATRA_PREFIX
|
228
228
|
when :middleware then ::NewRelic::Agent::Transaction::MIDDLEWARE_PREFIX
|
229
|
+
when :grape then ::NewRelic::Agent::Transaction::GRAPE_PREFIX
|
229
230
|
else "#{category.to_s}/" # for internal use only
|
230
231
|
end
|
231
232
|
end
|
@@ -331,42 +332,25 @@ module NewRelic
|
|
331
332
|
state.request = newrelic_request(args)
|
332
333
|
|
333
334
|
skip_tracing = do_not_trace? || !state.is_execution_traced?
|
335
|
+
|
334
336
|
if skip_tracing
|
335
|
-
if
|
336
|
-
|
337
|
-
else
|
338
|
-
state.current_transaction.ignore! if state.current_transaction
|
339
|
-
NewRelic::Agent.disable_all_tracing do
|
340
|
-
return perform_action_without_newrelic_trace(*args)
|
341
|
-
end
|
342
|
-
end
|
337
|
+
state.current_transaction.ignore! if state.current_transaction
|
338
|
+
NewRelic::Agent.disable_all_tracing { return yield }
|
343
339
|
end
|
344
340
|
|
345
|
-
#
|
346
|
-
#
|
347
|
-
|
341
|
+
# This method has traditionally taken a variable number of arguments, but the
|
342
|
+
# only one that is expected / used is a single options hash. We are preserving
|
343
|
+
# the *args method signature to ensure backwards compatibility.
|
348
344
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
else
|
353
|
-
available_params = respond_to?(:params) && params
|
354
|
-
end
|
355
|
-
|
356
|
-
category = trace_options[:category] || :controller
|
357
|
-
txn_options = create_transaction_options(trace_options, available_params)
|
358
|
-
txn_options[:transaction_name] = TransactionNamer.name_for(nil, self, category, trace_options)
|
359
|
-
txn_options[:apdex_start_time] = detect_queue_start_time(state)
|
345
|
+
trace_options = args.last.is_a?(Hash) ? args.last : NR_DEFAULT_OPTIONS
|
346
|
+
category = trace_options[:category] || :controller
|
347
|
+
txn_options = create_transaction_options(trace_options, category, state)
|
360
348
|
|
361
349
|
begin
|
362
350
|
txn = Transaction.start(state, category, txn_options)
|
363
351
|
|
364
352
|
begin
|
365
|
-
|
366
|
-
yield
|
367
|
-
else
|
368
|
-
perform_action_without_newrelic_trace(*args)
|
369
|
-
end
|
353
|
+
yield
|
370
354
|
rescue => e
|
371
355
|
NewRelic::Agent.notice_error(e)
|
372
356
|
raise
|
@@ -429,15 +413,14 @@ module NewRelic
|
|
429
413
|
|
430
414
|
private
|
431
415
|
|
432
|
-
def create_transaction_options(trace_options,
|
416
|
+
def create_transaction_options(trace_options, category, state)
|
433
417
|
txn_options = {}
|
434
418
|
txn_options[:request] = trace_options[:request]
|
435
419
|
txn_options[:request] ||= request if respond_to?(:request)
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
420
|
+
# params should have been filtered before calling perform_action_with_newrelic_trace
|
421
|
+
txn_options[:filtered_params] = trace_options[:params]
|
422
|
+
txn_options[:transaction_name] = TransactionNamer.name_for(nil, self, category, trace_options)
|
423
|
+
txn_options[:apdex_start_time] = detect_queue_start_time(state)
|
441
424
|
txn_options
|
442
425
|
end
|
443
426
|
|
@@ -2,13 +2,52 @@
|
|
2
2
|
# This file is distributed under New Relic's license terms.
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
|
+
require 'new_relic/agent/parameter_filtering'
|
6
|
+
|
5
7
|
module NewRelic
|
6
8
|
module Agent
|
7
|
-
module
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
module Instrumentation
|
10
|
+
module GrapeInstrumentation
|
11
|
+
extend self
|
12
|
+
|
13
|
+
API_ENDPOINT = 'api.endpoint'.freeze
|
14
|
+
FORMAT_REGEX = /\(\/?\.:format\)/.freeze
|
15
|
+
VERSION_REGEX = /:version(\/|$)/.freeze
|
16
|
+
EMPTY_STRING = ''.freeze
|
17
|
+
MIN_VERSION = VersionNumber.new("0.2.0")
|
18
|
+
|
19
|
+
def handle_transaction(endpoint, class_name)
|
20
|
+
return unless endpoint && route = endpoint.route
|
21
|
+
name_transaction(route, class_name)
|
22
|
+
capture_params(endpoint) if Agent.config[:capture_params]
|
23
|
+
end
|
24
|
+
|
25
|
+
def name_transaction(route, class_name)
|
26
|
+
txn_name = name_for_transaction(route, class_name)
|
27
|
+
segment_name = "Middleware/Grape/#{class_name}/call"
|
28
|
+
Transaction.set_default_transaction_name(txn_name, :grape, segment_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def name_for_transaction(route, class_name)
|
32
|
+
action_name = route.route_path.sub(FORMAT_REGEX, EMPTY_STRING)
|
33
|
+
method_name = route.route_method
|
34
|
+
|
35
|
+
if route.route_version
|
36
|
+
action_name = action_name.sub(VERSION_REGEX, EMPTY_STRING)
|
37
|
+
"#{class_name}-#{route.route_version}#{action_name} (#{method_name})"
|
38
|
+
else
|
39
|
+
"#{class_name}#{action_name} (#{method_name})"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def capture_params(endpoint)
|
44
|
+
txn = Transaction.tl_current
|
45
|
+
env = endpoint.request.env
|
46
|
+
params = ParameterFiltering::apply_filters(env, endpoint.params)
|
47
|
+
params.delete("route_info")
|
48
|
+
txn.filtered_params = params
|
49
|
+
end
|
50
|
+
end
|
12
51
|
end
|
13
52
|
end
|
14
53
|
end
|
@@ -24,15 +63,25 @@ DependencyDetection.defer do
|
|
24
63
|
|
25
64
|
depends_on do
|
26
65
|
defined?(::Grape::VERSION) &&
|
27
|
-
::NewRelic::VersionNumber.new(::Grape::VERSION) >= ::NewRelic::Agent::GrapeInstrumentation::MIN_VERSION
|
66
|
+
::NewRelic::VersionNumber.new(::Grape::VERSION) >= ::NewRelic::Agent::Instrumentation::GrapeInstrumentation::MIN_VERSION
|
28
67
|
end
|
29
68
|
|
30
69
|
depends_on do
|
31
|
-
|
70
|
+
begin
|
71
|
+
if defined?(Bundler) && Bundler.rubygems.all_specs.map(&:name).include?("newrelic-grape")
|
72
|
+
::NewRelic::Agent.logger.info("Not installing New Relic supported Grape instrumentation because the third party newrelic-grape gem is present")
|
73
|
+
false
|
74
|
+
else
|
75
|
+
true
|
76
|
+
end
|
77
|
+
rescue => e
|
78
|
+
::NewRelic::Agent.logger.info("Could not determine if third party newrelic-grape gem is installed")
|
79
|
+
true
|
80
|
+
end
|
32
81
|
end
|
33
82
|
|
34
83
|
executes do
|
35
|
-
NewRelic::Agent.logger.info 'Installing Grape instrumentation'
|
84
|
+
NewRelic::Agent.logger.info 'Installing New Relic supported Grape instrumentation'
|
36
85
|
instrument_call
|
37
86
|
end
|
38
87
|
|
@@ -42,23 +91,11 @@ DependencyDetection.defer do
|
|
42
91
|
begin
|
43
92
|
response = call_without_new_relic(env)
|
44
93
|
ensure
|
45
|
-
# We don't want an error in our transaction naming to kill the request.
|
46
94
|
begin
|
47
|
-
endpoint = env[::NewRelic::Agent::GrapeInstrumentation::API_ENDPOINT]
|
48
|
-
|
49
|
-
if endpoint
|
50
|
-
route_obj = endpoint.route
|
51
|
-
if route_obj
|
52
|
-
action_name = route_obj.route_path.sub(::NewRelic::Agent::GrapeInstrumentation::FORMAT,
|
53
|
-
::NewRelic::Agent::GrapeInstrumentation::EMPTY_STRING)
|
54
|
-
method_name = route_obj.route_method
|
55
|
-
|
56
|
-
txn_name = "#{self.class.name}#{action_name} (#{method_name})"
|
57
|
-
::NewRelic::Agent.set_transaction_name(txn_name)
|
58
|
-
end
|
59
|
-
end
|
95
|
+
endpoint = env[::NewRelic::Agent::Instrumentation::GrapeInstrumentation::API_ENDPOINT]
|
96
|
+
::NewRelic::Agent::Instrumentation::GrapeInstrumentation.handle_transaction(endpoint, self.class.name)
|
60
97
|
rescue => e
|
61
|
-
::NewRelic::Agent.logger.warn("Error in Grape
|
98
|
+
::NewRelic::Agent.logger.warn("Error in Grape instrumentation", e)
|
62
99
|
end
|
63
100
|
end
|
64
101
|
|
@@ -29,8 +29,16 @@ DependencyDetection.defer do
|
|
29
29
|
|
30
30
|
protected
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
def _dispatch_with_newrelic_trace(*args)
|
33
|
+
options = {}
|
34
|
+
options[:params] = params
|
35
|
+
perform_action_with_newrelic_trace(options) do
|
36
|
+
_dispatch_without_newrelic_trace(*args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
alias_method :_dispatch_without_newrelic_trace, :_dispatch
|
41
|
+
alias_method :_dispatch, :_dispatch_with_newrelic_trace
|
34
42
|
end
|
35
43
|
end
|
36
44
|
end
|
@@ -26,40 +26,48 @@ module NewRelic
|
|
26
26
|
module Agent
|
27
27
|
module Instrumentation
|
28
28
|
module MiddlewareTracing
|
29
|
-
|
29
|
+
TXN_STARTED_KEY = 'newrelic.transaction_started'.freeze unless defined?(TXN_STARTED_KEY)
|
30
30
|
|
31
31
|
def _nr_has_middleware_tracing
|
32
32
|
true
|
33
33
|
end
|
34
34
|
|
35
|
-
def build_transaction_options(env)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
)
|
35
|
+
def build_transaction_options(env, first_middleware)
|
36
|
+
opts = transaction_options
|
37
|
+
opts = merge_first_middleware_options(opts, env) if first_middleware
|
38
|
+
opts
|
39
|
+
end
|
40
|
+
|
41
|
+
def merge_first_middleware_options(opts, env)
|
42
|
+
opts.merge(
|
43
|
+
:request => ::Rack::Request.new(env),
|
44
|
+
:apdex_start_time => QueueTime.parse_frontend_timestamp(env)
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
def note_transaction_started(env)
|
49
|
+
env[TXN_STARTED_KEY] = true unless env[TXN_STARTED_KEY]
|
50
|
+
end
|
51
|
+
|
52
|
+
def capture_http_response_code(state, result)
|
53
|
+
if result.is_a?(Array) && state.current_transaction
|
54
|
+
state.current_transaction.http_response_code = result[0]
|
45
55
|
end
|
46
56
|
end
|
47
57
|
|
48
58
|
def call(env)
|
49
|
-
|
59
|
+
first_middleware = note_transaction_started(env)
|
60
|
+
|
50
61
|
state = NewRelic::Agent::TransactionState.tl_get
|
51
62
|
|
52
63
|
begin
|
53
|
-
Transaction.start(state, category,
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
result = target.call(env)
|
58
|
-
end
|
64
|
+
Transaction.start(state, category, build_transaction_options(env, first_middleware))
|
65
|
+
events.notify(:before_call, env) if first_middleware
|
66
|
+
|
67
|
+
result = (target == self) ? traced_call(env) : target.call(env)
|
59
68
|
|
60
|
-
|
61
|
-
|
62
|
-
end
|
69
|
+
capture_http_response_code(state, result)
|
70
|
+
events.notify(:after_call, env, result) if first_middleware
|
63
71
|
|
64
72
|
result
|
65
73
|
rescue Exception => e
|
@@ -69,6 +77,10 @@ module NewRelic
|
|
69
77
|
Transaction.stop(state)
|
70
78
|
end
|
71
79
|
end
|
80
|
+
|
81
|
+
def events
|
82
|
+
NewRelic::Agent.instance.events
|
83
|
+
end
|
72
84
|
end
|
73
85
|
end
|
74
86
|
end
|