newrelic_rpm 9.23.0 → 10.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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +136 -0
  3. data/README.md +0 -7
  4. data/lib/new_relic/agent/agent.rb +9 -4
  5. data/lib/new_relic/agent/configuration/default_source.rb +103 -181
  6. data/lib/new_relic/agent/configuration/environment_source.rb +7 -38
  7. data/lib/new_relic/agent/configuration/manager.rb +141 -59
  8. data/lib/new_relic/agent/configuration/sampler_config_validator.rb +54 -0
  9. data/lib/new_relic/agent/configuration/server_source.rb +0 -1
  10. data/lib/new_relic/agent/connect/response_handler.rb +0 -11
  11. data/lib/new_relic/agent/datastores.rb +13 -17
  12. data/lib/new_relic/agent/distributed_tracing.rb +0 -3
  13. data/lib/new_relic/agent/health_check.rb +1 -0
  14. data/lib/new_relic/agent/instrumentation/active_job.rb +1 -1
  15. data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +2 -1
  16. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +1 -4
  17. data/lib/new_relic/agent/instrumentation/active_support.rb +8 -1
  18. data/lib/new_relic/agent/instrumentation/active_support_subscriber.rb +22 -14
  19. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +1 -4
  20. data/lib/new_relic/agent/instrumentation/bunny.rb +0 -1
  21. data/lib/new_relic/agent/instrumentation/curb/chain.rb +2 -2
  22. data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +2 -3
  23. data/lib/new_relic/agent/instrumentation/curb.rb +0 -1
  24. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +1 -1
  25. data/lib/new_relic/agent/instrumentation/excon.rb +2 -3
  26. data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +1 -2
  27. data/lib/new_relic/agent/instrumentation/httpclient.rb +0 -1
  28. data/lib/new_relic/agent/instrumentation/httprb.rb +0 -1
  29. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +0 -2
  30. data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +0 -2
  31. data/lib/new_relic/agent/instrumentation/rack/helpers.rb +1 -3
  32. data/lib/new_relic/agent/instrumentation/typhoeus.rb +0 -1
  33. data/lib/new_relic/agent/llm/chat_completion_summary.rb +1 -8
  34. data/lib/new_relic/agent/llm/embedding.rb +1 -8
  35. data/lib/new_relic/agent/messaging.rb +12 -5
  36. data/lib/new_relic/agent/monitors/inbound_request_monitor.rb +1 -2
  37. data/lib/new_relic/agent/monitors/synthetics_monitor.rb +2 -1
  38. data/lib/new_relic/agent/monitors.rb +0 -3
  39. data/lib/new_relic/agent/new_relic_service/encoders.rb +0 -14
  40. data/lib/new_relic/agent/new_relic_service.rb +11 -49
  41. data/lib/new_relic/agent/opentelemetry/trace/span.rb +41 -0
  42. data/lib/new_relic/agent/opentelemetry/trace/tracer.rb +16 -7
  43. data/lib/new_relic/agent/opentelemetry_bridge.rb +9 -5
  44. data/lib/new_relic/agent/serverless_handler.rb +2 -2
  45. data/lib/new_relic/agent/span_event_primitive.rb +1 -1
  46. data/lib/new_relic/agent/sql_sampler.rb +0 -31
  47. data/lib/new_relic/agent/stats_engine.rb +1 -0
  48. data/lib/new_relic/agent/transaction/distributed_tracer.rb +12 -56
  49. data/lib/new_relic/agent/transaction/distributed_tracing.rb +11 -19
  50. data/lib/new_relic/agent/transaction/external_request_segment.rb +1 -131
  51. data/lib/new_relic/agent/transaction/message_broker_segment.rb +0 -2
  52. data/lib/new_relic/agent/transaction/trace_context.rb +33 -11
  53. data/lib/new_relic/agent/transaction.rb +35 -4
  54. data/lib/new_relic/agent/transaction_error_primitive.rb +0 -8
  55. data/lib/new_relic/agent/transaction_event_primitive.rb +0 -14
  56. data/lib/new_relic/agent/utilization/gcp.rb +2 -0
  57. data/lib/new_relic/agent.rb +11 -3
  58. data/lib/new_relic/cli/command.rb +2 -11
  59. data/lib/new_relic/control/instance_methods.rb +2 -15
  60. data/lib/new_relic/control/private_instance_methods.rb +2 -4
  61. data/lib/new_relic/control/server_methods.rb +0 -6
  62. data/lib/new_relic/helper.rb +21 -2
  63. data/lib/new_relic/language_support.rb +3 -34
  64. data/lib/new_relic/supportability_helper.rb +0 -4
  65. data/lib/new_relic/version.rb +2 -2
  66. data/lib/tasks/helpers/newrelicyml.rb +2 -2
  67. data/lib/tasks/helpers/version_bump.rb +1 -2
  68. data/newrelic.yml +25 -28
  69. data/newrelic_rpm.gemspec +10 -9
  70. metadata +27 -26
  71. data/bin/newrelic +0 -8
  72. data/lib/new_relic/agent/configuration/security_policy_source.rb +0 -246
  73. data/lib/new_relic/agent/distributed_tracing/cross_app_payload.rb +0 -44
  74. data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +0 -253
  75. data/lib/new_relic/agent/external.rb +0 -112
  76. data/lib/new_relic/agent/monitors/cross_app_monitor.rb +0 -117
  77. data/lib/new_relic/agent/new_relic_service/security_policy_settings.rb +0 -61
  78. data/lib/new_relic/cli/commands/deployments.rb +0 -206
  79. data/lib/new_relic/recipes/capistrano3.rb +0 -23
  80. data/lib/new_relic/recipes/capistrano_legacy.rb +0 -95
  81. data/lib/new_relic/recipes/helpers/send_deployment.rb +0 -70
  82. data/lib/new_relic/recipes.rb +0 -24
  83. data/recipes/newrelic.rb +0 -10
@@ -1,117 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- require 'digest'
6
- require 'json'
7
-
8
- require 'new_relic/agent/tracer'
9
- require 'new_relic/agent/threading/agent_thread'
10
-
11
- module NewRelic
12
- module Agent
13
- module DistributedTracing
14
- class CrossAppMonitor < InboundRequestMonitor
15
- NEWRELIC_TXN_HEADER = 'X-NewRelic-Transaction'.freeze
16
- NEWRELIC_APPDATA_HEADER = 'X-NewRelic-App-Data'.freeze
17
-
18
- NEWRELIC_ID_HEADER_KEY = 'HTTP_X_NEWRELIC_ID'.freeze
19
- NEWRELIC_TXN_HEADER_KEY = 'HTTP_X_NEWRELIC_TRANSACTION'.freeze
20
- CONTENT_LENGTH_HEADER_KEY = 'HTTP_CONTENT_LENGTH'.freeze
21
-
22
- def on_finished_configuring(events)
23
- if CrossAppTracing.cross_app_enabled?
24
- Deprecator.deprecate('cross_application_tracer')
25
- ::NewRelic::Agent.logger.warn(
26
- '[DEPRECATED] Cross application tracing is enabled. Distributed tracing is replacing cross application tracing as the default means of tracing between services. To continue using cross application tracing, enable it with `cross_application_tracer.enabled: true` and `distributed_tracing.enabled: false`'
27
- )
28
- end
29
-
30
- register_event_listeners(events)
31
- end
32
-
33
- def path_hash(txn_name, seed)
34
- rotated = ((seed << 1) | (seed >> 31)) & 0xffffffff
35
- app_name = NewRelic::Agent.config[:app_name].first
36
- identifier = "#{app_name};#{txn_name}"
37
- sprintf('%08x', rotated ^ hash_transaction_name(identifier))
38
- end
39
-
40
- private
41
-
42
- # Expected sequence of events:
43
- # :before_call will save our cross application request id to the thread
44
- # :after_call will write our response headers/metrics and clean up the thread
45
- def register_event_listeners(events)
46
- NewRelic::Agent.logger
47
- .debug('Wiring up Cross Application Tracing to events after finished configuring')
48
-
49
- events.subscribe(:before_call) do |env| # THREAD_LOCAL_ACCESS
50
- if id = decoded_id(env) and should_process_request?(id)
51
- state = NewRelic::Agent::Tracer.state
52
-
53
- if (txn = state.current_transaction)
54
- transaction_info = referring_transaction_info(state, env)
55
-
56
- payload = CrossAppPayload.new(id, txn, transaction_info)
57
- txn.distributed_tracer.cross_app_payload = payload
58
- end
59
-
60
- CrossAppTracing.assign_intrinsic_transaction_attributes(state)
61
- end
62
- end
63
-
64
- events.subscribe(:after_call) do |env, (_status_code, headers, _body)| # THREAD_LOCAL_ACCESS
65
- state = NewRelic::Agent::Tracer.state
66
-
67
- insert_response_header(state, env, headers)
68
- end
69
- end
70
-
71
- def referring_transaction_info(state, request_headers)
72
- txn_header = request_headers[NEWRELIC_TXN_HEADER_KEY] or return
73
- deserialize_header(txn_header, NEWRELIC_TXN_HEADER)
74
- end
75
-
76
- def insert_response_header(state, request_headers, response_headers)
77
- txn = state.current_transaction
78
- unless txn.nil? || txn.distributed_tracer.cross_app_payload.nil?
79
- txn.freeze_name_and_execute_if_not_ignored do
80
- content_length = content_length_from_request(request_headers)
81
- set_response_headers(txn, response_headers, content_length)
82
- end
83
- end
84
- end
85
-
86
- def should_process_request?(id)
87
- CrossAppTracing.cross_app_enabled? && CrossAppTracing.trusts?(id)
88
- end
89
-
90
- def set_response_headers(transaction, response_headers, content_length)
91
- payload = obfuscator.obfuscate(
92
- ::JSON.dump(
93
- transaction.distributed_tracer.cross_app_payload.as_json_array(content_length)
94
- )
95
- )
96
-
97
- response_headers[NEWRELIC_APPDATA_HEADER] = payload
98
- end
99
-
100
- def decoded_id(request)
101
- encoded_id = request[NEWRELIC_ID_HEADER_KEY]
102
- return NewRelic::EMPTY_STR if encoded_id.nil? || encoded_id.empty?
103
-
104
- obfuscator.deobfuscate(encoded_id)
105
- end
106
-
107
- def content_length_from_request(request)
108
- request[CONTENT_LENGTH_HEADER_KEY] || -1
109
- end
110
-
111
- def hash_transaction_name(identifier)
112
- Digest::MD5.digest(identifier).unpack('@12N').first & 0xffffffff
113
- end
114
- end
115
- end
116
- end
117
- end
@@ -1,61 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- module NewRelic
6
- module Agent
7
- class NewRelicService
8
- module SecurityPolicySettings
9
- EXPECTED_SECURITY_POLICIES = %w[
10
- record_sql
11
- attributes_include
12
- allow_raw_exception_messages
13
- custom_events
14
- custom_parameters
15
- custom_instrumentation_editor
16
- message_parameters
17
- ].map(&:freeze)
18
-
19
- def self.preliminary_settings(security_policies)
20
- enabled_key = 'enabled'.freeze
21
- settings = EXPECTED_SECURITY_POLICIES.inject({}) do |memo, policy_name|
22
- memo[policy_name] = {enabled_key => security_policies[policy_name][enabled_key]}
23
- memo
24
- end
25
- {'security_policies' => settings}
26
- end
27
-
28
- class Validator
29
- def initialize(preconnect_response)
30
- @preconnect_policies = preconnect_response['security_policies'] || {}
31
- end
32
-
33
- def validate_matching_agent_config!
34
- agent_keys = EXPECTED_SECURITY_POLICIES
35
- all_server_keys = @preconnect_policies.keys
36
- required = 'required'
37
- required_server_keys = @preconnect_policies.keys.select do |key|
38
- key if @preconnect_policies[key][required]
39
- end
40
-
41
- missing_from_agent = required_server_keys - agent_keys
42
- unless missing_from_agent.empty?
43
- message = "The agent received one or more required security policies \
44
- that it does not recognize and will shut down: #{missing_from_agent.join(',')}. \
45
- Please check if a newer agent version supports these policies or contact support."
46
- raise NewRelic::Agent::UnrecoverableAgentException.new(message)
47
- end
48
-
49
- missing_from_server = agent_keys - all_server_keys
50
- unless missing_from_server.empty?
51
- message = "The agent did not receive one or more security policies \
52
- that it expected and will shut down: #{missing_from_server.join(',')}. Please \
53
- contact support."
54
- raise NewRelic::Agent::UnrecoverableAgentException.new(message)
55
- end
56
- end
57
- end
58
- end
59
- end
60
- end
61
- end
@@ -1,206 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- # This is a class for executing commands related to deployment
6
- # events. It runs without loading the rails environment
7
-
8
- require 'yaml'
9
- require 'net/http'
10
- require 'new_relic/agent/hostname'
11
-
12
- # We need to use the Control object but we don't want to load
13
- # the rails environment. The defined? clause is so that
14
- # it won't load it twice, something it does when run inside a test
15
- require 'new_relic/control' unless defined? NewRelic::Control
16
-
17
- class NewRelic::Cli::Deployments < NewRelic::Cli::Command
18
- # DEPRECATION NOTICE (Effective September 2025)
19
- #
20
- # The entire `NewRelic::Cli::Deployments` class and its associated
21
- # `newrelic deployments` command are deprecated and will be removed in
22
- # agent version 10.0.0.
23
- #
24
- # Users should migrate to recording deployments directly via New Relic's
25
- # APIs. For more information, please see the official Change Tracking
26
- # documentation: https://docs.newrelic.com/docs/change-tracking/change-tracking-introduction/
27
- #
28
- # @api public
29
- #
30
-
31
- attr_reader :control
32
- def self.command; 'deployments'; end
33
-
34
- # Initialize the deployment uploader with command line args.
35
- # Use -h to see options.
36
- # When command_line_args is a hash, we are invoking directly and
37
- # it's treated as an options with optional string values for
38
- # :user, :description, :appname, :revision, :environment,
39
- # :license_key, and :changes.
40
- #
41
- # Will throw CommandFailed exception if there's any error.
42
- #
43
- def initialize(command_line_args)
44
- @control = NewRelic::Control.instance
45
- @environment = nil
46
- @changelog = nil
47
- @user = nil
48
- super(command_line_args)
49
- # needs else branch coverage
50
- @description ||= @leftover && @leftover.join(' ') # rubocop:disable Style/SafeNavigation
51
- @user ||= ENV['USER']
52
- control.env = @environment if @environment
53
-
54
- load_yaml_from_env(control.env)
55
- @appname ||= NewRelic::Agent.config[:app_name][0] || control.env || 'development'
56
- @license_key ||= NewRelic::Agent.config[:license_key]
57
- @api_key ||= NewRelic::Agent.config[:api_key]
58
-
59
- setup_logging(control.env)
60
- end
61
-
62
- def load_yaml_from_env(env)
63
- yaml = NewRelic::Agent::Configuration::YamlSource.new(NewRelic::Agent.config[:config_path], env)
64
- if yaml.failed?
65
- messages = yaml.failures.flatten.map(&:to_s).join("\n")
66
- raise NewRelic::Cli::Command::CommandFailure.new("Error in loading newrelic.yml.\n#{messages}")
67
- end
68
-
69
- NewRelic::Agent.config.replace_or_add_config(yaml)
70
- end
71
-
72
- def setup_logging(env)
73
- NewRelic::Agent.logger = NewRelic::Agent::AgentLogger.new
74
- NewRelic::Agent.logger.info("Running Capistrano from '#{env}' environment for application '#{@appname}'")
75
- end
76
-
77
- # Run the Deployment upload in New Relic via Active Resource.
78
- # Will possibly print errors and exit the VM
79
- def run
80
- msg = <<~TEXT
81
- DEPRECATED: The `newrelic deployments` command will be removed in v10.0.0. Learn more about the alternate options: https://docs.newrelic.com/docs/change-tracking/change-tracking-introduction/
82
- TEXT
83
- NewRelic::Agent.logger.log_once(:warn, 'newrelic_deployments'.to_sym, msg)
84
- warn msg
85
-
86
- begin
87
- @description = nil if @description && @description.strip.empty?
88
-
89
- if @license_key.nil? || @license_key.empty?
90
- raise "license_key not set in newrelic.yml for #{control.env}. api_key also required to use New Relic REST API v2"
91
- end
92
-
93
- if !api_v1? && (@revision.nil? || @revision.empty?)
94
- raise 'revision required when using New Relic REST API v2 with api_key. Pass in revision using: -r, --revision=REV'
95
- end
96
-
97
- request = if api_v1?
98
- uri = '/deployments.xml'
99
- create_request(uri, {'x-license-key' => @license_key}, 'application/octet-stream').tap do |req|
100
- set_params_v1(req)
101
- end
102
- else
103
- uri = "/v2/applications/#{application_id}/deployments.json"
104
- create_request(uri, {'Api-Key' => @api_key}, 'application/json').tap do |req|
105
- set_params_v2(req)
106
- end
107
- end
108
-
109
- http = ::NewRelic::Agent::NewRelicService.new(nil, control.api_server).http_connection
110
- response = http.request(request)
111
-
112
- if response.is_a?(Net::HTTPSuccess)
113
- info("Recorded deployment to '#{@appname}' (#{@description || Time.now})")
114
- else
115
- err_string = REXML::Document.new(response.body).elements['errors/error'].map(&:to_s).join('; ') rescue response.message
116
- raise NewRelic::Cli::Command::CommandFailure, "Deployment not recorded: #{err_string}"
117
- end
118
- rescue SystemCallError, SocketError => e
119
- # These include Errno connection errors
120
- err_string = "Transient error attempting to connect to #{control.api_server} (#{e})"
121
- raise NewRelic::Cli::Command::CommandFailure.new(err_string)
122
- rescue NewRelic::Cli::Command::CommandFailure
123
- raise
124
- rescue => e
125
- err("Unexpected error attempting to connect to #{control.api_server}")
126
- info("#{e}: #{e.backtrace.join("\n ")}")
127
- raise NewRelic::Cli::Command::CommandFailure.new(e.to_s)
128
- end
129
- end
130
-
131
- def api_v1?
132
- @api_key.nil? || @api_key.empty?
133
- end
134
-
135
- private
136
-
137
- def create_request(uri, headers, content_type)
138
- Net::HTTP::Post.new(uri, headers).tap do |req|
139
- req.content_type = content_type
140
- end
141
- end
142
-
143
- def application_id
144
- return @application_id if @application_id
145
-
146
- # Need to connect to collector to acquire application id from the connect response
147
- # but set monitor_mode false because we don't want to actually report anything
148
- begin
149
- NewRelic::Agent.manual_start(monitor_mode: false)
150
- NewRelic::Agent.agent.connect_to_server
151
- @application_id = NewRelic::Agent.config[:primary_application_id]
152
- ensure
153
- NewRelic::Agent.shutdown
154
- end
155
- end
156
-
157
- def set_params_v1(request)
158
- params = {
159
- :application_id => @appname,
160
- :host => NewRelic::Agent::Hostname.get,
161
- :description => @description,
162
- :user => @user,
163
- :revision => @revision,
164
- :changelog => @changelog
165
- }.each_with_object({}) do |(k, v), h|
166
- h["deployment[#{k}]"] = v unless v.nil? || v == ''
167
- end
168
- request.set_form_data(params)
169
- end
170
-
171
- def set_params_v2(request)
172
- request.body = {
173
- 'deployment' => {
174
- :description => @description,
175
- :user => @user,
176
- :revision => @revision,
177
- :changelog => @changelog
178
- }
179
- }.to_json
180
- end
181
-
182
- def options
183
- OptionParser.new(%Q(Usage: #{$0} #{self.class.command} [OPTIONS] ["description"] ), 40) do |o|
184
- o.separator('OPTIONS:')
185
- o.on('-a', '--appname=NAME', String,
186
- 'Set the application name.',
187
- 'Default is app_name setting in newrelic.yml. Available only when using API v1.') { |e| @appname = e }
188
- o.on('-i', '--appid=ID', String,
189
- 'Set the application ID',
190
- 'If not provided, will connect to the New Relic collector to get it') { |i| @application_id = i }
191
- o.on('-e', '--environment=name', String,
192
- 'Override the (RAILS|RUBY|RACK)_ENV setting',
193
- "currently: #{control.env}") { |e| @environment = e }
194
- o.on('-u', '--user=USER', String,
195
- 'Specify the user deploying, for information only',
196
- "Default: #{@user || '<none>'}") { |u| @user = u }
197
- o.on('-r', '--revision=REV', String,
198
- 'Specify the revision being deployed. Required when using New Relic REST API v2') { |r| @revision = r }
199
- o.on('-l', '--license-key=KEY', String,
200
- 'Specify the license key of the account for the app being deployed') { |l| @license_key = l }
201
- o.on('-c', '--changes',
202
- 'Read in a change log from the standard input') { @changelog = STDIN.read }
203
- yield(o) if block_given?
204
- end
205
- end
206
- end
@@ -1,23 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- require 'capistrano/framework'
6
- require_relative 'helpers/send_deployment'
7
-
8
- namespace :newrelic do
9
- include SendDeployment
10
- # notifies New Relic of a deployment
11
- desc 'Record a deployment in New Relic (newrelic.com)'
12
- task :notice_deployment do
13
- if fetch(:newrelic_role)
14
- on roles(fetch(:newrelic_role)) do
15
- send_deployment_notification_to_newrelic
16
- end
17
- else
18
- run_locally do
19
- send_deployment_notification_to_newrelic
20
- end
21
- end
22
- end
23
- end
@@ -1,95 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- make_notify_task = proc do
6
- namespace(:newrelic) do
7
- # on all deployments, notify New Relic
8
- desc('Record a deployment in New Relic (newrelic.com)')
9
- task(:notice_deployment, :roles => :app, :except => {:no_release => true}) do
10
- rails_env = fetch(:newrelic_rails_env, fetch(:rails_env, 'production'))
11
-
12
- require 'new_relic/cli/command'
13
-
14
- begin
15
- # allow overrides to be defined for revision, description, changelog, appname, and user
16
- rev = fetch(:newrelic_revision) if exists?(:newrelic_revision)
17
- description = fetch(:newrelic_desc) if exists?(:newrelic_desc)
18
- changelog = fetch(:newrelic_changelog) if exists?(:newrelic_changelog)
19
- appname = fetch(:newrelic_appname) if exists?(:newrelic_appname)
20
- user = fetch(:newrelic_user) if exists?(:newrelic_user)
21
- license_key = fetch(:newrelic_license_key) if exists?(:newrelic_license_key)
22
-
23
- unless scm == :none
24
- changelog = lookup_changelog(changelog)
25
- rev = lookup_rev(rev)
26
- end
27
-
28
- new_revision = rev
29
- deploy_options = {
30
- :environment => rails_env,
31
- :revision => new_revision,
32
- :changelog => changelog,
33
- :description => description,
34
- :appname => appname,
35
- :user => user,
36
- :license_key => license_key
37
- }
38
-
39
- logger.debug('Uploading deployment to New Relic')
40
- deployment = NewRelic::Cli::Deployments.new(deploy_options)
41
- deployment.run
42
- logger.info('Uploaded deployment information to New Relic')
43
- rescue NewRelic::Cli::Command::CommandFailure => e
44
- logger.info(e.message)
45
- rescue Capistrano::CommandError
46
- logger.info('Unable to notify New Relic of the deployment... skipping')
47
- rescue => e
48
- logger.info("Error creating New Relic deployment (#{e})\n#{e.backtrace.join("\n")}")
49
- end
50
- end
51
-
52
- def lookup_changelog(changelog)
53
- if !changelog
54
- logger.debug('Getting log of changes for New Relic Deployment details')
55
- from_revision = source.next_revision(current_revision)
56
-
57
- if scm == :git
58
- log_command = "git --no-pager log --no-color --pretty=format:' * %an: %s' " +
59
- "--abbrev-commit --no-merges #{previous_revision}..#{real_revision}"
60
- else
61
- log_command = "#{source.log(from_revision)}"
62
- end
63
-
64
- changelog = `#{log_command}`
65
- end
66
- changelog
67
- end
68
-
69
- def lookup_rev(rev)
70
- if rev.nil?
71
- rev = source.query_revision(source.head()) do |cmd|
72
- logger.debug("executing locally: '#{cmd}'")
73
- `#{cmd}`
74
- end
75
-
76
- rev = rev[0..6] if scm == :git
77
- end
78
- rev
79
- end
80
- end
81
- end
82
-
83
- require 'capistrano/version'
84
-
85
- if defined?(Capistrano::Version::MAJOR) && Capistrano::Version::MAJOR < 2
86
- STDERR.puts "Unable to load #{__FILE__}\nNew Relic Capistrano hooks require at least version 2.0.0"
87
- else
88
- instance = Capistrano::Configuration.instance
89
-
90
- if instance
91
- instance.load(&make_notify_task)
92
- else
93
- make_notify_task.call
94
- end
95
- end
@@ -1,70 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- module SendDeployment
6
- def send_deployment_notification_to_newrelic
7
- require 'new_relic/cli/command'
8
- debug('Uploading deployment to New Relic')
9
- NewRelic::Cli::Deployments.new(deploy_options).run
10
- info('Uploaded deployment information to New Relic')
11
- rescue NewRelic::Cli::Command::CommandFailure => e
12
- info(e.message)
13
- rescue => e
14
- info("Error creating New Relic deployment (#{e})\n#{e.backtrace.join("\n")}")
15
- end
16
-
17
- private
18
-
19
- def deploy_options
20
- {
21
- :environment => fetch_environment,
22
- :revision => fetch_rev,
23
- :changelog => fetch_changelog,
24
- :description => fetch(:newrelic_desc),
25
- :appname => fetch(:newrelic_appname),
26
- :user => fetch(:newrelic_user),
27
- :license_key => fetch(:newrelic_license_key)
28
- }
29
- end
30
-
31
- def fetch_changelog
32
- newrelic_changelog = fetch(:newrelic_changelog)
33
- has_scm? && !newrelic_changelog ? lookup_changelog : newrelic_changelog
34
- end
35
-
36
- def fetch_environment
37
- fetch(:newrelic_rails_env, fetch(:rack_env, fetch(:rails_env, fetch(:stage, 'production'))))
38
- end
39
-
40
- def fetch_rev
41
- newrelic_rev = fetch(:newrelic_revision)
42
- has_scm? && !newrelic_rev ? fetch(:current_revision) : newrelic_rev
43
- end
44
-
45
- def has_scm?
46
- has_scm_from_plugin? || has_scm_from_config?
47
- end
48
-
49
- def has_scm_from_config?
50
- defined?(scm) && !scm.nil? && scm != :none
51
- end
52
-
53
- def has_scm_from_plugin?
54
- respond_to?(:scm_plugin_installed?) && scm_plugin_installed?
55
- end
56
-
57
- def lookup_changelog
58
- previous_revision = fetch(:previous_revision)
59
- current_revision = fetch(:current_revision)
60
- return unless current_revision && previous_revision
61
-
62
- debug('Retrieving changelog for New Relic Deployment details')
63
-
64
- if Rake::Task.task_defined?('git:check')
65
- log_command = "git --no-pager log --no-color --pretty=format:' * %an: %s' " +
66
- "--abbrev-commit --no-merges #{previous_revision}..#{current_revision}"
67
- `#{log_command}`
68
- end
69
- end
70
- end
@@ -1,24 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- # When installed as a plugin, this is loaded automatically.
6
- #
7
- # When installed as a gem, you need to add
8
- # require 'new_relic/recipes'
9
- # to deploy.rb
10
- #
11
- # Defines newrelic:notice_deployment, which sends information about the deploy
12
- # to New Relic. The task will run on all app release roles. If it fails, it will
13
- # not affect the execution of subsequent tasks or cause a rollback.
14
- #
15
- # @api public
16
- #
17
-
18
- require 'capistrano/version'
19
-
20
- if defined?(Capistrano::VERSION) && Capistrano::VERSION.to_s.split('.').first.to_i >= 3
21
- require 'new_relic/recipes/capistrano3'
22
- else
23
- require 'new_relic/recipes/capistrano_legacy'
24
- end
data/recipes/newrelic.rb DELETED
@@ -1,10 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- # The capistrano recipes in plugins are automatically
6
- # loaded from here. From gems, they are available from
7
- # the lib directory. We have to make them available from
8
- # both locations
9
-
10
- require File.join(File.dirname(__FILE__), '..', 'lib', 'new_relic', 'recipes')