newrelic_rpm 9.3.1 → 9.4.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 +29 -1
- data/README.md +4 -0
- data/lib/new_relic/agent/configuration/default_source.rb +25 -2
- data/lib/new_relic/agent/configuration/environment_source.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_controller_other_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +1 -2
- data/lib/new_relic/agent/instrumentation/memcache.rb +2 -2
- data/lib/new_relic/agent/instrumentation/queue_time.rb +1 -1
- data/lib/new_relic/agent/instrumentation/roda/chain.rb +43 -0
- data/lib/new_relic/agent/instrumentation/roda/instrumentation.rb +52 -0
- data/lib/new_relic/agent/instrumentation/roda/prepend.rb +24 -0
- data/lib/new_relic/agent/instrumentation/roda/roda_transaction_namer.rb +30 -0
- data/lib/new_relic/agent/instrumentation/roda.rb +33 -0
- data/lib/new_relic/agent/instrumentation/sequel.rb +1 -1
- data/lib/new_relic/agent/log_event_attributes.rb +1 -1
- data/lib/new_relic/agent/new_relic_service.rb +33 -17
- data/lib/new_relic/agent/pipe_service.rb +1 -1
- data/lib/new_relic/agent/tracer.rb +4 -3
- data/lib/new_relic/agent/transaction/request_attributes.rb +45 -7
- data/lib/new_relic/agent/transaction.rb +5 -4
- data/lib/new_relic/agent/utilization/vendor.rb +5 -7
- data/lib/new_relic/control/class_methods.rb +1 -7
- data/lib/new_relic/control/frameworks/roda.rb +20 -0
- data/lib/new_relic/language_support.rb +5 -0
- data/lib/new_relic/noticed_error.rb +5 -2
- data/lib/new_relic/version.rb +2 -2
- data/lib/tasks/bump_version.rake +1 -1
- data/lib/tasks/config.rake +3 -2
- data/lib/tasks/helpers/config.html.erb +93 -0
- data/lib/tasks/helpers/format.rb +11 -7
- data/lib/tasks/helpers/version_bump.rb +2 -2
- data/lib/tasks/newrelicyml.rake +1 -1
- data/newrelic.yml +11 -0
- data/newrelic_rpm.gemspec +3 -2
- metadata +24 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8e0198f3fe3562d84248d3be65acdc8e7ae92e0ca27ecaa1023ca2303152464
|
4
|
+
data.tar.gz: 6d721589df2371d8d63b96eba38adddff1e534678e19b9adfdf028807233d109
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e72bfc0219779d6912631c687d64d896b5becf69be013b35f0a88729ebc444f592d72261b2620d7fdc419b7f3fe0557af56e7e3577a6a482c1cdd4fd19aea7a
|
7
|
+
data.tar.gz: 99a8dee22642c178cf8800e1eec28544262c9b09abcfeb9f856495121de33d5fe1e33483e233d41d746d37cb2e0a2377db00a446d80653816dc252967b64b3e1
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,34 @@
|
|
1
1
|
# New Relic Ruby Agent Release Notes
|
2
2
|
|
3
|
+
## v9.4.0
|
4
|
+
|
5
|
+
Version 9.4.0 of the agent adds [Roda](https://roda.jeremyevans.net/) instrumentation, adds a new `allow_all_headers` configuration option to permit capturing all HTTP headers, introduces improved error tracking functionality by associating a transaction id with each error, and uses more reliable network timeout logic.
|
6
|
+
|
7
|
+
- **Feature: Add Roda instrumentation**
|
8
|
+
|
9
|
+
[Roda](https://roda.jeremyevans.net/) is a now an instrumented framework. The agent currently supports Roda versions 3.19.0+. [PR#2144](https://github.com/newrelic/newrelic-ruby-agent/pull/2144)
|
10
|
+
|
11
|
+
- **Feature: New allow_all_headers configuration option**
|
12
|
+
|
13
|
+
A new `allow_all_headers` configuration option brings parity with the [Node.js agent](https://docs.newrelic.com/docs/release-notes/agent-release-notes/nodejs-release-notes/node-agent-270/) to capture all HTTP request headers.
|
14
|
+
|
15
|
+
This configuration option:
|
16
|
+
* Defaults to `false`
|
17
|
+
* Is not compatible with high security mode
|
18
|
+
* Requires Rack version 2 or higher (as does Ruby on Rails version 5 and above)
|
19
|
+
* Respects all existing behavior for the `attributes.include` and `attributes.exclude` [configuration options](https://docs.newrelic.com/docs/apm/agents/ruby-agent/configuration/ruby-agent-configuration/#attributes)
|
20
|
+
* Captures the additional headers as attributes prefixed with `request.headers.`
|
21
|
+
|
22
|
+
This work was done in response to a feature request submitted by community member [@jamesarosen](https://github.com/jamesarosen). Thank you very much, @jamesarosen! [Issue#1029](https://github.com/newrelic/newrelic-ruby-agent/issues/1029)
|
23
|
+
|
24
|
+
- **Feature: Improved error tracking transaction linking**
|
25
|
+
|
26
|
+
Errors tracked and sent to the New Relic errors inbox will now be associated with a transaction id to enable improved UI/UX associations between transactions and errors. [PR#2035](https://github.com/newrelic/newrelic-ruby-agent/pull/2035)
|
27
|
+
|
28
|
+
- **Feature: Use Net::HTTP native timeout logic**
|
29
|
+
|
30
|
+
In line with current Ruby best practices, make use of Net::HTTP's own timeout logic and avoid the use of `Timeout.timeout()` when possible. The agent's data transmissions and cloud provider detection routines have been updated accordingly. [PR#2147](https://github.com/newrelic/newrelic-ruby-agent/pull/2147)
|
31
|
+
|
3
32
|
## v9.3.1
|
4
33
|
|
5
34
|
Version 9.3.1 of the agent fixes `NewRelic::Agent.require_test_helper`.
|
@@ -14,7 +43,6 @@ Version 9.3.1 of the agent fixes `NewRelic::Agent.require_test_helper`.
|
|
14
43
|
|
15
44
|
Community member [@olleolleolle](https://github.com/olleolleolle) noticed that our source code was referencing a now defunct URL for the Rack specification and submitted [PR#2121](https://github.com/newrelic/newrelic-ruby-agent/pull/2121) to update it. He also provided a terrific recommendation that we automate the checking of links to proactively catch defunct ones in future. Thanks, @olleolleolle!
|
16
45
|
|
17
|
-
|
18
46
|
## v9.3.0
|
19
47
|
|
20
48
|
Version 9.3.0 of the agent adds log-level filtering, adds custom attributes for log events, and updates instrumentation for Action Cable. It also provides fixes for how `Fiber` args are treated, Code-Level Metrics, unnecessary files being included in the gem, and `NewRelic::Agent::Logging::DecoratingFormatter#clear_tags!` being incorrectly private.
|
data/README.md
CHANGED
@@ -134,6 +134,10 @@ The New Relic Ruby agent may use source code from third-party libraries. When us
|
|
134
134
|
|
135
135
|
## Thank You
|
136
136
|
|
137
|
+
We always look forward to connecting with the community. We welcome [contributions](https://github.com/newrelic/newrelic-ruby-agent#contributing) to our source code and suggestions for improvements, and would love to hear about what you like and want to see in the future.
|
138
|
+
|
139
|
+
Visit our [project board](https://github.com/orgs/newrelic/projects/84/) to see what's upcoming in a future release, what we're currently working on, and what we're planning next.
|
140
|
+
|
137
141
|
Thank you,
|
138
142
|
|
139
143
|
New Relic Ruby agent team
|
@@ -24,7 +24,7 @@ module NewRelic
|
|
24
24
|
# Does not appear in logs.
|
25
25
|
def self.deprecated_description(new_setting, description)
|
26
26
|
link_ref = new_setting.to_s.tr('.', '-')
|
27
|
-
%{Please see: [#{new_setting}](
|
27
|
+
%{Please see: [#{new_setting}](##{link_ref}). \n\n#{description}}
|
28
28
|
end
|
29
29
|
|
30
30
|
class Boolean
|
@@ -115,6 +115,7 @@ module NewRelic
|
|
115
115
|
:rails_notifications
|
116
116
|
end
|
117
117
|
when defined?(::Sinatra) && defined?(::Sinatra::Base) then :sinatra
|
118
|
+
when defined?(::Roda) then :roda
|
118
119
|
when defined?(::NewRelic::IA) then :external
|
119
120
|
else :ruby
|
120
121
|
end
|
@@ -818,6 +819,13 @@ module NewRelic
|
|
818
819
|
:description => 'If `true`, the agent captures metrics related to logging for your application.'
|
819
820
|
},
|
820
821
|
# Attributes
|
822
|
+
:'allow_all_headers' => {
|
823
|
+
:default => false,
|
824
|
+
:public => true,
|
825
|
+
:type => Boolean,
|
826
|
+
:allowed_from_server => false,
|
827
|
+
:description => 'If `true`, enables capture of all HTTP request headers for all destinations.'
|
828
|
+
},
|
821
829
|
:'attributes.enabled' => {
|
822
830
|
:default => true,
|
823
831
|
:public => true,
|
@@ -1042,7 +1050,7 @@ module NewRelic
|
|
1042
1050
|
:allowed_from_server => true,
|
1043
1051
|
:deprecated => true,
|
1044
1052
|
:description => deprecated_description(
|
1045
|
-
:'distributed_tracing
|
1053
|
+
:'distributed_tracing.enabled',
|
1046
1054
|
'If `true`, enables [cross-application tracing](/docs/agents/ruby-agent/features/cross-application-tracing-ruby/) when `distributed_tracing.enabled` is set to `false`.'
|
1047
1055
|
)
|
1048
1056
|
},
|
@@ -1227,6 +1235,13 @@ module NewRelic
|
|
1227
1235
|
:allowed_from_server => false,
|
1228
1236
|
:description => 'If `true`, disables [Sidekiq instrumentation](/docs/agents/ruby-agent/background-jobs/sidekiq-instrumentation).'
|
1229
1237
|
},
|
1238
|
+
:disable_roda_auto_middleware => {
|
1239
|
+
:default => false,
|
1240
|
+
:public => true,
|
1241
|
+
:type => Boolean,
|
1242
|
+
:allowed_from_server => false,
|
1243
|
+
:description => 'If `true`, disables agent middleware for Roda. This middleware is responsible for advanced feature support such as [page load timing](/docs/browser/new-relic-browser/getting-started/new-relic-browser) and [error collection](/docs/apm/applications-menu/events/view-apm-error-analytics).'
|
1244
|
+
},
|
1230
1245
|
:disable_sinatra_auto_middleware => {
|
1231
1246
|
:default => false,
|
1232
1247
|
:public => true,
|
@@ -1564,6 +1579,14 @@ module NewRelic
|
|
1564
1579
|
:allowed_from_server => false,
|
1565
1580
|
:description => 'Controls auto-instrumentation of resque at start up. May be one of: `auto`, `prepend`, `chain`, `disabled`.'
|
1566
1581
|
},
|
1582
|
+
:'instrumentation.roda' => {
|
1583
|
+
:default => 'auto',
|
1584
|
+
:public => true,
|
1585
|
+
:type => String,
|
1586
|
+
:dynamic_name => true,
|
1587
|
+
:allowed_from_server => false,
|
1588
|
+
:description => 'Controls auto-instrumentation of Roda at start up. May be one of: `auto`, `prepend`, `chain`, `disabled`.'
|
1589
|
+
},
|
1567
1590
|
:'instrumentation.sinatra' => {
|
1568
1591
|
:default => 'auto',
|
1569
1592
|
:public => true,
|
@@ -101,7 +101,7 @@ module NewRelic
|
|
101
101
|
end
|
102
102
|
else
|
103
103
|
::NewRelic::Agent.logger.info("#{environment_key} does not have a corresponding configuration setting (#{config_key} does not exist).")
|
104
|
-
::NewRelic::Agent.logger.info('Run `rake newrelic:config:docs` or visit https://newrelic.com/docs/ruby/ruby-agent-configuration to see a list of available configuration settings.')
|
104
|
+
::NewRelic::Agent.logger.info('Run `rake newrelic:config:docs` or visit https://docs.newrelic.com/docs/apm/agents/ruby-agent/configuration/ruby-agent-configuration to see a list of available configuration settings.')
|
105
105
|
self[config_key] = value
|
106
106
|
end
|
107
107
|
end
|
@@ -23,7 +23,7 @@ module NewRelic
|
|
23
23
|
|
24
24
|
def metric_name(name, payload)
|
25
25
|
controller_name = controller_name_for_metric(payload)
|
26
|
-
"Ruby/ActionController#{"/#{controller_name}" if controller_name}/#{name.gsub(
|
26
|
+
"Ruby/ActionController#{"/#{controller_name}" if controller_name}/#{name.gsub('.action_controller', '')}"
|
27
27
|
end
|
28
28
|
|
29
29
|
def controller_name_for_metric(payload)
|
@@ -41,8 +41,6 @@ module NewRelic
|
|
41
41
|
clazz.extend(ClassMethodsShim)
|
42
42
|
end
|
43
43
|
|
44
|
-
def new_relic_trace_controller_action(*args); yield; end
|
45
|
-
|
46
44
|
def perform_action_with_newrelic_trace(*args); yield; end
|
47
45
|
end
|
48
46
|
|
@@ -245,6 +243,7 @@ module NewRelic
|
|
245
243
|
when :background then ::NewRelic::Agent::Transaction::TASK_PREFIX
|
246
244
|
when :rack then ::NewRelic::Agent::Transaction::RACK_PREFIX
|
247
245
|
when :uri then ::NewRelic::Agent::Transaction::CONTROLLER_PREFIX
|
246
|
+
when :roda then ::NewRelic::Agent::Transaction::RODA_PREFIX
|
248
247
|
when :sinatra then ::NewRelic::Agent::Transaction::SINATRA_PREFIX
|
249
248
|
when :middleware then ::NewRelic::Agent::Transaction::MIDDLEWARE_PREFIX
|
250
249
|
when :grape then ::NewRelic::Agent::Transaction::GRAPE_PREFIX
|
@@ -5,8 +5,8 @@
|
|
5
5
|
# NOTE: there are multiple implementations of the Memcached client in Ruby,
|
6
6
|
# each with slightly different APIs and semantics.
|
7
7
|
# See:
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# https://rubygems.org/gems/Ruby-MemCache (Gem: Ruby-MemCache)
|
9
|
+
# https://github.com/mperham/memcache-client (Gem: memcache-client)
|
10
10
|
# https://github.com/mperham/dalli (Gem: dalli)
|
11
11
|
|
12
12
|
require_relative 'memcache/helper'
|
@@ -5,7 +5,7 @@
|
|
5
5
|
module NewRelic
|
6
6
|
module Agent
|
7
7
|
module Instrumentation
|
8
|
-
# https://newrelic.com/docs/features/tracking-front-end-time
|
8
|
+
# https://docs.newrelic.com/docs/features/tracking-front-end-time
|
9
9
|
# Record queue time metrics based on any of three headers
|
10
10
|
# which can be set on the request.
|
11
11
|
module QueueTime
|
@@ -0,0 +1,43 @@
|
|
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::Agent::Instrumentation
|
6
|
+
module Roda
|
7
|
+
module Chain
|
8
|
+
def self.instrument!
|
9
|
+
::Roda.class_eval do
|
10
|
+
include ::NewRelic::Agent::Instrumentation::Roda::Tracer
|
11
|
+
|
12
|
+
alias_method(:_roda_handle_main_route_without_tracing, :_roda_handle_main_route)
|
13
|
+
|
14
|
+
def _roda_handle_main_route(*args)
|
15
|
+
_roda_handle_main_route_with_tracing(*args) do
|
16
|
+
_roda_handle_main_route_without_tracing(*args)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Build
|
24
|
+
module Chain
|
25
|
+
def self.instrument!
|
26
|
+
::Roda.class_eval do
|
27
|
+
include ::NewRelic::Agent::Instrumentation::Roda::Tracer
|
28
|
+
|
29
|
+
class << self
|
30
|
+
alias_method(:build_rack_app_without_tracing, :build_rack_app)
|
31
|
+
|
32
|
+
def build_rack_app
|
33
|
+
build_rack_app_with_tracing do
|
34
|
+
build_rack_app_without_tracing
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,52 @@
|
|
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::Agent::Instrumentation
|
6
|
+
module Roda
|
7
|
+
module Tracer
|
8
|
+
include ::NewRelic::Agent::Instrumentation::ControllerInstrumentation
|
9
|
+
|
10
|
+
def self.included(clazz)
|
11
|
+
clazz.extend(self)
|
12
|
+
end
|
13
|
+
|
14
|
+
def newrelic_middlewares
|
15
|
+
middlewares = [NewRelic::Rack::BrowserMonitoring]
|
16
|
+
if NewRelic::Rack::AgentHooks.needed?
|
17
|
+
middlewares << NewRelic::Rack::AgentHooks
|
18
|
+
end
|
19
|
+
middlewares
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_rack_app_with_tracing
|
23
|
+
unless NewRelic::Agent.config[:disable_roda_auto_middleware]
|
24
|
+
newrelic_middlewares.each do |middleware_class|
|
25
|
+
self.use middleware_class
|
26
|
+
end
|
27
|
+
end
|
28
|
+
yield
|
29
|
+
end
|
30
|
+
|
31
|
+
# Roda makes use of Rack, so we can get params from the request object
|
32
|
+
def rack_request_params
|
33
|
+
begin
|
34
|
+
@_request.params
|
35
|
+
rescue => e
|
36
|
+
NewRelic::Agent.logger.debug('Failed to get params from Rack request.', e)
|
37
|
+
NewRelic::EMPTY_HASH
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def _roda_handle_main_route_with_tracing(*args)
|
42
|
+
perform_action_with_newrelic_trace(
|
43
|
+
category: :roda,
|
44
|
+
name: TransactionNamer.transaction_name(request),
|
45
|
+
params: ::NewRelic::Agent::ParameterFiltering::apply_filters(request.env, rack_request_params)
|
46
|
+
) do
|
47
|
+
yield
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,24 @@
|
|
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::Agent::Instrumentation
|
6
|
+
module Roda
|
7
|
+
module Prepend
|
8
|
+
include ::NewRelic::Agent::Instrumentation::Roda::Tracer
|
9
|
+
|
10
|
+
def _roda_handle_main_route(*args)
|
11
|
+
_roda_handle_main_route_with_tracing(*args) { super }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module Build
|
16
|
+
module Prepend
|
17
|
+
include ::NewRelic::Agent::Instrumentation::Roda::Tracer
|
18
|
+
def build_rack_app
|
19
|
+
build_rack_app_with_tracing { super }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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
|
+
module Instrumentation
|
8
|
+
module Roda
|
9
|
+
module TransactionNamer
|
10
|
+
extend self
|
11
|
+
|
12
|
+
ROOT = '/'.freeze
|
13
|
+
REGEX_MULTIPLE_SLASHES = %r{^[/^\A]*(.*?)[/$?\z]*$}.freeze
|
14
|
+
|
15
|
+
def transaction_name(request)
|
16
|
+
path = request.path || ::NewRelic::Agent::UNKNOWN_METRIC
|
17
|
+
name = path.gsub(REGEX_MULTIPLE_SLASHES, '\1') # remove any rogue slashes
|
18
|
+
name = ROOT if name.empty?
|
19
|
+
name = "#{request.request_method} #{name}" if request.respond_to?(:request_method)
|
20
|
+
|
21
|
+
name
|
22
|
+
rescue => e
|
23
|
+
::NewRelic::Agent.logger.debug("#{e.class} : #{e.message} - Error encountered trying to identify Roda transaction name")
|
24
|
+
::NewRelic::Agent::UNKNOWN_METRIC
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
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_relative 'roda/instrumentation'
|
6
|
+
|
7
|
+
DependencyDetection.defer do
|
8
|
+
named :roda
|
9
|
+
|
10
|
+
depends_on do
|
11
|
+
defined?(Roda) &&
|
12
|
+
Gem::Version.new(Roda::RodaVersion) >= Gem::Version.new('3.19.0') &&
|
13
|
+
Roda::RodaPlugins::Base::ClassMethods.private_method_defined?(:build_rack_app) &&
|
14
|
+
Roda::RodaPlugins::Base::InstanceMethods.method_defined?(:_roda_handle_main_route)
|
15
|
+
end
|
16
|
+
|
17
|
+
executes do
|
18
|
+
require_relative '../../rack/agent_hooks'
|
19
|
+
require_relative '../../rack/browser_monitoring'
|
20
|
+
|
21
|
+
NewRelic::Agent.logger.info('Installing Roda instrumentation')
|
22
|
+
|
23
|
+
if use_prepend?
|
24
|
+
require_relative 'roda/prepend'
|
25
|
+
prepend_instrument Roda.singleton_class, NewRelic::Agent::Instrumentation::Roda::Build::Prepend
|
26
|
+
prepend_instrument Roda, NewRelic::Agent::Instrumentation::Roda::Prepend
|
27
|
+
else
|
28
|
+
require_relative 'roda/chain'
|
29
|
+
chain_instrument NewRelic::Agent::Instrumentation::Roda::Build::Chain
|
30
|
+
chain_instrument NewRelic::Agent::Instrumentation::Roda::Chain
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -30,7 +30,7 @@ DependencyDetection.defer do
|
|
30
30
|
else
|
31
31
|
NewRelic::Agent.logger.info('Detected Sequel version %s.' % [Sequel::VERSION])
|
32
32
|
NewRelic::Agent.logger.info('Please see additional documentation: ' +
|
33
|
-
'https://newrelic.com/docs/ruby/sequel-instrumentation')
|
33
|
+
'https://docs.newrelic.com/docs/apm/agents/ruby-agent/frameworks/sequel-instrumentation/')
|
34
34
|
end
|
35
35
|
|
36
36
|
Sequel.synchronize { Sequel::DATABASES.dup }.each do |db|
|
@@ -10,7 +10,7 @@ module NewRelic
|
|
10
10
|
ATTRIBUTE_VALUE_CHARACTER_LIMIT = 4094
|
11
11
|
|
12
12
|
def add_custom_attributes(attributes)
|
13
|
-
return if @custom_attribute_limit_reached
|
13
|
+
return if defined?(@custom_attribute_limit_reached) && @custom_attribute_limit_reached
|
14
14
|
|
15
15
|
attributes.each do |key, value|
|
16
16
|
next if absent?(key) || absent?(value)
|
@@ -3,7 +3,6 @@
|
|
3
3
|
# frozen_string_literal: true
|
4
4
|
|
5
5
|
require 'zlib'
|
6
|
-
require 'timeout'
|
7
6
|
require 'new_relic/agent/audit_logger'
|
8
7
|
require 'new_relic/agent/new_relic_service/encoders'
|
9
8
|
require 'new_relic/agent/new_relic_service/marshaller'
|
@@ -19,7 +18,13 @@ module NewRelic
|
|
19
18
|
|
20
19
|
# These include Errno connection errors, and all indicate that the
|
21
20
|
# underlying TCP connection may be in a bad state.
|
22
|
-
CONNECTION_ERRORS = [
|
21
|
+
CONNECTION_ERRORS = [Net::OpenTimeout, Net::ReadTimeout, EOFError, SystemCallError, SocketError]
|
22
|
+
# TODO: MAJOR VERSION - Net::WriteTimeout wasn't defined until Ruby 2.6.
|
23
|
+
# Once support for Ruby 2.5 is dropped, we should simply include
|
24
|
+
# Net::WriteTimeout in the connection errors array directly instead
|
25
|
+
# of with a conditional
|
26
|
+
CONNECTION_ERRORS << Net::WriteTimeout if defined?(Net::WriteTimeout)
|
27
|
+
CONNECTION_ERRORS.freeze
|
23
28
|
|
24
29
|
# The maximum number of times to attempt an HTTP request
|
25
30
|
MAX_ATTEMPTS = 2
|
@@ -319,13 +324,15 @@ module NewRelic
|
|
319
324
|
|
320
325
|
def start_connection(conn)
|
321
326
|
NewRelic::Agent.logger.debug("Opening TCP connection to #{conn.address}:#{conn.port}")
|
322
|
-
|
323
|
-
conn
|
327
|
+
conn.start
|
324
328
|
end
|
325
329
|
|
326
330
|
def setup_connection_timeouts(conn)
|
327
|
-
|
328
|
-
conn.read_timeout =
|
331
|
+
conn.open_timeout = @request_timeout
|
332
|
+
conn.read_timeout = @request_timeout
|
333
|
+
# TODO: MAJOR VERSION - #write_timeout= requires Ruby 2.6+, so remove
|
334
|
+
# the conditional check once support for Ruby 2.5 is dropped
|
335
|
+
conn.write_timeout = @request_timeout if conn.respond_to?(:write_timeout=)
|
329
336
|
|
330
337
|
if conn.respond_to?(:keep_alive_timeout) && NewRelic::Agent.config[:aggressive_keepalive]
|
331
338
|
conn.keep_alive_timeout = NewRelic::Agent.config[:keep_alive_timeout]
|
@@ -362,8 +369,8 @@ module NewRelic
|
|
362
369
|
conn = create_http_connection
|
363
370
|
start_connection(conn)
|
364
371
|
conn
|
365
|
-
rescue
|
366
|
-
::NewRelic::Agent.logger.info('
|
372
|
+
rescue Net::OpenTimeout
|
373
|
+
::NewRelic::Agent.logger.info('Timed out while attempting to connect. For SSL issues, you may need to install system-level CA Certificates to be used by Net::HTTP.')
|
367
374
|
raise
|
368
375
|
end
|
369
376
|
|
@@ -436,13 +443,9 @@ module NewRelic
|
|
436
443
|
end
|
437
444
|
|
438
445
|
def attempt_request(request, opts)
|
439
|
-
response = nil
|
440
446
|
conn = http_connection
|
441
447
|
::NewRelic::Agent.logger.debug("Sending request to #{opts[:collector]}#{opts[:uri]} with #{request.method}")
|
442
|
-
|
443
|
-
response = conn.request(request)
|
444
|
-
end
|
445
|
-
response
|
448
|
+
conn.request(request)
|
446
449
|
end
|
447
450
|
|
448
451
|
def handle_error_response(response, endpoint)
|
@@ -450,7 +453,9 @@ module NewRelic
|
|
450
453
|
when Net::HTTPRequestTimeOut,
|
451
454
|
Net::HTTPTooManyRequests,
|
452
455
|
Net::HTTPInternalServerError,
|
453
|
-
Net::HTTPServiceUnavailable
|
456
|
+
Net::HTTPServiceUnavailable,
|
457
|
+
Net::OpenTimeout,
|
458
|
+
Net::ReadTimeout
|
454
459
|
handle_server_connection_exception(response, endpoint)
|
455
460
|
when Net::HTTPBadRequest,
|
456
461
|
Net::HTTPForbidden,
|
@@ -471,9 +476,20 @@ module NewRelic
|
|
471
476
|
when Net::HTTPGone
|
472
477
|
handle_gone_response(response, endpoint)
|
473
478
|
else
|
474
|
-
|
475
|
-
|
476
|
-
|
479
|
+
# TODO: MAJOR VERSION - Net::WriteTimeout wasn't defined until
|
480
|
+
# Ruby 2.6, so it can't be included in the case statement
|
481
|
+
# as a constant and instead needs to be found here. Once
|
482
|
+
# support for Ruby 2.5 is dropped, we should have
|
483
|
+
# Net::WriteTimeout sit in the 'when' clause above alongside
|
484
|
+
# Net::OpenTimeout and Net::ReadTimeout and this entire if/else
|
485
|
+
# conditional can be removed.
|
486
|
+
if response.respond_to?(:name) && response.name == 'Net::WriteTimeout'
|
487
|
+
handle_server_connection_exception(response, endpoint)
|
488
|
+
else
|
489
|
+
record_endpoint_attempts_supportability_metrics(endpoint)
|
490
|
+
record_error_response_supportability_metrics(response.code)
|
491
|
+
raise UnrecoverableServerException, "#{response.code}: #{response.message}"
|
492
|
+
end
|
477
493
|
end
|
478
494
|
response
|
479
495
|
end
|
@@ -15,7 +15,7 @@ module NewRelic
|
|
15
15
|
if @pipe && @pipe.parent_pid != $$
|
16
16
|
@pipe.after_fork_in_child
|
17
17
|
else
|
18
|
-
NewRelic::Agent.logger.error('No communication channel to parent process, please see https://newrelic.com/docs/ruby/resque-instrumentation for more information.')
|
18
|
+
NewRelic::Agent.logger.error('No communication channel to parent process, please see https://docs.newrelic.com/docs/apm/agents/ruby-agent/background-jobs/resque-instrumentation/ for more information.')
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
@@ -66,9 +66,10 @@ module NewRelic
|
|
66
66
|
#
|
67
67
|
# @api public
|
68
68
|
def transaction_sampled?
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
txn = current_transaction
|
70
|
+
return false unless txn
|
71
|
+
|
72
|
+
txn.sampled?
|
72
73
|
end
|
73
74
|
alias_method :sampled?, :transaction_sampled?
|
74
75
|
|
@@ -8,11 +8,17 @@ module NewRelic
|
|
8
8
|
module Agent
|
9
9
|
class Transaction
|
10
10
|
class RequestAttributes
|
11
|
-
|
12
|
-
|
11
|
+
# the HTTP standard has "referrer" mispelled as "referer"
|
12
|
+
attr_reader :accept, :content_length, :content_type, :host, :other_headers, :port, :referer, :request_method,
|
13
|
+
:request_path, :user_agent
|
13
14
|
|
14
15
|
HTTP_ACCEPT_HEADER_KEY = 'HTTP_ACCEPT'.freeze
|
15
16
|
|
17
|
+
BASE_HEADERS = %w[CONTENT_LENGTH CONTENT_TYPE HTTP_ACCEPT HTTP_REFERER HTTP_USER_AGENT PATH_INFO REMOTE_HOST
|
18
|
+
REQUEST_METHOD REQUEST_URI SERVER_PORT].freeze
|
19
|
+
|
20
|
+
ATTRIBUTE_PREFIX = 'request.headers.'
|
21
|
+
|
16
22
|
def initialize(request)
|
17
23
|
@request_path = path_from_request(request)
|
18
24
|
@referer = referer_from_request(request)
|
@@ -23,6 +29,7 @@ module NewRelic
|
|
23
29
|
@port = port_from_request(request)
|
24
30
|
@user_agent = attribute_from_request(request, :user_agent)
|
25
31
|
@request_method = attribute_from_request(request, :request_method)
|
32
|
+
@other_headers = other_headers_from_request(request)
|
26
33
|
end
|
27
34
|
|
28
35
|
def assign_agent_attributes(txn)
|
@@ -31,14 +38,17 @@ module NewRelic
|
|
31
38
|
AttributeFilter::DST_ERROR_COLLECTOR
|
32
39
|
|
33
40
|
if referer
|
34
|
-
|
41
|
+
destinations = allow_other_headers? ? default_destinations : AttributeFilter::DST_ERROR_COLLECTOR
|
42
|
+
txn.add_agent_attribute(:'request.headers.referer', referer, destinations)
|
35
43
|
end
|
36
44
|
|
37
45
|
if request_path
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
46
|
+
destinations = if allow_other_headers?
|
47
|
+
default_destinations
|
48
|
+
else
|
49
|
+
AttributeFilter::DST_TRANSACTION_TRACER | AttributeFilter::DST_ERROR_COLLECTOR
|
50
|
+
end
|
51
|
+
txn.add_agent_attribute(:'request.uri', request_path, destinations)
|
42
52
|
end
|
43
53
|
|
44
54
|
if accept
|
@@ -64,6 +74,14 @@ module NewRelic
|
|
64
74
|
if request_method
|
65
75
|
txn.add_agent_attribute(:'request.method', request_method, default_destinations)
|
66
76
|
end
|
77
|
+
|
78
|
+
if port && allow_other_headers?
|
79
|
+
txn.add_agent_attribute(:'request.headers.port', port, default_destinations)
|
80
|
+
end
|
81
|
+
|
82
|
+
other_headers.each do |header, value|
|
83
|
+
txn.add_agent_attribute(header, value, default_destinations)
|
84
|
+
end
|
67
85
|
end
|
68
86
|
|
69
87
|
private
|
@@ -116,6 +134,26 @@ module NewRelic
|
|
116
134
|
env[key]
|
117
135
|
end
|
118
136
|
end
|
137
|
+
|
138
|
+
def allow_other_headers?
|
139
|
+
NewRelic::Agent.config[:allow_all_headers] && !NewRelic::Agent.config[:high_security]
|
140
|
+
end
|
141
|
+
|
142
|
+
def other_headers_from_request(request)
|
143
|
+
# confirm that `request` is an instance of `Rack::Request` by checking
|
144
|
+
# for #each_header
|
145
|
+
return NewRelic::EMPTY_HASH unless allow_other_headers? && request.respond_to?(:each_header)
|
146
|
+
|
147
|
+
request.each_header.with_object({}) do |(header, value), hash|
|
148
|
+
next if BASE_HEADERS.include?(header)
|
149
|
+
|
150
|
+
hash[formatted_header(header)] = value
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def formatted_header(raw_name)
|
155
|
+
"#{ATTRIBUTE_PREFIX}#{NewRelic::LanguageSupport.camelize_with_first_letter_downcased(raw_name)}".to_sym
|
156
|
+
end
|
119
157
|
end
|
120
158
|
end
|
121
159
|
end
|
@@ -31,11 +31,12 @@ module NewRelic
|
|
31
31
|
RAKE_PREFIX = "#{OTHER_TRANSACTION_PREFIX}Rake/"
|
32
32
|
MESSAGE_PREFIX = "#{OTHER_TRANSACTION_PREFIX}Message/"
|
33
33
|
RACK_PREFIX = "#{CONTROLLER_PREFIX}Rack/"
|
34
|
+
RODA_PREFIX = "#{CONTROLLER_PREFIX}Roda/"
|
34
35
|
SINATRA_PREFIX = "#{CONTROLLER_PREFIX}Sinatra/"
|
35
36
|
GRAPE_PREFIX = "#{CONTROLLER_PREFIX}Grape/"
|
36
37
|
ACTION_CABLE_PREFIX = "#{CONTROLLER_PREFIX}ActionCable/"
|
37
38
|
|
38
|
-
WEB_TRANSACTION_CATEGORIES = [
|
39
|
+
WEB_TRANSACTION_CATEGORIES = %i[action_cable controller grape middleware rack roda sinatra web uri].freeze
|
39
40
|
|
40
41
|
MIDDLEWARE_SUMMARY_METRICS = ['Middleware/all'].freeze
|
41
42
|
WEB_SUMMARY_METRIC = 'HttpDispatcher'
|
@@ -289,7 +290,7 @@ module NewRelic
|
|
289
290
|
end
|
290
291
|
|
291
292
|
def sampled?
|
292
|
-
return unless Agent.config[:'distributed_tracing.enabled']
|
293
|
+
return false unless Agent.config[:'distributed_tracing.enabled']
|
293
294
|
|
294
295
|
if @sampled.nil?
|
295
296
|
@sampled = NewRelic::Agent.instance.adaptive_sampler.sampled?
|
@@ -545,8 +546,8 @@ module NewRelic
|
|
545
546
|
end
|
546
547
|
|
547
548
|
def user_defined_rules_ignore?
|
548
|
-
return unless request_path
|
549
|
-
return if (rules = NewRelic::Agent.config[:"rules.ignore_url_regexes"]).empty?
|
549
|
+
return false unless request_path
|
550
|
+
return false if (rules = NewRelic::Agent.config[:"rules.ignore_url_regexes"]).empty?
|
550
551
|
|
551
552
|
rules.any? do |rule|
|
552
553
|
request_path.match(rule)
|
@@ -75,14 +75,12 @@ module NewRelic
|
|
75
75
|
processed_headers = headers
|
76
76
|
raise if processed_headers.value?(:error)
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
Net::HTTP.
|
81
|
-
|
82
|
-
response = http.request(req)
|
83
|
-
end
|
84
|
-
response
|
78
|
+
response = nil
|
79
|
+
Net::HTTP.start(endpoint.host, endpoint.port, open_timeout: 1, read_timeout: 1) do |http|
|
80
|
+
req = Net::HTTP::Get.new(endpoint, processed_headers)
|
81
|
+
response = http.request(req)
|
85
82
|
end
|
83
|
+
response
|
86
84
|
rescue
|
87
85
|
NewRelic::Agent.logger.debug("#{vendor_name} environment not detected")
|
88
86
|
end
|
@@ -49,19 +49,13 @@ module NewRelic
|
|
49
49
|
# maybe it is already loaded by some external system
|
50
50
|
# i.e. rpm_contrib or user extensions?
|
51
51
|
end
|
52
|
-
NewRelic::Control::Frameworks.const_get(camelize(framework.to_s))
|
52
|
+
NewRelic::Control::Frameworks.const_get(NewRelic::LanguageSupport.camelize(framework.to_s))
|
53
53
|
end
|
54
54
|
|
55
55
|
# The root directory for the plugin or gem
|
56
56
|
def newrelic_root
|
57
57
|
File.expand_path(File.join('..', '..', '..', '..'), __FILE__)
|
58
58
|
end
|
59
|
-
|
60
|
-
def camelize(snake_case_name)
|
61
|
-
snake_case_name.gsub(/(\_|^)[a-z]/) do |substring|
|
62
|
-
substring[-1].capitalize!
|
63
|
-
end
|
64
|
-
end
|
65
59
|
end
|
66
60
|
extend ClassMethods
|
67
61
|
end
|
@@ -0,0 +1,20 @@
|
|
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 Roda
|
10
|
+
class Roda < NewRelic::Control::Frameworks::Ruby
|
11
|
+
protected
|
12
|
+
|
13
|
+
def install_shim
|
14
|
+
super
|
15
|
+
::Roda.class_eval { include NewRelic::Agent::Instrumentation::ControllerInstrumentation::Shim }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -78,6 +78,11 @@ module NewRelic
|
|
78
78
|
camelized.split(/\-|\_/).map(&:capitalize).join
|
79
79
|
end
|
80
80
|
|
81
|
+
def camelize_with_first_letter_downcased(string)
|
82
|
+
camelized = camelize(string)
|
83
|
+
camelized[0].downcase.concat(camelized[1..-1])
|
84
|
+
end
|
85
|
+
|
81
86
|
def bundled_gem?(gem_name)
|
82
87
|
defined?(Bundler) && Bundler.rubygems.all_specs.map(&:name).include?(gem_name)
|
83
88
|
rescue => e
|
@@ -13,7 +13,7 @@ class NewRelic::NoticedError
|
|
13
13
|
attr_accessor :path, :timestamp, :message, :exception_class_name,
|
14
14
|
:request_uri, :request_port, :file_name, :line_number,
|
15
15
|
:stack_trace, :attributes_from_notice_error, :attributes,
|
16
|
-
:expected
|
16
|
+
:expected, :transaction_id
|
17
17
|
|
18
18
|
attr_reader :error_group, :exception_id, :is_internal
|
19
19
|
|
@@ -45,6 +45,7 @@ class NewRelic::NoticedError
|
|
45
45
|
@is_internal = (exception.class < NewRelic::Agent::InternalAgentError)
|
46
46
|
|
47
47
|
extract_class_name_and_message_from(exception)
|
48
|
+
@transaction_id = NewRelic::Agent::Tracer&.current_transaction&.guid
|
48
49
|
|
49
50
|
# clamp long messages to 4k so that we don't send a lot of
|
50
51
|
# overhead across the wire
|
@@ -79,11 +80,13 @@ class NewRelic::NoticedError
|
|
79
80
|
include NewRelic::Coerce
|
80
81
|
|
81
82
|
def to_collector_array(encoder = nil)
|
82
|
-
[NewRelic::Helper.time_to_millis(timestamp),
|
83
|
+
arr = [NewRelic::Helper.time_to_millis(timestamp),
|
83
84
|
string(path),
|
84
85
|
string(message),
|
85
86
|
string(exception_class_name),
|
86
87
|
processed_attributes]
|
88
|
+
arr << @transaction_id if @transaction_id
|
89
|
+
arr
|
87
90
|
end
|
88
91
|
|
89
92
|
# Note that we process attributes lazily and store the result. This is because
|
data/lib/new_relic/version.rb
CHANGED
data/lib/tasks/bump_version.rake
CHANGED
data/lib/tasks/config.rake
CHANGED
@@ -21,12 +21,13 @@ namespace :newrelic do
|
|
21
21
|
'transaction_tracer' => 'The [transaction traces](/docs/apm/traces/transaction-traces/transaction-traces) feature collects detailed information from a selection of transactions, including a summary of the calling sequence, a breakdown of time spent, and a list of SQL queries and their query plans (on mysql and postgresql). Available features depend on your New Relic subscription level.',
|
22
22
|
'error_collector' => "The agent collects and reports all uncaught exceptions by default. These configuration options allow you to customize the error collection.\n\nFor information on ignored and expected errors, [see this page on Error Analytics in APM](/docs/agents/manage-apm-agents/agent-data/manage-errors-apm-collect-ignore-or-mark-expected/). To set expected errors via the `NewRelic::Agent.notice_error` Ruby method, [consult the Ruby Agent API](/docs/agents/ruby-agent/api-guides/sending-handled-errors-new-relic/).",
|
23
23
|
'browser_monitoring' => "The browser monitoring [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
|
+
'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:",
|
24
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.'
|
25
26
|
}
|
26
27
|
|
27
28
|
NAME_OVERRIDES = {
|
28
|
-
'slow_sql' => 'Slow SQL',
|
29
|
-
'custom_insights_events' => 'Custom Events'
|
29
|
+
'slow_sql' => 'Slow SQL [#slow-sql]',
|
30
|
+
'custom_insights_events' => 'Custom Events [#custom-events]'
|
30
31
|
}
|
31
32
|
|
32
33
|
desc 'Describe available New Relic configuration settings'
|
@@ -1,3 +1,96 @@
|
|
1
|
+
---
|
2
|
+
title: Ruby agent configuration
|
3
|
+
tags:
|
4
|
+
- Agents
|
5
|
+
- Ruby agent
|
6
|
+
- Configuration
|
7
|
+
metaDescription: 'APM for Ruby: how to configure the Ruby agent, including editing the config file and setting environment variables.'
|
8
|
+
redirects:
|
9
|
+
- /docs/agents/ruby-agent/configuration/ruby-agent-configuration
|
10
|
+
- /docs/ruby/ruby-agent-configuration
|
11
|
+
- /docs/agents/ruby-agent/installation-and-configuration/ruby-agent-configuration
|
12
|
+
- /docs/agents/ruby-agent/installation-configuration/ruby-agent-configuration
|
13
|
+
---
|
14
|
+
|
15
|
+
<CONTRIBUTOR_NOTE>
|
16
|
+
This file is automatically generated from values defined in `lib/new_relic/agent/configuration/default_source.rb`.
|
17
|
+
All changes should be made directly to `default_source.rb.`
|
18
|
+
Submit PRs or raise issues at: https://github.com/newrelic/newrelic-ruby-agent
|
19
|
+
</CONTRIBUTOR_NOTE>
|
20
|
+
|
21
|
+
You can configure the New Relic Ruby agent with settings in a configuration file, environment variables, or programmatically with server-side configuration. This document summarizes the configuration options available for the Ruby agent.
|
22
|
+
|
23
|
+
If the default value for a configuration option is `(Dynamic)`, this means the Ruby agent calculates the default at runtime. The value for the config setting defaults to the value of another setting as appropriate.
|
24
|
+
|
25
|
+
## Configuration methods and precedence [#Options]
|
26
|
+
|
27
|
+
The primary (default) method to configure the Ruby agent is via the configuration file (`newrelic.yml`) in the `config` subdirectory. To set configuration values using environment variables:
|
28
|
+
|
29
|
+
1. Add the prefix `NEW_RELIC_` to the setting's name.
|
30
|
+
2. Replace any periods `.` with underscores `_`.
|
31
|
+
|
32
|
+
You can also configure a few values in the UI via [server-side configuration](/docs/agents/manage-apm-agents/configuration/server-side-agent-configuration).
|
33
|
+
|
34
|
+
The Ruby agent follows this order of precedence for configuration:
|
35
|
+
|
36
|
+
1. Environment variables
|
37
|
+
2. Server-side configuration
|
38
|
+
3. Configuration file (`newrelic.yml`)
|
39
|
+
4. Default configuration settings
|
40
|
+
|
41
|
+
In other words, environment variables override all other configuration settings and info, server-side configuration overrides the configuration file and default config settings, and so on.
|
42
|
+
|
43
|
+
## View and edit config file options [#Edit]
|
44
|
+
|
45
|
+
The Ruby agent's `newrelic.yml` is a standard YAML configuration file. It typically includes a `Defaults` section at the top, plus sections below for each application environment; for example, `Development`, `Testing`, and `Production`.
|
46
|
+
|
47
|
+
The Ruby agent determines which section of the `newrelic.yml` config file to read from by looking at certain environment variables to derive the application's environment. This can be useful, for example, when you want to use `info` for the `log_level` config setting in your production environment, and you want more verbose `log_level` config settings (such as `debug` in your development environment.
|
48
|
+
|
49
|
+
Here is an example `newrelic.yml` config file:
|
50
|
+
|
51
|
+
```yaml
|
52
|
+
common: &default_settings
|
53
|
+
license_key: 'YOUR_LICENSE_KEY'
|
54
|
+
app_name: 'My Application Name'
|
55
|
+
production:
|
56
|
+
<<: *default_settings
|
57
|
+
log_level: info
|
58
|
+
development:
|
59
|
+
<<: *default_settings
|
60
|
+
log_level: debug
|
61
|
+
```
|
62
|
+
|
63
|
+
For non-Rails apps, the Ruby agent looks for the following environment variables, in this order, to determine the application environment:
|
64
|
+
|
65
|
+
1. `NEW_RELIC_ENV`
|
66
|
+
2. `RUBY_ENV`
|
67
|
+
3. `RAILS_ENV`
|
68
|
+
4. `APP_ENV`
|
69
|
+
5. `RACK_ENV`
|
70
|
+
|
71
|
+
If the Ruby agent does not detect values for any of those environment variables, it will default the application environment to `development` and read from the `development` section of the `newrelic.yml` config file.
|
72
|
+
|
73
|
+
When running the Ruby agent in a Rails app, the agent first looks for the `NEW_RELIC_ENV` environment variable to determine the application environment and which section of the `newrelic.yml` to use. If `NEW_RELIC_ENV` is not present, the agent uses the Rails environment (`RAILS_ENV` or `RAILS.env`, depending on the version of Rails) .
|
74
|
+
|
75
|
+
When you edit the config file, be sure to:
|
76
|
+
|
77
|
+
* Indent only with two spaces.
|
78
|
+
* Indent only where relevant, in stanzas such as **`error_collector`**.
|
79
|
+
|
80
|
+
If you do not indent correctly, the agent may throw an `Unable to parse configuration file` error on startup.
|
81
|
+
|
82
|
+
To view the most current list of available Ruby agent configuration options, use the `rake newrelic:config:docs` command. This document describes the most common options.
|
83
|
+
|
84
|
+
## Update the config file [#Updates]
|
85
|
+
|
86
|
+
This documentation applies to the Ruby agent's latest release. For details on earlier versions, refer to the comments in `newrelic.yml` itself.
|
87
|
+
|
88
|
+
To update `newrelic.yml` file after a new release, use the template in the base directory of the agent gem. When you update to new gem versions, examine or diff `config/newrelic.yml` and `newrelic.yml` in the [installation directory](/docs/agents/manage-apm-agents/troubleshooting/find-agent-root-directory#ruby-agent) to take advantage of new configuration options.
|
89
|
+
|
90
|
+
<Callout variant="important">
|
91
|
+
Updating the gem does not automatically update `config/newrelic.yml`.
|
92
|
+
</Callout>
|
93
|
+
|
1
94
|
<% sections.each do |(section_key, section_name, section_description, configs)| %>
|
2
95
|
## <%=section_name%>
|
3
96
|
|
data/lib/tasks/helpers/format.rb
CHANGED
@@ -3,16 +3,19 @@
|
|
3
3
|
# frozen_string_literal: true
|
4
4
|
|
5
5
|
module Format
|
6
|
-
|
7
|
-
config_hash = build_config_hash
|
8
|
-
sections = flatten_config_hash(config_hash)
|
6
|
+
DEFAULT_CONFIG_PATH = 'ruby-agent-configuration.mdx'
|
9
7
|
|
10
|
-
|
11
|
-
|
8
|
+
def output(format)
|
9
|
+
result = build_erb(format).result(binding).split("\n").map(&:rstrip).join("\n").gsub('. ', '. ')
|
10
|
+
File.write(DEFAULT_CONFIG_PATH, result)
|
12
11
|
end
|
13
12
|
|
14
13
|
private
|
15
14
|
|
15
|
+
def sections
|
16
|
+
@sections ||= flatten_config_hash(build_config_hash)
|
17
|
+
end
|
18
|
+
|
16
19
|
def add_data_to_sections(sections)
|
17
20
|
sections.each do |section|
|
18
21
|
section_key = section[0]
|
@@ -66,7 +69,7 @@ module Format
|
|
66
69
|
|
67
70
|
def format_description(value)
|
68
71
|
description = ''
|
69
|
-
description += '
|
72
|
+
description += '**DEPRECATED** ' if value[:deprecated]
|
70
73
|
description += value[:description]
|
71
74
|
description
|
72
75
|
end
|
@@ -81,9 +84,10 @@ module Format
|
|
81
84
|
name = NAME_OVERRIDES[key]
|
82
85
|
return name if name
|
83
86
|
|
84
|
-
key.split('_')
|
87
|
+
title = key.split('_')
|
85
88
|
.each { |fragment| fragment[0] = fragment[0].upcase }
|
86
89
|
.join(' ')
|
90
|
+
"#{title} [##{key.tr('_', '-')}]"
|
87
91
|
end
|
88
92
|
|
89
93
|
def format_sections(key, value)
|
@@ -55,8 +55,8 @@ module VersionBump
|
|
55
55
|
# Replace dev with version number in changelog
|
56
56
|
def self.update_changelog(version)
|
57
57
|
file = read_file('CHANGELOG.md')
|
58
|
-
file.gsub!(
|
59
|
-
file.gsub!(
|
58
|
+
file.gsub!('## dev', "## v#{version}")
|
59
|
+
file.gsub!('Version <dev>', "Version #{version}")
|
60
60
|
write_file('CHANGELOG.md', file)
|
61
61
|
end
|
62
62
|
end
|
data/lib/tasks/newrelicyml.rake
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
3
3
|
# frozen_string_literal: true
|
4
4
|
|
5
|
-
require_relative '
|
5
|
+
require_relative 'helpers/newrelicyml'
|
6
6
|
|
7
7
|
namespace :newrelic do
|
8
8
|
desc 'Update newrelic.yml with latest config options from default_source.rb'
|
data/newrelic.yml
CHANGED
@@ -33,6 +33,9 @@ common: &default_settings
|
|
33
33
|
# - a.third.event
|
34
34
|
# active_support_custom_events_names: []
|
35
35
|
|
36
|
+
# If true, enables capture of all HTTP request headers for all destinations.
|
37
|
+
# allow_all_headers: false
|
38
|
+
|
36
39
|
# Your New Relic userKey. Required when using the New Relic REST API v2 to record
|
37
40
|
# deployments using the newrelic deployments command.
|
38
41
|
# api_key: ""
|
@@ -222,6 +225,10 @@ common: &default_settings
|
|
222
225
|
# (regardless of whether they are installed via Rack::Builder or Rails).
|
223
226
|
# disable_middleware_instrumentation: false
|
224
227
|
|
228
|
+
# If true, disables agent middleware for Roda. This middleware is responsible for
|
229
|
+
# advanced feature support such as page load timing and error collection.
|
230
|
+
# disable_roda_auto_middleware: false
|
231
|
+
|
225
232
|
# If true, disables the collection of sampler metrics. Sampler metrics are metrics
|
226
233
|
# that are not event-based (such as CPU time or memory usage).
|
227
234
|
# disable_samplers: false
|
@@ -479,6 +486,10 @@ common: &default_settings
|
|
479
486
|
# prepend, chain, disabled.
|
480
487
|
# instrumentation.resque: auto
|
481
488
|
|
489
|
+
# Controls auto-instrumentation of Roda at start up. May be one of: auto, prepend,
|
490
|
+
# chain, disabled.
|
491
|
+
# instrumentation.roda: auto
|
492
|
+
|
482
493
|
# Controls auto-instrumentation of Sinatra at start up. May be one of: auto,
|
483
494
|
# prepend, chain, disabled.
|
484
495
|
# instrumentation.sinatra: auto
|
data/newrelic_rpm.gemspec
CHANGED
@@ -39,7 +39,7 @@ Gem::Specification.new do |s|
|
|
39
39
|
'homepage_uri' => 'https://newrelic.com/ruby'
|
40
40
|
}
|
41
41
|
|
42
|
-
reject_list = File.read('
|
42
|
+
reject_list = File.read(File.expand_path('../.build_ignore', __FILE__)).split("\n")
|
43
43
|
file_list = `git ls-files -z`.split("\x0").reject { |f| reject_list.any? { |rf| f.start_with?(rf) } }
|
44
44
|
# test/agent_helper.rb is a requirement for the NewRelic::Agent.require_test_helper public API
|
45
45
|
test_helper_path = 'test/agent_helper.rb'
|
@@ -56,9 +56,10 @@ Gem::Specification.new do |s|
|
|
56
56
|
s.add_development_dependency 'minitest-stub-const', '0.6'
|
57
57
|
s.add_development_dependency 'mocha', '~> 1.16'
|
58
58
|
s.add_development_dependency 'pry' unless ENV['CI']
|
59
|
+
s.add_development_dependency 'rack'
|
59
60
|
s.add_development_dependency 'rake', '12.3.3'
|
60
61
|
|
61
|
-
s.add_development_dependency 'rubocop', '1.
|
62
|
+
s.add_development_dependency 'rubocop', '1.54' unless ENV['CI'] && RUBY_VERSION < '3.0.0'
|
62
63
|
s.add_development_dependency 'rubocop-ast', '1.28.1' unless ENV['CI'] && RUBY_VERSION < '3.0.0'
|
63
64
|
s.add_development_dependency 'rubocop-minitest', '0.27.0' unless ENV['CI'] && RUBY_VERSION < '3.0.0'
|
64
65
|
s.add_development_dependency 'rubocop-performance', '1.16.0' unless ENV['CI'] && RUBY_VERSION < '3.0.0'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: newrelic_rpm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 9.
|
4
|
+
version: 9.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tanna McClure
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2023-
|
14
|
+
date: 2023-08-15 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -69,6 +69,20 @@ dependencies:
|
|
69
69
|
- - "~>"
|
70
70
|
- !ruby/object:Gem::Version
|
71
71
|
version: '1.16'
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: rack
|
74
|
+
requirement: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
72
86
|
- !ruby/object:Gem::Dependency
|
73
87
|
name: rake
|
74
88
|
requirement: !ruby/object:Gem::Requirement
|
@@ -89,14 +103,14 @@ dependencies:
|
|
89
103
|
requirements:
|
90
104
|
- - '='
|
91
105
|
- !ruby/object:Gem::Version
|
92
|
-
version: '1.
|
106
|
+
version: '1.54'
|
93
107
|
type: :development
|
94
108
|
prerelease: false
|
95
109
|
version_requirements: !ruby/object:Gem::Requirement
|
96
110
|
requirements:
|
97
111
|
- - '='
|
98
112
|
- !ruby/object:Gem::Version
|
99
|
-
version: '1.
|
113
|
+
version: '1.54'
|
100
114
|
- !ruby/object:Gem::Dependency
|
101
115
|
name: rubocop-ast
|
102
116
|
requirement: !ruby/object:Gem::Requirement
|
@@ -440,6 +454,11 @@ files:
|
|
440
454
|
- lib/new_relic/agent/instrumentation/resque/helper.rb
|
441
455
|
- lib/new_relic/agent/instrumentation/resque/instrumentation.rb
|
442
456
|
- lib/new_relic/agent/instrumentation/resque/prepend.rb
|
457
|
+
- lib/new_relic/agent/instrumentation/roda.rb
|
458
|
+
- lib/new_relic/agent/instrumentation/roda/chain.rb
|
459
|
+
- lib/new_relic/agent/instrumentation/roda/instrumentation.rb
|
460
|
+
- lib/new_relic/agent/instrumentation/roda/prepend.rb
|
461
|
+
- lib/new_relic/agent/instrumentation/roda/roda_transaction_namer.rb
|
443
462
|
- lib/new_relic/agent/instrumentation/sequel.rb
|
444
463
|
- lib/new_relic/agent/instrumentation/sequel_helper.rb
|
445
464
|
- lib/new_relic/agent/instrumentation/sidekiq.rb
|
@@ -571,6 +590,7 @@ files:
|
|
571
590
|
- lib/new_relic/control/frameworks/rails3.rb
|
572
591
|
- lib/new_relic/control/frameworks/rails4.rb
|
573
592
|
- lib/new_relic/control/frameworks/rails_notifications.rb
|
593
|
+
- lib/new_relic/control/frameworks/roda.rb
|
574
594
|
- lib/new_relic/control/frameworks/ruby.rb
|
575
595
|
- lib/new_relic/control/frameworks/sinatra.rb
|
576
596
|
- lib/new_relic/control/instance_methods.rb
|