newrelic_rpm 6.15.0 → 7.0.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/CHANGELOG.md +96 -22
  3. data/README.md +2 -2
  4. data/lib/new_relic/agent.rb +0 -6
  5. data/lib/new_relic/agent/autostart.rb +1 -2
  6. data/lib/new_relic/agent/configuration/default_source.rb +270 -104
  7. data/lib/new_relic/agent/configuration/manager.rb +2 -2
  8. data/lib/new_relic/agent/datastores/redis.rb +0 -4
  9. data/lib/new_relic/agent/distributed_tracing.rb +0 -66
  10. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +0 -16
  11. data/lib/new_relic/agent/instrumentation/bunny.rb +10 -152
  12. data/lib/new_relic/agent/instrumentation/bunny/chain.rb +45 -0
  13. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +152 -0
  14. data/lib/new_relic/agent/instrumentation/bunny/prepend.rb +35 -0
  15. data/lib/new_relic/agent/instrumentation/curb.rb +9 -241
  16. data/lib/new_relic/agent/instrumentation/curb/chain.rb +93 -0
  17. data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +222 -0
  18. data/lib/new_relic/agent/instrumentation/curb/prepend.rb +63 -0
  19. data/lib/new_relic/agent/instrumentation/delayed_job/chain.rb +38 -0
  20. data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +53 -0
  21. data/lib/new_relic/agent/instrumentation/delayed_job/prepend.rb +34 -0
  22. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +8 -50
  23. data/lib/new_relic/agent/instrumentation/excon.rb +2 -1
  24. data/lib/new_relic/agent/instrumentation/grape.rb +13 -113
  25. data/lib/new_relic/agent/instrumentation/grape/chain.rb +25 -0
  26. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +100 -0
  27. data/lib/new_relic/agent/instrumentation/grape/prepend.rb +17 -0
  28. data/lib/new_relic/agent/instrumentation/httpclient.rb +8 -30
  29. data/lib/new_relic/agent/instrumentation/httpclient/chain.rb +25 -0
  30. data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +38 -0
  31. data/lib/new_relic/agent/instrumentation/httpclient/prepend.rb +17 -0
  32. data/lib/new_relic/agent/instrumentation/httprb.rb +29 -0
  33. data/lib/new_relic/agent/instrumentation/httprb/chain.rb +22 -0
  34. data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +30 -0
  35. data/lib/new_relic/agent/instrumentation/httprb/prepend.rb +15 -0
  36. data/lib/new_relic/agent/instrumentation/memcache.rb +54 -69
  37. data/lib/new_relic/agent/instrumentation/memcache/chain.rb +16 -0
  38. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +38 -121
  39. data/lib/new_relic/agent/instrumentation/memcache/helper.rb +56 -0
  40. data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +88 -0
  41. data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +88 -0
  42. data/lib/new_relic/agent/instrumentation/middleware_proxy.rb +2 -0
  43. data/lib/new_relic/agent/instrumentation/mongo.rb +7 -0
  44. data/lib/new_relic/agent/instrumentation/net_http.rb +39 -0
  45. data/lib/new_relic/agent/instrumentation/net_http/chain.rb +25 -0
  46. data/lib/new_relic/agent/instrumentation/{net_prepend.rb → net_http/instrumentation.rb} +3 -3
  47. data/lib/new_relic/agent/instrumentation/net_http/prepend.rb +21 -0
  48. data/lib/new_relic/agent/instrumentation/padrino.rb +18 -53
  49. data/lib/new_relic/agent/instrumentation/padrino/chain.rb +34 -0
  50. data/lib/new_relic/agent/instrumentation/padrino/instrumentation.rb +27 -0
  51. data/lib/new_relic/agent/instrumentation/padrino/prepend.rb +20 -0
  52. data/lib/new_relic/agent/instrumentation/rack.rb +29 -139
  53. data/lib/new_relic/agent/instrumentation/rack/chain.rb +57 -0
  54. data/lib/new_relic/agent/instrumentation/rack/helpers.rb +32 -0
  55. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +73 -0
  56. data/lib/new_relic/agent/instrumentation/rack/prepend.rb +36 -0
  57. data/lib/new_relic/agent/instrumentation/rake.rb +13 -154
  58. data/lib/new_relic/agent/instrumentation/rake/chain.rb +25 -0
  59. data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +144 -0
  60. data/lib/new_relic/agent/instrumentation/rake/prepend.rb +14 -0
  61. data/lib/new_relic/agent/instrumentation/redis.rb +10 -109
  62. data/lib/new_relic/agent/instrumentation/redis/chain.rb +34 -0
  63. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +65 -0
  64. data/lib/new_relic/agent/instrumentation/redis/prepend.rb +24 -0
  65. data/lib/new_relic/agent/instrumentation/resque.rb +8 -28
  66. data/lib/new_relic/agent/instrumentation/resque/chain.rb +22 -0
  67. data/lib/new_relic/agent/instrumentation/resque/instrumentation.rb +33 -0
  68. data/lib/new_relic/agent/instrumentation/resque/prepend.rb +16 -0
  69. data/lib/new_relic/agent/instrumentation/sinatra.rb +20 -158
  70. data/lib/new_relic/agent/instrumentation/sinatra/chain.rb +55 -0
  71. data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +29 -34
  72. data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +118 -0
  73. data/lib/new_relic/agent/instrumentation/sinatra/prepend.rb +33 -0
  74. data/lib/new_relic/agent/instrumentation/typhoeus.rb +10 -89
  75. data/lib/new_relic/agent/instrumentation/typhoeus/chain.rb +22 -0
  76. data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +82 -0
  77. data/lib/new_relic/agent/instrumentation/typhoeus/prepend.rb +14 -0
  78. data/lib/new_relic/agent/new_relic_service.rb +3 -12
  79. data/lib/new_relic/agent/sql_sampler.rb +1 -1
  80. data/lib/new_relic/agent/transaction.rb +1 -4
  81. data/lib/new_relic/control/frameworks/rails.rb +11 -9
  82. data/lib/new_relic/control/instance_methods.rb +1 -0
  83. data/lib/new_relic/dependency_detection.rb +116 -10
  84. data/lib/new_relic/noticed_error.rb +1 -5
  85. data/lib/new_relic/supportability_helper.rb +1 -2
  86. data/lib/new_relic/version.rb +2 -2
  87. data/newrelic_rpm.gemspec +1 -1
  88. metadata +53 -8
  89. data/cert/cacert.pem +0 -1177
  90. data/lib/new_relic/agent/instrumentation/http.rb +0 -49
  91. data/lib/new_relic/agent/instrumentation/net.rb +0 -70
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module Rake
7
+ module Prepend
8
+ include NewRelic::Agent::Instrumentation::Rake::Tracer
9
+ def invoke(*args)
10
+ invoke_with_newrelic_tracing(*args) { super }
11
+ end
12
+ end
13
+ end
14
+ end
@@ -5,43 +5,17 @@
5
5
  require 'new_relic/agent/datastores'
6
6
  require 'new_relic/agent/datastores/redis'
7
7
 
8
- module NewRelic
9
- module Agent
10
- module Instrumentation
11
- module Redis
12
- extend self
13
-
14
- UNKNOWN = "unknown".freeze
15
- LOCALHOST = "localhost".freeze
16
-
17
- def host_for(client)
18
- client.path ? LOCALHOST : client.host
19
- rescue => e
20
- NewRelic::Agent.logger.debug "Failed to retrieve Redis host: #{e}"
21
- UNKNOWN
22
- end
23
-
24
- def port_path_or_id_for(client)
25
- client.path || client.port
26
- rescue => e
27
- NewRelic::Agent.logger.debug "Failed to retrieve Redis port_path_or_id: #{e}"
28
- UNKNOWN
29
- end
30
- end
31
- end
32
- end
33
- end
8
+ require_relative 'redis/instrumentation'
9
+ require_relative 'redis/chain'
10
+ require_relative 'redis/prepend'
34
11
 
35
12
  DependencyDetection.defer do
36
13
  # Why not :redis? newrelic-redis used that name, so avoid conflicting
37
14
  named :redis_instrumentation
38
-
39
- depends_on do
40
- defined? ::Redis::VERSION
41
- end
42
-
15
+ configure_with :redis
16
+
43
17
  depends_on do
44
- NewRelic::Agent.config[:disable_redis] == false
18
+ defined?(::Redis) && defined?(::Redis::VERSION)
45
19
  end
46
20
 
47
21
  depends_on do
@@ -51,83 +25,10 @@ DependencyDetection.defer do
51
25
 
52
26
  executes do
53
27
  NewRelic::Agent.logger.info 'Installing Redis Instrumentation'
54
-
55
- Redis::Client.class_eval do
56
- alias_method :call_without_new_relic, :call
57
-
58
- def call(*args, &block)
59
- operation = args[0][0]
60
- statement = ::NewRelic::Agent::Datastores::Redis.format_command(args[0])
61
-
62
- hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
63
- port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
64
-
65
- segment = NewRelic::Agent::Tracer.start_datastore_segment(
66
- product: NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
67
- operation: operation,
68
- host: hostname,
69
- port_path_or_id: port_path_or_id,
70
- database_name: db
71
- )
72
- begin
73
- segment.notice_nosql_statement(statement) if statement
74
- NewRelic::Agent::Tracer.capture_segment_error segment do
75
- call_without_new_relic(*args, &block)
76
- end
77
- ensure
78
- segment.finish if segment
79
- end
80
- end
81
-
82
- alias_method :call_pipeline_without_new_relic, :call_pipeline
83
-
84
- def call_pipeline(*args, &block)
85
- pipeline = args[0]
86
- operation = pipeline.is_a?(::Redis::Pipeline::Multi) ? NewRelic::Agent::Datastores::Redis::MULTI_OPERATION : NewRelic::Agent::Datastores::Redis::PIPELINE_OPERATION
87
- statement = ::NewRelic::Agent::Datastores::Redis.format_pipeline_commands(pipeline.commands)
88
-
89
- hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
90
- port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
91
-
92
- segment = NewRelic::Agent::Tracer.start_datastore_segment(
93
- product: NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
94
- operation: operation,
95
- host: hostname,
96
- port_path_or_id: port_path_or_id,
97
- database_name: db
98
- )
99
- begin
100
- segment.notice_nosql_statement(statement)
101
- NewRelic::Agent::Tracer.capture_segment_error segment do
102
- call_pipeline_without_new_relic(*args, &block)
103
- end
104
- ensure
105
- segment.finish if segment
106
- end
107
- end
108
-
109
- alias_method :connect_without_new_relic, :connect
110
-
111
- def connect(*args, &block)
112
- hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
113
- port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
114
-
115
- segment = NewRelic::Agent::Tracer.start_datastore_segment(
116
- product: NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
117
- operation: NewRelic::Agent::Datastores::Redis::CONNECT,
118
- host: hostname,
119
- port_path_or_id: port_path_or_id,
120
- database_name: db
121
- )
122
-
123
- begin
124
- NewRelic::Agent::Tracer.capture_segment_error segment do
125
- connect_without_new_relic(*args, &block)
126
- end
127
- ensure
128
- segment.finish if segment
129
- end
130
- end
28
+ if use_prepend?
29
+ prepend_instrument ::Redis::Client, NewRelic::Agent::Instrumentation::Redis::Prepend
30
+ else
31
+ chain_instrument NewRelic::Agent::Instrumentation::Redis::Chain
131
32
  end
132
33
  end
133
34
  end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+ # frozen_string_literal: true
5
+
6
+ module NewRelic::Agent::Instrumentation
7
+ module Redis
8
+ module Chain
9
+ def self.instrument!
10
+ ::Redis::Client.class_eval do
11
+ include NewRelic::Agent::Instrumentation::Redis
12
+
13
+ alias_method :call_without_new_relic, :call
14
+
15
+ def call(*args, &block)
16
+ call_with_tracing(args[0]) { call_without_new_relic(*args, &block) }
17
+ end
18
+
19
+ alias_method :call_pipeline_without_new_relic, :call_pipeline
20
+
21
+ def call_pipeline(*args, &block)
22
+ call_pipeline_with_tracing(args[0]) { call_pipeline_without_new_relic(*args, &block) }
23
+ end
24
+
25
+ alias_method :connect_without_new_relic, :connect
26
+
27
+ def connect(*args, &block)
28
+ connect_with_tracing { connect_without_new_relic(*args, &block) }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+ # frozen_string_literal: true
5
+
6
+ module NewRelic::Agent::Instrumentation
7
+ module Redis
8
+ PRODUCT_NAME = 'Redis'
9
+ CONNECT = 'connect'
10
+ UNKNOWN = "unknown"
11
+ LOCALHOST = "localhost"
12
+ MULTI_OPERATION = 'multi'
13
+ PIPELINE_OPERATION = 'pipeline'
14
+
15
+ def call_with_tracing command, &block
16
+ operation = command[0]
17
+ statement = ::NewRelic::Agent::Datastores::Redis.format_command(command)
18
+
19
+ with_tracing(operation, statement) { yield }
20
+ end
21
+
22
+ def call_pipeline_with_tracing pipeline
23
+ operation = pipeline.is_a?(::Redis::Pipeline::Multi) ? MULTI_OPERATION : PIPELINE_OPERATION
24
+ statement = ::NewRelic::Agent::Datastores::Redis.format_pipeline_commands(pipeline.commands)
25
+
26
+ with_tracing(operation, statement) { yield }
27
+ end
28
+
29
+ def connect_with_tracing
30
+ with_tracing(CONNECT) { yield }
31
+ end
32
+
33
+ private
34
+
35
+ def with_tracing operation, statement=nil
36
+ segment = NewRelic::Agent::Tracer.start_datastore_segment(
37
+ product: PRODUCT_NAME,
38
+ operation: operation,
39
+ host: _nr_hostname,
40
+ port_path_or_id: _nr_port_path_or_id,
41
+ database_name: db
42
+ )
43
+ begin
44
+ segment.notice_nosql_statement(statement) if statement
45
+ NewRelic::Agent::Tracer.capture_segment_error(segment) { yield }
46
+ ensure
47
+ segment.finish if segment
48
+ end
49
+ end
50
+
51
+ def _nr_hostname
52
+ self.path ? LOCALHOST : self.host
53
+ rescue => e
54
+ NewRelic::Agent.logger.debug "Failed to retrieve Redis host: #{e}"
55
+ UNKNOWN
56
+ end
57
+
58
+ def _nr_port_path_or_id
59
+ self.path || self.port
60
+ rescue => e
61
+ NewRelic::Agent.logger.debug "Failed to retrieve Redis port_path_or_id: #{e}"
62
+ UNKNOWN
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+ # frozen_string_literal: true
5
+
6
+ module NewRelic::Agent::Instrumentation
7
+ module Redis
8
+ module Prepend
9
+ include NewRelic::Agent::Instrumentation::Redis
10
+
11
+ def call *args, &block
12
+ call_with_tracing(args[0]) { super }
13
+ end
14
+
15
+ def call_pipeline *args, &block
16
+ call_pipeline_with_tracing(args[0]) { super }
17
+ end
18
+
19
+ def connect *args, &block
20
+ connect_with_tracing { super }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -2,6 +2,10 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
4
 
5
+ require_relative 'resque/instrumentation'
6
+ require_relative 'resque/chain'
7
+ require_relative 'resque/prepend'
8
+
5
9
  DependencyDetection.defer do
6
10
  @name = :resque
7
11
 
@@ -22,34 +26,10 @@ DependencyDetection.defer do
22
26
  end
23
27
 
24
28
  executes do
25
- module ::Resque
26
- class Job
27
- include NewRelic::Agent::Instrumentation::ControllerInstrumentation
28
-
29
- alias_method :perform_without_instrumentation, :perform
30
-
31
- def perform
32
- begin
33
- perform_action_with_newrelic_trace(
34
- :name => 'perform',
35
- :class_name => self.payload_class,
36
- :category => 'OtherTransaction/ResqueJob') do
37
-
38
- NewRelic::Agent::Transaction.merge_untrusted_agent_attributes(
39
- args,
40
- :'job.resque.args',
41
- NewRelic::Agent::AttributeFilter::DST_NONE)
42
-
43
- perform_without_instrumentation
44
- end
45
- ensure
46
- # Stopping the event loop before flushing the pipe.
47
- # The goal is to avoid conflict during write.
48
- NewRelic::Agent.agent.stop_event_loop
49
- NewRelic::Agent.agent.flush_pipe_data
50
- end
51
- end
52
- end
29
+ if use_prepend?
30
+ prepend_instrument ::Resque::Job, NewRelic::Agent::Instrumentation::Resque::Prepend
31
+ else
32
+ chain_instrument NewRelic::Agent::Instrumentation::Resque::Chain
53
33
  end
54
34
 
55
35
  if NewRelic::LanguageSupport.can_fork?
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+
5
+
6
+ module NewRelic::Agent::Instrumentation
7
+ module Resque
8
+ module Chain
9
+ def self.instrument!
10
+ ::Resque::Job.class_eval do
11
+ include NewRelic::Agent::Instrumentation::Resque
12
+
13
+ alias_method :perform_without_instrumentation, :perform
14
+
15
+ def perform
16
+ with_tracing { perform_without_instrumentation }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+ # frozen_string_literal: true
5
+
6
+ module NewRelic::Agent::Instrumentation
7
+ module Resque
8
+ include NewRelic::Agent::Instrumentation::ControllerInstrumentation
9
+
10
+ def with_tracing
11
+ begin
12
+ perform_action_with_newrelic_trace(
13
+ :name => 'perform',
14
+ :class_name => self.payload_class,
15
+ :category => 'OtherTransaction/ResqueJob') do
16
+
17
+ NewRelic::Agent::Transaction.merge_untrusted_agent_attributes(
18
+ args,
19
+ :'job.resque.args',
20
+ NewRelic::Agent::AttributeFilter::DST_NONE)
21
+
22
+ yield
23
+ end
24
+ ensure
25
+ # Stopping the event loop before flushing the pipe.
26
+ # The goal is to avoid conflict during write.
27
+ NewRelic::Agent.agent.stop_event_loop
28
+ NewRelic::Agent.agent.flush_pipe_data
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+
5
+
6
+ module NewRelic::Agent::Instrumentation
7
+ module Resque
8
+ module Prepend
9
+ include NewRelic::Agent::Instrumentation::Resque
10
+
11
+ def perform
12
+ with_tracing { super }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -2,45 +2,33 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
4
 
5
- require 'new_relic/agent/instrumentation/controller_instrumentation'
6
- require 'new_relic/agent/instrumentation/sinatra/transaction_namer'
7
- require 'new_relic/agent/instrumentation/sinatra/ignorer'
8
- require 'new_relic/agent/parameter_filtering'
5
+ require_relative 'sinatra/transaction_namer'
6
+ require_relative 'sinatra/ignorer'
7
+ require_relative 'sinatra/instrumentation'
8
+ require_relative 'sinatra/chain'
9
+ require_relative 'sinatra/prepend'
9
10
 
10
11
  DependencyDetection.defer do
11
- @name = :sinatra
12
+ named :sinatra
12
13
 
13
- depends_on do
14
- !NewRelic::Agent.config[:disable_sinatra] &&
15
- defined?(::Sinatra) && defined?(::Sinatra::Base) &&
16
- Sinatra::Base.private_method_defined?(:dispatch!) &&
17
- Sinatra::Base.private_method_defined?(:process_route) &&
18
- Sinatra::Base.private_method_defined?(:route_eval)
19
- end
14
+ depends_on { defined?(::Sinatra) && defined?(::Sinatra::Base) }
15
+ depends_on { Sinatra::Base.private_method_defined?(:dispatch!) }
16
+ depends_on { Sinatra::Base.private_method_defined?(:process_route) }
17
+ depends_on { Sinatra::Base.private_method_defined?(:route_eval) }
20
18
 
21
19
  executes do
22
20
  ::NewRelic::Agent.logger.info 'Installing Sinatra instrumentation'
23
21
  end
24
22
 
25
23
  executes do
26
- ::Sinatra::Base.class_eval do
27
- include NewRelic::Agent::Instrumentation::Sinatra
28
-
29
- alias dispatch_without_newrelic dispatch!
30
- alias dispatch! dispatch_with_newrelic
31
-
32
- alias process_route_without_newrelic process_route
33
- alias process_route process_route_with_newrelic
34
-
35
- alias route_eval_without_newrelic route_eval
36
- alias route_eval route_eval_with_newrelic
37
-
38
- register NewRelic::Agent::Instrumentation::Sinatra::Ignorer
24
+ if use_prepend?
25
+ prepend_instrument ::Sinatra::Base, NewRelic::Agent::Instrumentation::Sinatra::Prepend
26
+ else
27
+ chain_instrument NewRelic::Agent::Instrumentation::Sinatra::Chain
39
28
  end
40
29
 
41
- module ::Sinatra
42
- register NewRelic::Agent::Instrumentation::Sinatra::Ignorer
43
- end
30
+ ::Sinatra::Base.class_eval { register ::NewRelic::Agent::Instrumentation::Sinatra::Ignorer }
31
+ ::Sinatra.module_eval { register NewRelic::Agent::Instrumentation::Sinatra::Ignorer }
44
32
  end
45
33
 
46
34
  executes do
@@ -49,139 +37,13 @@ DependencyDetection.defer do
49
37
  # we can't be sure that rack is available when this file is first required.
50
38
  require 'new_relic/rack/agent_hooks'
51
39
  require 'new_relic/rack/browser_monitoring'
52
-
53
- ::Sinatra::Base.class_eval do
54
- class << self
55
- alias build_without_newrelic build
56
- alias build build_with_newrelic
57
- end
40
+ if use_prepend?
41
+ prepend_instrument ::Sinatra::Base.singleton_class, NewRelic::Agent::Instrumentation::Sinatra::Build::Prepend
42
+ else
43
+ chain_instrument NewRelic::Agent::Instrumentation::Sinatra::Build::Chain
58
44
  end
59
45
  else
60
46
  ::NewRelic::Agent.logger.info("Skipping auto-injection of middleware for Sinatra - requires Sinatra 1.2.1+")
61
47
  end
62
48
  end
63
49
  end
64
-
65
- module NewRelic
66
- module Agent
67
- module Instrumentation
68
- # NewRelic instrumentation for Sinatra applications. Sinatra actions will
69
- # appear in the UI similar to controller actions, and have breakdown charts
70
- # and transaction traces.
71
- #
72
- # The actions in the UI will correspond to the pattern expression used
73
- # to match them, not directly to full URL's.
74
- module Sinatra
75
- include ::NewRelic::Agent::Instrumentation::ControllerInstrumentation
76
-
77
- # Expected method for supporting ControllerInstrumentation
78
- def newrelic_request_headers(_)
79
- request.env
80
- end
81
-
82
- def self.included(clazz)
83
- clazz.extend(ClassMethods)
84
- end
85
-
86
- module ClassMethods
87
- def newrelic_middlewares
88
- middlewares = [NewRelic::Rack::BrowserMonitoring]
89
- if NewRelic::Rack::AgentHooks.needed?
90
- middlewares << NewRelic::Rack::AgentHooks
91
- end
92
- middlewares
93
- end
94
-
95
- def build_with_newrelic(*args, &block)
96
- unless NewRelic::Agent.config[:disable_sinatra_auto_middleware]
97
- newrelic_middlewares.each do |middleware_class|
98
- try_to_use(self, middleware_class)
99
- end
100
- end
101
- build_without_newrelic(*args, &block)
102
- end
103
-
104
- def try_to_use(app, clazz)
105
- has_middleware = app.middleware.any? { |info| info[0] == clazz }
106
- app.use(clazz) unless has_middleware
107
- end
108
- end
109
-
110
- # Capture last route we've seen. Will set for transaction on route_eval
111
- def process_route_with_newrelic(*args, &block)
112
- begin
113
- env["newrelic.last_route"] = args[0]
114
- rescue => e
115
- ::NewRelic::Agent.logger.debug("Failed determining last route in Sinatra", e)
116
- end
117
-
118
- process_route_without_newrelic(*args, &block)
119
- end
120
-
121
- # If a transaction name is already set, this call will tromple over it.
122
- # This is intentional, as typically passing to a separate route is like
123
- # an entirely separate transaction, so we pick up the new name.
124
- #
125
- # If we're ignored, this remains safe, since set_transaction_name
126
- # care for the gating on the transaction's existence for us.
127
- def route_eval_with_newrelic(*args, &block)
128
- begin
129
- txn_name = TransactionNamer.transaction_name_for_route(env, request)
130
- unless txn_name.nil?
131
- ::NewRelic::Agent::Transaction.set_default_transaction_name(
132
- "#{self.class.name}/#{txn_name}", :sinatra)
133
- end
134
- rescue => e
135
- ::NewRelic::Agent.logger.debug("Failed during route_eval to set transaction name", e)
136
- end
137
-
138
- route_eval_without_newrelic(*args, &block)
139
- end
140
-
141
- def dispatch_with_newrelic #THREAD_LOCAL_ACCESS
142
- request_params = get_request_params
143
- filtered_params = ParameterFiltering::apply_filters(request.env, request_params || {})
144
-
145
- name = TransactionNamer.initial_transaction_name(request)
146
- perform_action_with_newrelic_trace(:category => :sinatra,
147
- :name => name,
148
- :params => filtered_params) do
149
- dispatch_and_notice_errors_with_newrelic
150
- end
151
- end
152
-
153
- def get_request_params
154
- begin
155
- @request.params
156
- rescue => e
157
- NewRelic::Agent.logger.debug("Failed to get params from Rack request.", e)
158
- nil
159
- end
160
- end
161
-
162
- def dispatch_and_notice_errors_with_newrelic
163
- dispatch_without_newrelic
164
- ensure
165
- # Will only see an error raised if :show_exceptions is true, but
166
- # will always see them in the env hash if they occur
167
- had_error = env.has_key?('sinatra.error')
168
- ::NewRelic::Agent.notice_error(env['sinatra.error']) if had_error
169
- end
170
-
171
- def do_not_trace?
172
- Ignorer.should_ignore?(self, :routes)
173
- end
174
-
175
- # Overrides ControllerInstrumentation implementation
176
- def ignore_apdex?
177
- Ignorer.should_ignore?(self, :apdex)
178
- end
179
-
180
- # Overrides ControllerInstrumentation implementation
181
- def ignore_enduser?
182
- Ignorer.should_ignore?(self, :enduser)
183
- end
184
- end
185
- end
186
- end
187
- end