newrelic_rpm 6.13.0 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +231 -0
  4. data/CONTRIBUTING.md +13 -2
  5. data/README.md +2 -2
  6. data/lib/new_relic/agent.rb +5 -8
  7. data/lib/new_relic/agent/agent.rb +4 -5
  8. data/lib/new_relic/agent/audit_logger.rb +10 -0
  9. data/lib/new_relic/agent/autostart.rb +1 -2
  10. data/lib/new_relic/agent/configuration/default_source.rb +412 -220
  11. data/lib/new_relic/agent/configuration/manager.rb +2 -2
  12. data/lib/new_relic/agent/database_adapter.rb +33 -0
  13. data/lib/new_relic/agent/datastores/redis.rb +0 -4
  14. data/lib/new_relic/agent/distributed_tracing.rb +0 -66
  15. data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +2 -2
  16. data/lib/new_relic/agent/http_clients/uri_util.rb +1 -1
  17. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +4 -5
  18. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +21 -68
  19. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +0 -16
  20. data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +23 -57
  21. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +1 -3
  22. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +0 -15
  23. data/lib/new_relic/agent/instrumentation/bunny.rb +10 -196
  24. data/lib/new_relic/agent/instrumentation/bunny/chain.rb +45 -0
  25. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +152 -0
  26. data/lib/new_relic/agent/instrumentation/bunny/prepend.rb +35 -0
  27. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +1 -0
  28. data/lib/new_relic/agent/instrumentation/curb.rb +9 -259
  29. data/lib/new_relic/agent/instrumentation/curb/chain.rb +93 -0
  30. data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +222 -0
  31. data/lib/new_relic/agent/instrumentation/curb/prepend.rb +63 -0
  32. data/lib/new_relic/agent/instrumentation/delayed_job/chain.rb +38 -0
  33. data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +53 -0
  34. data/lib/new_relic/agent/instrumentation/delayed_job/prepend.rb +34 -0
  35. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +8 -84
  36. data/lib/new_relic/agent/instrumentation/excon.rb +2 -1
  37. data/lib/new_relic/agent/instrumentation/grape.rb +13 -113
  38. data/lib/new_relic/agent/instrumentation/grape/chain.rb +25 -0
  39. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +100 -0
  40. data/lib/new_relic/agent/instrumentation/grape/prepend.rb +17 -0
  41. data/lib/new_relic/agent/instrumentation/httpclient.rb +8 -30
  42. data/lib/new_relic/agent/instrumentation/httpclient/chain.rb +25 -0
  43. data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +38 -0
  44. data/lib/new_relic/agent/instrumentation/httpclient/prepend.rb +17 -0
  45. data/lib/new_relic/agent/instrumentation/httprb.rb +29 -0
  46. data/lib/new_relic/agent/instrumentation/httprb/chain.rb +22 -0
  47. data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +30 -0
  48. data/lib/new_relic/agent/instrumentation/httprb/prepend.rb +15 -0
  49. data/lib/new_relic/agent/instrumentation/memcache.rb +54 -69
  50. data/lib/new_relic/agent/instrumentation/memcache/chain.rb +16 -0
  51. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +38 -121
  52. data/lib/new_relic/agent/instrumentation/memcache/helper.rb +56 -0
  53. data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +88 -0
  54. data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +88 -0
  55. data/lib/new_relic/agent/instrumentation/middleware_proxy.rb +4 -10
  56. data/lib/new_relic/agent/instrumentation/mongo.rb +7 -0
  57. data/lib/new_relic/agent/instrumentation/net_http.rb +44 -0
  58. data/lib/new_relic/agent/instrumentation/net_http/chain.rb +25 -0
  59. data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +40 -0
  60. data/lib/new_relic/agent/instrumentation/net_http/prepend.rb +21 -0
  61. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +1 -1
  62. data/lib/new_relic/agent/instrumentation/padrino.rb +18 -75
  63. data/lib/new_relic/agent/instrumentation/padrino/chain.rb +34 -0
  64. data/lib/new_relic/agent/instrumentation/padrino/instrumentation.rb +27 -0
  65. data/lib/new_relic/agent/instrumentation/padrino/prepend.rb +20 -0
  66. data/lib/new_relic/agent/instrumentation/rack.rb +29 -160
  67. data/lib/new_relic/agent/instrumentation/rack/chain.rb +57 -0
  68. data/lib/new_relic/agent/instrumentation/rack/helpers.rb +32 -0
  69. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +73 -0
  70. data/lib/new_relic/agent/instrumentation/rack/prepend.rb +36 -0
  71. data/lib/new_relic/agent/instrumentation/rake.rb +13 -188
  72. data/lib/new_relic/agent/instrumentation/rake/chain.rb +25 -0
  73. data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +144 -0
  74. data/lib/new_relic/agent/instrumentation/rake/prepend.rb +14 -0
  75. data/lib/new_relic/agent/instrumentation/redis.rb +12 -186
  76. data/lib/new_relic/agent/instrumentation/redis/chain.rb +34 -0
  77. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +65 -0
  78. data/lib/new_relic/agent/instrumentation/redis/prepend.rb +24 -0
  79. data/lib/new_relic/agent/instrumentation/resque.rb +21 -32
  80. data/lib/new_relic/agent/instrumentation/resque/chain.rb +22 -0
  81. data/lib/new_relic/agent/instrumentation/resque/helper.rb +19 -0
  82. data/lib/new_relic/agent/instrumentation/resque/instrumentation.rb +35 -0
  83. data/lib/new_relic/agent/instrumentation/resque/prepend.rb +16 -0
  84. data/lib/new_relic/agent/instrumentation/sidekiq.rb +1 -1
  85. data/lib/new_relic/agent/instrumentation/sinatra.rb +20 -198
  86. data/lib/new_relic/agent/instrumentation/sinatra/chain.rb +55 -0
  87. data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +29 -34
  88. data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +124 -0
  89. data/lib/new_relic/agent/instrumentation/sinatra/prepend.rb +33 -0
  90. data/lib/new_relic/agent/instrumentation/typhoeus.rb +10 -89
  91. data/lib/new_relic/agent/instrumentation/typhoeus/chain.rb +22 -0
  92. data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +82 -0
  93. data/lib/new_relic/agent/instrumentation/typhoeus/prepend.rb +14 -0
  94. data/lib/new_relic/agent/javascript_instrumentor.rb +12 -7
  95. data/lib/new_relic/agent/method_tracer.rb +6 -16
  96. data/lib/new_relic/agent/new_relic_service.rb +16 -13
  97. data/lib/new_relic/agent/samplers/memory_sampler.rb +1 -1
  98. data/lib/new_relic/agent/span_event_primitive.rb +10 -8
  99. data/lib/new_relic/agent/sql_sampler.rb +3 -3
  100. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +1 -1
  101. data/lib/new_relic/agent/transaction.rb +1 -4
  102. data/lib/new_relic/agent/transaction/abstract_segment.rb +1 -1
  103. data/lib/new_relic/agent/transaction/distributed_tracer.rb +12 -6
  104. data/lib/new_relic/agent/transaction/message_broker_segment.rb +1 -0
  105. data/lib/new_relic/agent/vm/mri_vm.rb +6 -4
  106. data/lib/new_relic/cli/commands/deployments.rb +0 -1
  107. data/lib/new_relic/constants.rb +4 -0
  108. data/lib/new_relic/control/frameworks/rails.rb +11 -9
  109. data/lib/new_relic/control/instance_methods.rb +1 -0
  110. data/lib/new_relic/dependency_detection.rb +119 -9
  111. data/lib/new_relic/environment_report.rb +1 -7
  112. data/lib/new_relic/noticed_error.rb +1 -5
  113. data/lib/new_relic/supportability_helper.rb +3 -2
  114. data/lib/new_relic/version.rb +2 -2
  115. data/lib/tasks/config.html.erb +14 -25
  116. data/lib/tasks/config.rake +8 -7
  117. data/newrelic_rpm.gemspec +2 -2
  118. data/test/agent_helper.rb +1 -0
  119. metadata +55 -32
  120. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
  121. data/.github/ISSUE_TEMPLATE/config.yml +0 -5
  122. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -24
  123. data/.github/actions/annotate/README.md +0 -79
  124. data/.github/actions/annotate/action.yml +0 -6
  125. data/.github/actions/annotate/dist/index.js +0 -433
  126. data/.github/actions/annotate/index.js +0 -25
  127. data/.github/actions/annotate/package-lock.json +0 -172
  128. data/.github/actions/annotate/package.json +0 -30
  129. data/.github/actions/annotate/pre-commit +0 -5
  130. data/.github/actions/build-ruby/README.md +0 -79
  131. data/.github/actions/build-ruby/action.yml +0 -15
  132. data/.github/actions/build-ruby/dist/index.js +0 -52683
  133. data/.github/actions/build-ruby/index.js +0 -514
  134. data/.github/actions/build-ruby/package-lock.json +0 -581
  135. data/.github/actions/build-ruby/package.json +0 -32
  136. data/.github/actions/build-ruby/pre-commit +0 -5
  137. data/.github/pull_request_template.md +0 -16
  138. data/.github/workflows/ci.yml +0 -212
  139. data/.github/workflows/pr_review_checklist.yml +0 -22
  140. data/.github/workflows/release.yml +0 -78
  141. data/.github/workflows/scripts/rubygems-authenticate.py +0 -13
  142. data/.github/workflows/scripts/rubygems-publish.rb +0 -32
  143. data/.github/workflows/snyk.yml +0 -27
  144. data/.github/workflows/stale.yml +0 -21
  145. data/cert/cacert.pem +0 -1177
  146. data/lib/new_relic/agent/instrumentation/http.rb +0 -49
  147. data/lib/new_relic/agent/instrumentation/net.rb +0 -87
@@ -0,0 +1,57 @@
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 Rack
7
+ module Chain
8
+ def self.instrument! builder_class
9
+ NewRelic::Agent::Instrumentation::RackBuilder.track_deferred_detection builder_class
10
+
11
+ builder_class.class_eval do
12
+ include ::NewRelic::Agent::Instrumentation::RackBuilder
13
+
14
+ def to_app_with_newrelic_deferred_dependency_detection
15
+ with_deferred_dependency_detection { to_app_without_newrelic }
16
+ end
17
+
18
+ alias_method :to_app_without_newrelic, :to_app
19
+ alias_method :to_app, :to_app_with_newrelic_deferred_dependency_detection
20
+
21
+ if ::NewRelic::Agent::Instrumentation::RackHelpers.middleware_instrumentation_enabled?
22
+ ::NewRelic::Agent.logger.info "Installing #{builder_class} middleware instrumentation"
23
+
24
+ def run_with_newrelic(app, *args)
25
+ run_with_tracing(app) { |wrapped_app| run_without_newrelic(wrapped_app, *args) }
26
+ end
27
+
28
+ alias_method :run_without_newrelic, :run
29
+ alias_method :run, :run_with_newrelic
30
+
31
+ def use_with_newrelic(middleware_class, *args, &block)
32
+ use_with_tracing(middleware_class) { |wrapped_class| use_without_newrelic(wrapped_class, *args, &block) }
33
+ end
34
+
35
+ alias_method :use_without_newrelic, :use
36
+ alias_method :use, :use_with_newrelic
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ module URLMap
43
+ module Chain
44
+ def self.instrument! url_map_class
45
+ url_map_class.class_eval do
46
+ alias_method :initialize_without_newrelic, :initialize
47
+
48
+ def initialize(map = {})
49
+ traced_map = ::NewRelic::Agent::Instrumentation::RackURLMap.generate_traced_map(map)
50
+ initialize_without_newrelic(traced_map)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,32 @@
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 RackHelpers
7
+ def self.version_supported?
8
+ rack_version_supported? || puma_rack_version_supported?
9
+ end
10
+
11
+ def self.rack_version_supported?
12
+ return false unless defined? ::Rack
13
+
14
+ version = Gem::Version.new(::Rack.release)
15
+ min_version = Gem::Version.new('1.1.0')
16
+ version >= min_version
17
+ end
18
+
19
+ def self.puma_rack_version_supported?
20
+ return false unless defined? ::Puma::Const::PUMA_VERSION
21
+
22
+ version = Gem::Version.new(::Puma::Const::PUMA_VERSION)
23
+ min_version = Gem::Version.new('2.12.0')
24
+ version >= min_version
25
+ end
26
+
27
+ def self.middleware_instrumentation_enabled?
28
+ version_supported? && !::NewRelic::Agent.config[:disable_middleware_instrumentation]
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,73 @@
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
6
+ module Agent
7
+ module Instrumentation
8
+ module RackBuilder
9
+
10
+ def self.track_deferred_detection builder_class
11
+ class << builder_class
12
+ attr_accessor :_nr_deferred_detection_ran
13
+ end
14
+ builder_class._nr_deferred_detection_ran = false
15
+ end
16
+
17
+ def deferred_dependency_check
18
+ return if self.class._nr_deferred_detection_ran
19
+
20
+ NewRelic::Agent.logger.info "Doing deferred dependency-detection before Rack startup"
21
+ DependencyDetection.detect!
22
+ self.class._nr_deferred_detection_ran = true
23
+ end
24
+
25
+ def check_for_late_instrumentation(app)
26
+ return if defined?(@checked_for_late_instrumentation) && @checked_for_late_instrumentation
27
+ @checked_for_late_instrumentation = true
28
+ if middleware_instrumentation_enabled?
29
+ if ::NewRelic::Agent::Instrumentation::MiddlewareProxy.needs_wrapping?(app)
30
+ ::NewRelic::Agent.logger.info("We weren't able to instrument all of your Rack middlewares.",
31
+ "To correct this, ensure you 'require \"newrelic_rpm\"' before setting up your middleware stack.")
32
+ end
33
+ end
34
+ end
35
+
36
+ # We patch the #to_app method for a reason that actually has nothing to do with
37
+ # instrumenting rack itself. It happens to be a convenient and
38
+ # easy-to-hook point that happens late in the startup sequence of almost
39
+ # every application, making it a good place to do a final call to
40
+ # DependencyDetection.detect!, since all libraries are likely loaded at
41
+ # this point.
42
+ def with_deferred_dependency_detection
43
+ deferred_dependency_check
44
+ yield.tap{ |result| check_for_late_instrumentation(result) }
45
+ end
46
+
47
+ def middleware_instrumentation_enabled?
48
+ ::NewRelic::Agent::Instrumentation::RackHelpers.middleware_instrumentation_enabled?
49
+ end
50
+
51
+ def run_with_tracing app
52
+ return yield(app) unless middleware_instrumentation_enabled?
53
+ yield ::NewRelic::Agent::Instrumentation::MiddlewareProxy.wrap(app, true)
54
+ end
55
+
56
+ def use_with_tracing middleware_class
57
+ return if middleware_class.nil?
58
+ return yield(middleware_class) unless middleware_instrumentation_enabled?
59
+ yield ::NewRelic::Agent::Instrumentation::MiddlewareProxy.for_class(middleware_class)
60
+ end
61
+ end
62
+
63
+ module RackURLMap
64
+ def self.generate_traced_map(map)
65
+ map.inject({}) do |traced_map, (url, handler)|
66
+ traced_map[url] = NewRelic::Agent::Instrumentation::MiddlewareProxy.wrap(handler, true)
67
+ traced_map
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,36 @@
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 Rack
7
+
8
+ module URLMap
9
+ module Prepend
10
+ def initialize(map = {})
11
+ super ::NewRelic::Agent::Instrumentation::RackURLMap.generate_traced_map(map)
12
+ end
13
+ end
14
+ end
15
+
16
+ module Prepend
17
+ include ::NewRelic::Agent::Instrumentation::RackBuilder
18
+
19
+ def self.prepended builder_class
20
+ NewRelic::Agent::Instrumentation::RackBuilder.track_deferred_detection builder_class
21
+ end
22
+
23
+ def to_app
24
+ with_deferred_dependency_detection { super }
25
+ end
26
+
27
+ def run(app, *args)
28
+ run_with_tracing(app) { |wrapped_app| super(wrapped_app, *args) }
29
+ end
30
+
31
+ def use(middleware_class, *args, &blk)
32
+ use_with_tracing(middleware_class) { |wrapped_class| super(wrapped_class, *args, &blk) }
33
+ end
34
+ end
35
+ end
36
+ end
@@ -2,17 +2,19 @@
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 'rake/instrumentation'
6
+ require_relative 'rake/chain'
7
+ require_relative 'rake/prepend'
8
+
5
9
  DependencyDetection.defer do
6
10
  # Why not :rake? newrelic-rake used that name, so avoid conflicting
7
11
  named :rake_instrumentation
12
+ configure_with :rake
8
13
 
9
- depends_on do
10
- defined?(::Rake) &&
11
- defined?(::Rake::VERSION) &&
12
- ::NewRelic::Agent.config[:'disable_rake'] == false &&
13
- ::NewRelic::Agent.config[:'rake.tasks'].any? &&
14
- ::NewRelic::Agent::Instrumentation::RakeInstrumentation.should_install?
15
- end
14
+ depends_on { defined?(::Rake) && defined?(::Rake::VERSION) }
15
+ depends_on { Gem::Version.new(::Rake::VERSION) >= Gem::Version.new("10.0.0") }
16
+ depends_on { ::NewRelic::Agent.config[:'rake.tasks'].any? }
17
+ depends_on { ::NewRelic::Agent::Instrumentation::Rake.safe_from_third_party_gem? }
16
18
 
17
19
  executes do
18
20
  ::NewRelic::Agent.logger.info "Installing Rake instrumentation"
@@ -20,187 +22,10 @@ DependencyDetection.defer do
20
22
  end
21
23
 
22
24
  executes do
23
- module Rake
24
- class Task
25
- alias_method :invoke_without_newrelic, :invoke
26
-
27
-
28
- if RUBY_VERSION < "2.7.0"
29
- def invoke(*args)
30
- unless NewRelic::Agent::Instrumentation::RakeInstrumentation.should_trace? name
31
- return invoke_without_newrelic(*args)
32
- end
33
-
34
- begin
35
- timeout = NewRelic::Agent.config[:'rake.connect_timeout']
36
- NewRelic::Agent.instance.wait_on_connect(timeout)
37
- rescue => e
38
- NewRelic::Agent.logger.error("Exception in wait_on_connect", e)
39
- return invoke_without_newrelic(*args)
40
- end
41
-
42
- NewRelic::Agent::Instrumentation::RakeInstrumentation.before_invoke_transaction(self)
43
-
44
- NewRelic::Agent::Tracer.in_transaction(name: "OtherTransaction/Rake/invoke/#{name}", category: :rake) do
45
- NewRelic::Agent::Instrumentation::RakeInstrumentation.record_attributes(args, self)
46
- invoke_without_newrelic(*args)
47
- end
48
- end
49
- else
50
- def invoke(*args, **kwargs)
51
- unless NewRelic::Agent::Instrumentation::RakeInstrumentation.should_trace? name
52
- return invoke_without_newrelic(*args, **kwargs)
53
- end
54
-
55
- begin
56
- timeout = NewRelic::Agent.config[:'rake.connect_timeout']
57
- NewRelic::Agent.instance.wait_on_connect(timeout)
58
- rescue => e
59
- NewRelic::Agent.logger.error("Exception in wait_on_connect", e)
60
- return invoke_without_newrelic(*args, **kwargs)
61
- end
62
-
63
- NewRelic::Agent::Instrumentation::RakeInstrumentation.before_invoke_transaction(self)
64
-
65
- NewRelic::Agent::Tracer.in_transaction(name: "OtherTransaction/Rake/invoke/#{name}", category: :rake) do
66
- NewRelic::Agent::Instrumentation::RakeInstrumentation.record_attributes(args, self)
67
- invoke_without_newrelic(*args, **kwargs)
68
- end
69
- end
70
- end
71
-
72
- end
73
- end
74
- end
75
- end
76
-
77
- module NewRelic
78
- module Agent
79
- module Instrumentation
80
- module RakeInstrumentation
81
- def self.should_install?
82
- is_supported_version? && safe_from_third_party_gem?
83
- end
84
-
85
- def self.is_supported_version?
86
- Gem::Version.new(::Rake::VERSION) >= Gem::Version.new("10.0.0")
87
- end
88
-
89
- def self.safe_from_third_party_gem?
90
- if NewRelic::LanguageSupport.bundled_gem?("newrelic-rake")
91
- ::NewRelic::Agent.logger.info("Not installing New Relic supported Rake instrumentation because the third party newrelic-rake gem is present")
92
- false
93
- else
94
- true
95
- end
96
- end
97
-
98
- def self.should_trace?(name)
99
- NewRelic::Agent.config[:'rake.tasks'].any? do |regex|
100
- regex.match(name)
101
- end
102
- end
103
-
104
- def self.instrument_execute_on_prereqs(task)
105
- task.prerequisite_tasks.each do |child_task|
106
- instrument_execute(child_task)
107
- end
108
- end
109
-
110
- def self.instrument_execute(task)
111
- return if task.instance_variable_get(:@__newrelic_instrumented_execute)
112
-
113
- task.instance_variable_set(:@__newrelic_instrumented_execute, true)
114
- task.instance_eval do
115
- if RUBY_VERSION < "2.7.0"
116
- def execute(*args, &block)
117
- NewRelic::Agent::MethodTracer.trace_execution_scoped("Rake/execute/#{self.name}") do
118
- super
119
- end
120
- end
121
- else
122
- def execute(*args, **kwargs, &block)
123
- NewRelic::Agent::MethodTracer.trace_execution_scoped("Rake/execute/#{self.name}") do
124
- super
125
- end
126
- end
127
- end
128
-
129
- end
130
-
131
- instrument_execute_on_prereqs(task)
132
- end
133
-
134
- def self.instrument_invoke_prerequisites_concurrently(task)
135
- task.instance_eval do
136
- def invoke_prerequisites_concurrently(*_)
137
- NewRelic::Agent::MethodTracer.trace_execution_scoped("Rake/execute/multitask") do
138
- prereqs = self.prerequisite_tasks.map(&:name).join(", ")
139
- if txn = ::NewRelic::Agent::Tracer.current_transaction
140
- txn.current_segment.params[:statement] = NewRelic::Agent::Database.truncate_query("Couldn't trace concurrent prereq tasks: #{prereqs}")
141
- end
142
- super
143
- end
144
- end
145
- end
146
- end
147
-
148
- def self.before_invoke_transaction(task)
149
- ensure_at_exit
150
-
151
- # We can't represent overlapping operations yet, so if multitask just
152
- # make one node and annotate with prereq task names
153
- if task.application.options.always_multitask
154
- instrument_invoke_prerequisites_concurrently(task)
155
- else
156
- instrument_execute_on_prereqs(task)
157
- end
158
- rescue => e
159
- NewRelic::Agent.logger.error("Error during Rake task invoke", e)
160
- end
161
-
162
- def self.record_attributes(args, task)
163
- command_line = task.application.top_level_tasks.join(" ")
164
- NewRelic::Agent::Transaction.merge_untrusted_agent_attributes({ :command => command_line },
165
- :'job.rake',
166
- NewRelic::Agent::AttributeFilter::DST_NONE)
167
- named_args = name_the_args(args, task.arg_names)
168
- unless named_args.empty?
169
- NewRelic::Agent::Transaction.merge_untrusted_agent_attributes(named_args,
170
- :'job.rake.args',
171
- NewRelic::Agent::AttributeFilter::DST_NONE)
172
- end
173
- rescue => e
174
- NewRelic::Agent.logger.error("Error during Rake task attribute recording.", e)
175
- end
176
-
177
- # Expects literal args passed to the task and array of task names
178
- # If names are present without matching args, still sets them with nils
179
- def self.name_the_args(args, names)
180
- unfulfilled_names_length = names.length - args.length
181
- if unfulfilled_names_length > 0
182
- args.concat(Array.new(unfulfilled_names_length))
183
- end
184
-
185
- result = {}
186
- args.zip(names).each_with_index do |(value, key), index|
187
- result[key || index.to_s] = value
188
- end
189
- result
190
- end
191
-
192
- def self.ensure_at_exit
193
- return if @installed_at_exit
194
-
195
- at_exit do
196
- # The agent's default at_exit might not default to installing, but
197
- # if we are running an instrumented rake task, we always want it.
198
- NewRelic::Agent.shutdown
199
- end
200
-
201
- @installed_at_exit = true
202
- end
203
- end
25
+ if use_prepend?
26
+ prepend_instrument ::Rake::Task, NewRelic::Agent::Instrumentation::Rake::Prepend
27
+ else
28
+ chain_instrument NewRelic::Agent::Instrumentation::Rake::Chain
204
29
  end
205
30
  end
206
31
  end
@@ -0,0 +1,25 @@
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 Chain
8
+ def self.instrument!
9
+ ::Rake::Task.class_eval do
10
+ include NewRelic::Agent::Instrumentation::Rake::Tracer
11
+ alias_method :invoke_without_newrelic, :invoke
12
+
13
+ def invoke(*args)
14
+ invoke_with_newrelic_tracing(*args) { invoke_without_newrelic(*args) }
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+
23
+
24
+
25
+