newrelic_rpm 9.11.0 → 9.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +112 -0
- data/README.md +16 -20
- data/lib/new_relic/agent/agent_logger.rb +1 -0
- data/lib/new_relic/agent/configuration/default_source.rb +136 -5
- data/lib/new_relic/agent/configuration/manager.rb +8 -0
- data/lib/new_relic/agent/database/obfuscator.rb +1 -0
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +0 -13
- data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +14 -0
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +0 -19
- data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/excon.rb +0 -16
- data/lib/new_relic/agent/instrumentation/grape.rb +3 -1
- data/lib/new_relic/agent/instrumentation/logstasher/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/logstasher/instrumentation.rb +24 -0
- data/lib/new_relic/agent/instrumentation/logstasher/prepend.rb +13 -0
- data/lib/new_relic/agent/instrumentation/logstasher.rb +27 -0
- data/lib/new_relic/agent/instrumentation/opensearch/chain.rb +21 -0
- data/lib/new_relic/agent/instrumentation/opensearch/instrumentation.rb +66 -0
- data/lib/new_relic/agent/instrumentation/opensearch/prepend.rb +13 -0
- data/lib/new_relic/agent/instrumentation/opensearch.rb +25 -0
- data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +3 -0
- data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +9 -5
- data/lib/new_relic/agent/instrumentation/redis/cluster_middleware.rb +26 -0
- data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +14 -11
- data/lib/new_relic/agent/instrumentation/redis/middleware.rb +3 -0
- data/lib/new_relic/agent/instrumentation/redis.rb +11 -4
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +0 -14
- data/lib/new_relic/agent/instrumentation/sinatra.rb +0 -13
- data/lib/new_relic/agent/local_log_decorator.rb +8 -1
- data/lib/new_relic/agent/log_event_aggregator.rb +91 -26
- data/lib/new_relic/agent/serverless_handler.rb +241 -12
- data/lib/new_relic/agent/serverless_handler_event_sources.json +155 -0
- data/lib/new_relic/agent/serverless_handler_event_sources.rb +49 -0
- data/lib/new_relic/agent/system_info.rb +14 -0
- data/lib/new_relic/agent/transaction/trace_context.rb +1 -1
- data/lib/new_relic/control/frameworks/grape.rb +14 -0
- data/lib/new_relic/control/frameworks/padrino.rb +14 -0
- data/lib/new_relic/control/frameworks/rails4.rb +4 -2
- data/lib/new_relic/control/instance_methods.rb +1 -0
- data/lib/new_relic/control/private_instance_methods.rb +4 -0
- data/lib/new_relic/control/security_interface.rb +57 -0
- data/lib/new_relic/control.rb +1 -1
- data/lib/new_relic/environment_report.rb +6 -2
- data/lib/new_relic/language_support.rb +7 -1
- data/lib/new_relic/local_environment.rb +1 -4
- data/lib/new_relic/rack/browser_monitoring.rb +11 -7
- data/lib/new_relic/version.rb +1 -1
- data/lib/tasks/config.rake +5 -2
- data/lib/tasks/helpers/config.html.erb +1 -1
- data/lib/tasks/helpers/format.rb +1 -1
- data/lib/tasks/helpers/newrelicyml.rb +76 -13
- data/lib/tasks/instrumentation_generator/instrumentation.thor +1 -0
- data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +3 -3
- data/newrelic.yml +209 -137
- data/test/agent_helper.rb +9 -0
- metadata +16 -2
@@ -0,0 +1,49 @@
|
|
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 'json'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
# ServerlessHandlerEventSources - New Relic's language agent devs maintain
|
10
|
+
# a cross-agent JSON map of all AWS resources with the potential to invoke
|
11
|
+
# an AWS Lambda function by issuing it an event. This map is used to glean
|
12
|
+
# source specific attributes while instrumenting the function's invocation.
|
13
|
+
#
|
14
|
+
# Given that the event arrives as a Ruby hash argument to the AWS Lambda
|
15
|
+
# function, the JSON map's values need to be converted into arrays that can
|
16
|
+
# be passed to `Hash#dig`. So a value such as `'records[0].name'` needs to
|
17
|
+
# be converted to `['records', 0, 'name']`. This class's `.to_hash` method
|
18
|
+
# yields the converted data.
|
19
|
+
#
|
20
|
+
# Furthermore, `.length` calls are converted to Ruby `#size` notation to
|
21
|
+
# denote that a method call must be performed on the dug value.
|
22
|
+
class ServerlessHandlerEventSources
|
23
|
+
JSON_SOURCE = File.join(File.dirname(__FILE__), 'serverless_handler_event_sources.json').freeze
|
24
|
+
JSON_RAW = JSON.parse(File.read(JSON_SOURCE)).freeze
|
25
|
+
|
26
|
+
def self.to_hash
|
27
|
+
JSON_RAW.each_with_object({}) do |(type, info), hash|
|
28
|
+
hash[type] = {'attributes' => {},
|
29
|
+
'name' => info['name'],
|
30
|
+
'required_keys' => []}
|
31
|
+
info['attributes'].each { |attr, value| hash[type]['attributes'][attr] = transform(value) }
|
32
|
+
info['required_keys'].each { |key| hash[type]['required_keys'].push(transform(key)) }
|
33
|
+
end.freeze
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.transform(value)
|
37
|
+
value.gsub(/\[(\d+)\]/, '.\1').split('.').map do |e|
|
38
|
+
if e.match?(/^\d+$/)
|
39
|
+
e.to_i
|
40
|
+
elsif e == 'length'
|
41
|
+
'#size'
|
42
|
+
else
|
43
|
+
e
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -19,6 +19,20 @@ module NewRelic
|
|
19
19
|
RbConfig::CONFIG['target_os']
|
20
20
|
end
|
21
21
|
|
22
|
+
def self.os_distribution
|
23
|
+
case
|
24
|
+
when darwin? then :darwin
|
25
|
+
when linux? then :linux
|
26
|
+
when bsd? then :bsd
|
27
|
+
when windows? then :windows
|
28
|
+
else ruby_os_identifier
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.windows?
|
33
|
+
!!(ruby_os_identifier[/mingw|mswin/i])
|
34
|
+
end
|
35
|
+
|
22
36
|
def self.darwin?
|
23
37
|
!!(ruby_os_identifier =~ /darwin/i)
|
24
38
|
end
|
@@ -95,7 +95,7 @@ module NewRelic
|
|
95
95
|
|
96
96
|
def create_trace_state_payload
|
97
97
|
unless Agent.config[:'distributed_tracing.enabled']
|
98
|
-
NewRelic::Agent.logger.warn('Not configured to create
|
98
|
+
NewRelic::Agent.logger.warn('Not configured to create W3C trace context payload')
|
99
99
|
return
|
100
100
|
end
|
101
101
|
|
@@ -0,0 +1,14 @@
|
|
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 'new_relic/control/frameworks/ruby'
|
6
|
+
module NewRelic
|
7
|
+
class Control
|
8
|
+
module Frameworks
|
9
|
+
# Contains basic control logic for Grape
|
10
|
+
class Grape < NewRelic::Control::Frameworks::Ruby
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
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 'new_relic/control/frameworks/sinatra'
|
6
|
+
module NewRelic
|
7
|
+
class Control
|
8
|
+
module Frameworks
|
9
|
+
# Contains basic control logic for Padrino
|
10
|
+
class Padrino < NewRelic::Control::Frameworks::Sinatra
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -9,8 +9,10 @@ module NewRelic
|
|
9
9
|
module Frameworks
|
10
10
|
class Rails4 < NewRelic::Control::Frameworks::Rails3
|
11
11
|
def rails_gem_list
|
12
|
-
Bundler.
|
13
|
-
"#{gem.name} (#{gem.version})"
|
12
|
+
if Gem::Version.new(Bundler::VERSION) >= Gem::Version.new('2.0.0')
|
13
|
+
Bundler.rubygems.installed_specs.map { |gem| "#{gem.name} (#{gem.version})" }
|
14
|
+
else
|
15
|
+
Bundler.rubygems.all_specs.map { |gem| "#{gem.name} (#{gem.version})" }
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
@@ -0,0 +1,57 @@
|
|
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 'singleton'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
class Control
|
9
|
+
class SecurityInterface
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
attr_accessor :wait
|
13
|
+
|
14
|
+
SUPPORTABILITY_PREFIX_SECURITY = 'Supportability/Ruby/SecurityAgent/Enabled/'
|
15
|
+
SUPPORTABILITY_PREFIX_SECURITY_AGENT = 'Supportability/Ruby/SecurityAgent/Agent/Enabled/'
|
16
|
+
ENABLED = 'enabled'
|
17
|
+
DISABLED = 'disabled'
|
18
|
+
|
19
|
+
def agent_started?
|
20
|
+
(@agent_started ||= false) == true
|
21
|
+
end
|
22
|
+
|
23
|
+
def waiting?
|
24
|
+
(@wait ||= false) == true
|
25
|
+
end
|
26
|
+
|
27
|
+
def init_agent
|
28
|
+
return if agent_started? || waiting?
|
29
|
+
|
30
|
+
record_supportability_metrics
|
31
|
+
|
32
|
+
if Agent.config[:'security.agent.enabled'] && !Agent.config[:high_security]
|
33
|
+
Agent.logger.info('Invoking New Relic security module')
|
34
|
+
require 'newrelic_security'
|
35
|
+
|
36
|
+
@agent_started = true
|
37
|
+
else
|
38
|
+
Agent.logger.info('New Relic Security is completely disabled by one of the user-provided configurations: `security.agent.enabled` or `high_security`. Not loading security capabilities.')
|
39
|
+
Agent.logger.info("high_security = #{Agent.config[:high_security]}")
|
40
|
+
Agent.logger.info("security.agent.enabled = #{Agent.config[:'security.agent.enabled']}")
|
41
|
+
end
|
42
|
+
rescue LoadError
|
43
|
+
Agent.logger.info('New Relic security agent not found - skipping')
|
44
|
+
rescue StandardError => exception
|
45
|
+
Agent.logger.error("Exception in New Relic security module loading: #{exception} #{exception.backtrace}")
|
46
|
+
end
|
47
|
+
|
48
|
+
def record_supportability_metrics
|
49
|
+
Agent.config[:'security.agent.enabled'] ? security_agent_metric(ENABLED) : security_agent_metric(DISABLED)
|
50
|
+
end
|
51
|
+
|
52
|
+
def security_agent_metric(setting)
|
53
|
+
NewRelic::Agent.record_metric_once(SUPPORTABILITY_PREFIX_SECURITY_AGENT + setting)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/new_relic/control.rb
CHANGED
@@ -8,7 +8,6 @@ require 'new_relic/local_environment'
|
|
8
8
|
require 'new_relic/language_support'
|
9
9
|
require 'new_relic/helper'
|
10
10
|
|
11
|
-
require 'singleton'
|
12
11
|
require 'erb'
|
13
12
|
require 'socket'
|
14
13
|
require 'net/https'
|
@@ -18,6 +17,7 @@ require 'new_relic/control/server_methods'
|
|
18
17
|
require 'new_relic/control/instrumentation'
|
19
18
|
require 'new_relic/control/class_methods'
|
20
19
|
require 'new_relic/control/instance_methods'
|
20
|
+
require 'new_relic/control/security_interface'
|
21
21
|
|
22
22
|
require 'new_relic/agent'
|
23
23
|
require 'new_relic/delayed_job_injection'
|
@@ -44,7 +44,11 @@ module NewRelic
|
|
44
44
|
####################################
|
45
45
|
report_on('Gems') do
|
46
46
|
begin
|
47
|
-
Bundler
|
47
|
+
if Gem::Version.new(Bundler::VERSION) >= Gem::Version.new('2.0.0')
|
48
|
+
Bundler.rubygems.installed_specs.map { |gem| "#{gem.name}(#{gem.version})" }
|
49
|
+
else
|
50
|
+
Bundler.rubygems.all_specs.map { |gem| "#{gem.name}(#{gem.version})" }
|
51
|
+
end
|
48
52
|
rescue
|
49
53
|
# There are certain rubygem, bundler, rails combinations (e.g. gem
|
50
54
|
# 1.6.2, rails 2.3, bundler 1.2.3) where the code above throws an error
|
@@ -67,7 +71,7 @@ module NewRelic
|
|
67
71
|
report_on('Physical Cores') { ::NewRelic::Agent::SystemInfo.num_physical_cores }
|
68
72
|
report_on('Arch') { ::NewRelic::Agent::SystemInfo.processor_arch }
|
69
73
|
report_on('OS version') { ::NewRelic::Agent::SystemInfo.os_version }
|
70
|
-
report_on('OS') { ::NewRelic::Agent::SystemInfo.
|
74
|
+
report_on('OS') { ::NewRelic::Agent::SystemInfo.os_distribution }
|
71
75
|
report_on('Database adapter') { ::NewRelic::Agent::DatabaseAdapter.value }
|
72
76
|
report_on('Framework') { Agent.config[:framework].to_s }
|
73
77
|
report_on('Dispatcher') { Agent.config[:dispatcher].to_s }
|
@@ -88,7 +88,13 @@ module NewRelic
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def bundled_gem?(gem_name)
|
91
|
-
defined?(Bundler)
|
91
|
+
return false unless defined?(Bundler)
|
92
|
+
|
93
|
+
if Gem::Version.new(Bundler::VERSION) >= Gem::Version.new('2.0.0')
|
94
|
+
Bundler.rubygems.installed_specs.map(&:name).include?(gem_name)
|
95
|
+
else
|
96
|
+
Bundler.rubygems.all_specs.map(&:name).include?(gem_name)
|
97
|
+
end
|
92
98
|
rescue => e
|
93
99
|
::NewRelic::Agent.logger.info("Could not determine if third party #{gem_name} gem is installed", e)
|
94
100
|
false
|
@@ -142,10 +142,7 @@ module NewRelic
|
|
142
142
|
end
|
143
143
|
|
144
144
|
def check_for_falcon
|
145
|
-
|
146
|
-
NewRelic::LanguageSupport.object_space_usable?
|
147
|
-
|
148
|
-
@discovered_dispatcher = :falcon if find_class_in_object_space(::Falcon::Server)
|
145
|
+
@discovered_dispatcher = :falcon if defined?(::Falcon::Server) && File.basename($PROGRAM_NAME) == 'falcon'
|
149
146
|
end
|
150
147
|
|
151
148
|
def check_for_delayed_job
|
@@ -20,15 +20,15 @@ module NewRelic
|
|
20
20
|
# examine in order to look for a RUM insertion point.
|
21
21
|
SCAN_LIMIT = 50_000
|
22
22
|
|
23
|
-
CONTENT_TYPE = 'Content-Type'
|
24
|
-
CONTENT_DISPOSITION = 'Content-Disposition'
|
25
|
-
CONTENT_LENGTH = 'Content-Length'
|
23
|
+
CONTENT_TYPE = 'Content-Type'
|
24
|
+
CONTENT_DISPOSITION = 'Content-Disposition'
|
25
|
+
CONTENT_LENGTH = 'Content-Length'
|
26
26
|
ATTACHMENT = /attachment/.freeze
|
27
27
|
TEXT_HTML = %r{text/html}.freeze
|
28
28
|
|
29
|
-
BODY_START = '<body'
|
30
|
-
HEAD_START = '<head'
|
31
|
-
GT = '>'
|
29
|
+
BODY_START = '<body'
|
30
|
+
HEAD_START = '<head'
|
31
|
+
GT = '>'
|
32
32
|
|
33
33
|
ALREADY_INSTRUMENTED_KEY = 'newrelic.browser_monitoring_already_instrumented'
|
34
34
|
CHARSET_RE = /<\s*meta[^>]+charset\s*=[^>]*>/im.freeze
|
@@ -120,7 +120,11 @@ module NewRelic
|
|
120
120
|
end
|
121
121
|
|
122
122
|
def streaming?(env, headers)
|
123
|
-
#
|
123
|
+
# Up until version 8.0, Rails would set 'Transfer-Encoding' to 'chunked'
|
124
|
+
# to trigger the desired HTTP/1.1 based streaming functionality in Rack.
|
125
|
+
# With version v8.0+, Rails assumes that the web server will be using
|
126
|
+
# Rack v3+ or an equally modern alternative and simply leaves the
|
127
|
+
# streaming behavior up to them.
|
124
128
|
return true if headers && headers['Transfer-Encoding'] == 'chunked'
|
125
129
|
|
126
130
|
defined?(ActionController::Live) &&
|
data/lib/new_relic/version.rb
CHANGED
data/lib/tasks/config.rake
CHANGED
@@ -23,13 +23,16 @@ namespace :newrelic do
|
|
23
23
|
'browser_monitoring' => "The <InlinePopover type='browser' /> [page load timing](/docs/browser/new-relic-browser/page-load-timing/page-load-timing-process) feature (sometimes referred to as real user monitoring or RUM) gives you insight into the performance real users are experiencing with your website. This is accomplished by measuring the time it takes for your users' browsers to download and render your web pages by injecting a small amount of JavaScript code into the header and footer of each page.",
|
24
24
|
'application_logging' => "The Ruby agent supports [APM logs in context](/docs/apm/new-relic-apm/getting-started/get-started-logs-context). For some tips on configuring logs for the Ruby agent, see [Configure Ruby logs in context](/docs/logs/logs-context/configure-logs-context-ruby).\n\nAvailable logging-related config options include:",
|
25
25
|
'analytics_events' => '[New Relic dashboards](/docs/query-your-data/explore-query-data/dashboards/introduction-new-relic-one-dashboards) is a resource to gather and visualize data about your software and what it says about your business. With it you can quickly and easily create real-time dashboards to get immediate answers about end-user experiences, clickstreams, mobile activities, and server transactions.',
|
26
|
-
'ai_monitoring' => "This section includes Ruby agent configurations for setting up AI monitoring.\n\n<Callout variant='important'>You need to enable distributed tracing to capture trace and feedback data. It is turned on by default in Ruby agents 8.0.0 and higher.</Callout>"
|
26
|
+
'ai_monitoring' => "This section includes Ruby agent configurations for setting up AI monitoring.\n\n<Callout variant='important'>You need to enable distributed tracing to capture trace and feedback data. It is turned on by default in Ruby agents 8.0.0 and higher.</Callout>",
|
27
|
+
'security_agent' => "[New Relic Interactive Application Security Testing](https://docs.newrelic.com/docs/iast/introduction/) (IAST) tests your applications for any exploitable vulnerability by replaying the generated HTTP request with vulnerable payloads.\n\n<Callout variant='important'>Run IAST with non-production deployments only to avoid exposing vulnerabilities on your production software. \
|
28
|
+
IAST mode requires Ruby agent version 9.12.0 or higher and the [newrelic_security](https://rubygems.org/gems/newrelic_security) gem. Security agent configurations are disabled by default.</Callout>"
|
27
29
|
}
|
28
30
|
|
29
31
|
NAME_OVERRIDES = {
|
30
32
|
'slow_sql' => 'Slow SQL [#slow-sql]',
|
31
33
|
'custom_insights_events' => 'Custom Events [#custom-events]',
|
32
|
-
'ai_monitoring' => 'AI Monitoring [#ai-monitoring]'
|
34
|
+
'ai_monitoring' => 'AI Monitoring [#ai-monitoring]',
|
35
|
+
'security_agent' => 'Security Agent [#security-agent]'
|
33
36
|
}
|
34
37
|
|
35
38
|
desc 'Describe available New Relic configuration settings'
|
@@ -76,7 +76,7 @@ When running the Ruby agent in a Rails app, the agent first looks for the `NEW_R
|
|
76
76
|
When you edit the config file, be sure to:
|
77
77
|
|
78
78
|
* Indent only with two spaces.
|
79
|
-
* Indent only where relevant, in sections such as
|
79
|
+
* Indent only where relevant, in sections such as **`error_collector`**.
|
80
80
|
|
81
81
|
If you do not indent correctly, the agent may throw an `Unable to parse configuration file` error on startup.
|
82
82
|
|
data/lib/tasks/helpers/format.rb
CHANGED
@@ -69,7 +69,7 @@ module Format
|
|
69
69
|
|
70
70
|
def format_description(value)
|
71
71
|
description = ''
|
72
|
-
description += '<
|
72
|
+
description += '<DNT>**DEPRECATED**</DNT> ' if value[:deprecated]
|
73
73
|
description += value[:description]
|
74
74
|
description
|
75
75
|
end
|
@@ -45,6 +45,34 @@ module NewRelicYML
|
|
45
45
|
|
46
46
|
HEADER
|
47
47
|
|
48
|
+
SECURITY_BEGIN = <<-SECURITY
|
49
|
+
# BEGIN security agent
|
50
|
+
#
|
51
|
+
# NOTE: At this time, the security agent is intended for use only within
|
52
|
+
# a dedicated security testing environment with data that can tolerate
|
53
|
+
# modification or deletion. The security agent is available as a
|
54
|
+
# separate Ruby gem, newrelic_security. It is recommended that this
|
55
|
+
# separate gem only be introduced to a security testing environment
|
56
|
+
# by leveraging Bundler grouping like so:
|
57
|
+
#
|
58
|
+
# # Gemfile
|
59
|
+
# gem 'newrelic_rpm' # New Relic APM observability agent
|
60
|
+
# gem 'newrelic-infinite_tracing' # New Relic Infinite Tracing
|
61
|
+
#
|
62
|
+
# group :security do
|
63
|
+
# gem 'newrelic_security', require: false # New Relic security agent
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# NOTE: All "security.*" configuration parameters are related only to the
|
67
|
+
# security agent, and all other configuration parameters that may
|
68
|
+
# have "security" in the name somewhere are related to the APM agent.
|
69
|
+
|
70
|
+
SECURITY
|
71
|
+
|
72
|
+
SECURITY_END = <<-SECURITY
|
73
|
+
# END security agent
|
74
|
+
SECURITY
|
75
|
+
|
48
76
|
FOOTER = <<~FOOTER
|
49
77
|
# Environment-specific settings are in this section.
|
50
78
|
# RAILS_ENV or RACK_ENV (as appropriate) is used to determine the environment.
|
@@ -67,16 +95,35 @@ module NewRelicYML
|
|
67
95
|
FOOTER
|
68
96
|
|
69
97
|
def self.get_configs(defaults)
|
70
|
-
|
98
|
+
agent_configs = {}
|
99
|
+
security_configs = {}
|
100
|
+
|
101
|
+
defaults.sort.each do |key, value|
|
71
102
|
next if CRITICAL.include?(key) || SKIP.include?(key)
|
72
103
|
|
73
104
|
next unless public_config?(value) && !deprecated?(value)
|
74
105
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
106
|
+
# TODO: OLD RUBIES < 2.6
|
107
|
+
# Remove `to_s`. `start_with?` doesn't accept symbols in Ruby <2.6
|
108
|
+
if key.to_s.start_with?('security.')
|
109
|
+
description, default = build_config(key, value)
|
110
|
+
security_configs[key] = {description: description, default: default}
|
111
|
+
next
|
112
|
+
end
|
113
|
+
|
114
|
+
description, default = build_config(key, value)
|
115
|
+
agent_configs[key] = {description: description, default: default}
|
79
116
|
end
|
117
|
+
|
118
|
+
[agent_configs, security_configs]
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.build_config(key, value)
|
122
|
+
sanitized_description = sanitize_description(value[:description])
|
123
|
+
description = format_description(sanitized_description)
|
124
|
+
default = default_value(key, value)
|
125
|
+
|
126
|
+
[description, default]
|
80
127
|
end
|
81
128
|
|
82
129
|
def self.public_config?(value)
|
@@ -105,8 +152,9 @@ module NewRelicYML
|
|
105
152
|
def self.format_description(description)
|
106
153
|
# remove leading and trailing whitespace
|
107
154
|
description.strip!
|
108
|
-
# wrap text after 80 characters
|
109
|
-
|
155
|
+
# wrap text after 80 characters, assuming we're at one tabstop's (two
|
156
|
+
# spaces') level of indentation already
|
157
|
+
description.gsub!(/(.{1,78})(\s+|\Z)/, "\\1\n")
|
110
158
|
# add hashtags to lines
|
111
159
|
description = description.split("\n").map { |line| " # #{line}" }.join("\n")
|
112
160
|
|
@@ -125,15 +173,30 @@ module NewRelicYML
|
|
125
173
|
end
|
126
174
|
end
|
127
175
|
|
128
|
-
def self.
|
129
|
-
|
130
|
-
|
176
|
+
def self.agent_configs_yml(agent_configs)
|
177
|
+
agent_yml = ''
|
178
|
+
agent_configs.each do |key, value|
|
179
|
+
agent_yml += "#{value[:description]}\n # #{key}: #{value[:default]}\n\n"
|
180
|
+
end
|
181
|
+
|
182
|
+
agent_yml
|
183
|
+
end
|
131
184
|
|
132
|
-
|
133
|
-
|
185
|
+
def self.security_configs_yml(security_configs)
|
186
|
+
security_yml = ''
|
187
|
+
security_configs.each do |key, value|
|
188
|
+
security_yml += "#{value[:description]}\n # #{key}: #{value[:default]}\n\n"
|
134
189
|
end
|
135
190
|
|
136
|
-
|
191
|
+
security_yml
|
192
|
+
end
|
193
|
+
|
194
|
+
def self.build_string(defaults)
|
195
|
+
agent_configs, security_configs = get_configs(defaults)
|
196
|
+
agent_string = agent_configs_yml(agent_configs)
|
197
|
+
security_string = security_configs_yml(security_configs)
|
198
|
+
|
199
|
+
agent_string + SECURITY_BEGIN + security_string + SECURITY_END + "\n"
|
137
200
|
end
|
138
201
|
|
139
202
|
# :nocov:
|
@@ -12,16 +12,16 @@ DependencyDetection.defer do
|
|
12
12
|
depends_on do
|
13
13
|
# The class that needs to be defined to prepend/chain onto. This can be used
|
14
14
|
# to determine whether the library is installed.
|
15
|
-
defined?(
|
15
|
+
defined?(<%= @class_name %>)
|
16
16
|
# Add any additional requirements to verify whether this instrumentation
|
17
17
|
# should be installed
|
18
18
|
end
|
19
19
|
|
20
20
|
executes do
|
21
|
-
|
21
|
+
NewRelic::Agent.logger.info('Installing <%= @name.downcase %> instrumentation')
|
22
22
|
|
23
23
|
if use_prepend?
|
24
|
-
prepend_instrument
|
24
|
+
prepend_instrument <%= @class_name %>, NewRelic::Agent::Instrumentation::<%= @class_name %>::Prepend
|
25
25
|
else
|
26
26
|
chain_instrument NewRelic::Agent::Instrumentation::<%= @class_name %>::Chain
|
27
27
|
end
|