newrelic_rpm 7.2.0 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/CHANGELOG.md +105 -9
  4. data/README.md +2 -0
  5. data/lib/new_relic/agent/adaptive_sampler.rb +2 -2
  6. data/lib/new_relic/agent/agent.rb +6 -6
  7. data/lib/new_relic/agent/commands/thread_profiler_session.rb +7 -3
  8. data/lib/new_relic/agent/configuration/default_source.rb +15 -7
  9. data/lib/new_relic/agent/configuration/event_harvest_config.rb +28 -12
  10. data/lib/new_relic/agent/configuration/manager.rb +0 -1
  11. data/lib/new_relic/agent/configuration/server_source.rb +3 -2
  12. data/lib/new_relic/agent/configuration/yaml_source.rb +22 -1
  13. data/lib/new_relic/agent/custom_event_aggregator.rb +2 -1
  14. data/lib/new_relic/agent/database.rb +5 -2
  15. data/lib/new_relic/agent/datastores/mongo.rb +5 -10
  16. data/lib/new_relic/agent/datastores.rb +7 -7
  17. data/lib/new_relic/agent/distributed_tracing/cross_app_payload.rb +5 -5
  18. data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +10 -6
  19. data/lib/new_relic/agent/distributed_tracing/distributed_trace_attributes.rb +0 -1
  20. data/lib/new_relic/agent/distributed_tracing/distributed_trace_payload.rb +1 -1
  21. data/lib/new_relic/agent/distributed_tracing/trace_context_payload.rb +1 -1
  22. data/lib/new_relic/agent/event_loop.rb +6 -6
  23. data/lib/new_relic/agent/external.rb +0 -32
  24. data/lib/new_relic/agent/http_clients/abstract.rb +2 -2
  25. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +1 -1
  26. data/lib/new_relic/agent/instrumentation/active_merchant.rb +3 -3
  27. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +1 -1
  28. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +1 -1
  29. data/lib/new_relic/agent/instrumentation/excon.rb +4 -23
  30. data/lib/new_relic/agent/instrumentation/mongo.rb +3 -141
  31. data/lib/new_relic/agent/instrumentation/queue_time.rb +4 -4
  32. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +5 -5
  33. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +1 -1
  34. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +5 -41
  35. data/lib/new_relic/agent/instrumentation/sidekiq.rb +6 -1
  36. data/lib/new_relic/agent/javascript_instrumentor.rb +3 -3
  37. data/lib/new_relic/agent/messaging.rb +10 -24
  38. data/lib/new_relic/agent/method_tracer.rb +132 -138
  39. data/lib/new_relic/agent/monitors/cross_app_monitor.rb +6 -1
  40. data/lib/new_relic/agent/new_relic_service.rb +9 -9
  41. data/lib/new_relic/agent/pipe_channel_manager.rb +10 -6
  42. data/lib/new_relic/agent/pipe_service.rb +1 -1
  43. data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -1
  44. data/lib/new_relic/agent/span_event_aggregator.rb +2 -2
  45. data/lib/new_relic/agent/sql_sampler.rb +1 -1
  46. data/lib/new_relic/agent/stats_engine/stats_hash.rb +1 -1
  47. data/lib/new_relic/agent/stats_engine.rb +1 -1
  48. data/lib/new_relic/agent/supported_versions.rb +1 -1
  49. data/lib/new_relic/agent/threading/backtrace_service.rb +4 -5
  50. data/lib/new_relic/agent/threading/thread_profile.rb +1 -1
  51. data/lib/new_relic/agent/tracer.rb +15 -37
  52. data/lib/new_relic/agent/transaction/abstract_segment.rb +3 -3
  53. data/lib/new_relic/agent/transaction/message_broker_segment.rb +5 -11
  54. data/lib/new_relic/agent/transaction.rb +7 -28
  55. data/lib/new_relic/agent/transaction_time_aggregator.rb +5 -5
  56. data/lib/new_relic/agent/vm/snapshot.rb +1 -1
  57. data/lib/new_relic/agent/worker_loop.rb +5 -5
  58. data/lib/new_relic/agent.rb +5 -5
  59. data/lib/new_relic/cli/commands/deployments.rb +2 -2
  60. data/lib/new_relic/constants.rb +0 -4
  61. data/lib/new_relic/noticed_error.rb +2 -2
  62. data/lib/new_relic/version.rb +2 -2
  63. data/lib/newrelic_rpm.rb +10 -34
  64. data/lib/tasks/all.rb +1 -1
  65. data/newrelic.yml +593 -3
  66. data/newrelic_rpm.gemspec +1 -1
  67. data/test/agent_helper.rb +27 -2
  68. metadata +3 -8
  69. data/lib/new_relic/agent/datastores/mongo/statement_formatter.rb +0 -53
  70. data/lib/new_relic/agent/instrumentation/excon/connection.rb +0 -49
  71. data/lib/new_relic/agent/instrumentation/merb/controller.rb +0 -44
  72. data/lib/new_relic/agent/instrumentation/merb/errors.rb +0 -33
  73. data/lib/new_relic/control/frameworks/merb.rb +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e364456c599b5484bd0b031f9bc19fd1ec634954c6c060eee1ac85c38adfed78
4
- data.tar.gz: aaaaa6a31504b5aac1da40ac2c0d69fefbbae8525ce96ef38e7fc01460c618d9
3
+ metadata.gz: ea3d77f1e8feb27c92b40dbd4d1732c5c068c786a99ab3f9cd76573ed6a201a1
4
+ data.tar.gz: a825501f60da5aa176ac391cc4acd91192b57736f476b477eae29efec1ca7e53
5
5
  SHA512:
6
- metadata.gz: c8a7d6825a9d05a99d45bffb9fc537f5630f9e8077cd939970f28b17e85991fa80443752bc05560b5fcea7f3a47058e68eb96621f66a0e3b2989206a0aa66ebd
7
- data.tar.gz: 2586902aac108d89c355eccae23acf6b88a72c18abdc773ef4938f3a5aaf17568821e2890bd2ecc4e56695d3798f1f74bdb136f2df3fc6002aacaa563fd329ea
6
+ metadata.gz: 4019cf2596a500dd0b0ffb0c316d5f68bcef00ffd114a480045ad8e3cee708002211da40a3240f0db1b924be06b4656d0e2964818cbce4cc86427436684f0c22
7
+ data.tar.gz: 8b0849f1c3c8ff8b770e83fb67dc77d5ccf0e3f4302c7d77359764c967bec4e2ee1064207a499e0a6a8acf17f25e60a07c974133ade3b14c4866af26ea306052
data/.gitignore CHANGED
@@ -35,3 +35,5 @@ test/fixtures/cross_agent_tests/*/README.md
35
35
  node_modules/
36
36
  yarn.lock
37
37
  errors.txt
38
+ .history/
39
+ vendor/
data/CHANGELOG.md CHANGED
@@ -1,5 +1,102 @@
1
1
  # New Relic Ruby Agent Release Notes #
2
2
 
3
+ ## v8.0.0
4
+
5
+ * **`add_method_tracer` refactored to use prepend over alias_method chaining**
6
+
7
+ This release overhauls the implementation of `add_method_tracer`, as detailed in [issue #502](https://github.com/newrelic/newrelic-ruby-agent/issues/502). The main breaking updates are as follows:
8
+ - A metric name passed to `add_method_tracer` will no longer be interpolated in an instance context as before. To maintain this behavior, pass a Proc object with the same arity as the method being traced. For example:
9
+ ```ruby
10
+ # OLD
11
+ add_method_tracer :foo, '#{args[0]}.#{args[1]}'
12
+
13
+ # NEW
14
+ add_method_tracer :foo, -> (*args) { "#{args[0]}.#{args[1]}" }
15
+ ```
16
+
17
+ - Similarly, the `:code_header` and `:code_footer` options to `add_method_tracer` will *only* accept a Proc object, which will be bound to the calling instance when the traced method is invoked.
18
+
19
+ - Calling `add_method_tracer` for a method will overwrite any previously defined tracers for that method. To specify multiple metric names for a single method tracer, pass them to `add_method_tracer` as an array.
20
+
21
+ See updated documentation on the following pages for full details:
22
+ - [Ruby Custom Instrumentation: Method Tracers](https://docs.newrelic.com/docs/agents/ruby-agent/api-guides/ruby-custom-instrumentation/#method_tracers)
23
+ - [MethodTracer::ClassMethods#add_method_tracer](https://rubydoc.info/github/newrelic/newrelic-ruby-agent/NewRelic/Agent/MethodTracer/ClassMethods#add_method_tracer-instance_method)
24
+
25
+
26
+ * **Distributed tracing is enabled by default**
27
+
28
+ [Distributed tracing](https://docs.newrelic.com/docs/distributed-tracing/enable-configure/language-agents-enable-distributed-tracing/) tracks and observes service requests as they flow through distributed systems. Distributed tracing is now enabled by default and replaces [cross application tracing](https://docs.newrelic.com/docs/agents/ruby-agent/features/cross-application-tracing-ruby/).
29
+
30
+ * **Bugfix: Incorrectly loading configuration options from newrelic.yml**
31
+
32
+ The agent will now import the configuration options [`error_collector.ignore_messages`](https://docs.newrelic.com/docs/agents/ruby-agent/configuration/ruby-agent-configuration/#error_collector-ignore_messages) and [`error_collector.expected_messages`](https://docs.newrelic.com/docs/agents/ruby-agent/configuration/ruby-agent-configuration/#error_collector-expected_messages) from the `newrelic.yml` file correctly.
33
+
34
+ * **Cross Application is now deprecated, and disabled by default**
35
+
36
+ [Distributed tracing](https://docs.newrelic.com/docs/distributed-tracing/enable-configure/language-agents-enable-distributed-tracing/) is replacing [cross application tracing](https://docs.newrelic.com/docs/agents/ruby-agent/features/cross-application-tracing-ruby/) as the default means of tracing between services. To continue using it, enable it with `cross_application_tracer.enabled: true` and `distributed_tracing.enabled: false`
37
+
38
+ * **Update configuration option default value for `span_events.max_samples_stored` from 1000 to 2000**
39
+
40
+ For more information about this congfiguration option, visit [the Ruby agent documentation](https://docs.newrelic.com/docs/agents/ruby-agent/configuration/ruby-agent-configuration/#span_events-max_samples_stored).
41
+
42
+ * **Agent now enforces server supplied maximum value for configuration option `span_events.max_samples_stored`**
43
+
44
+ Upon connection to the New Relic servers, the agent will now enforce a maximum value allowed for the configuration option [`span_events.max_samples_stored`](https://docs.newrelic.com/docs/agents/ruby-agent/configuration/ruby-agent-configuration/#span_events-max_samples_stored) sent from the New Relic servers.
45
+
46
+ * **Remove Ruby 2.0 required kwarg compatibility checks**
47
+
48
+ Our agent has code that provides compatibility for required keyword arguments in Ruby versions below 2.1. Since the agent now only supports Ruby 2.2+, this code is no longer required.
49
+
50
+ * **Replace Time.now with Process.clock_gettime**
51
+
52
+ Calls to `Time.now` have been replaced with calls to `Process.clock_gettime` to leverage the system's built-in clocks for elapsed time (`Process::CLOCK_MONOTONIC`) and wall-clock time (`Process::CLOCK_REALTIME`). This results in fewer object allocations, more accurate elapsed time records, and enhanced performance. Thanks to @sdemjanenko and @viraptor for advocating for this change!
53
+
54
+ * **Updated generated default newrelic.yml**
55
+
56
+ Thank you @wyhaines and @creaturenex for your contribution. The default newrelic.yml that the agent can generate is now updated with commented out examples of all configuration options.
57
+
58
+ * **Bugfix: Psych 4.0 causes errors when loading newrelic.yml**
59
+
60
+ Psych 4.0 now uses safe load behavior when using `YAML.load` which by default doesn't allow aliases, causing errors when the agent loads the config file. We have updated how we load the config file to avoid these errors.
61
+
62
+ * **Remove support for Excon versions below 0.19.0**
63
+
64
+ Excon versions below 0.19.0 will no longer be instrumented through the Ruby agent.
65
+
66
+ * **Remove support for Mongo versions below 2.1**
67
+
68
+ Mongo versions below 2.1 will no longer be instrumented through the Ruby agent.
69
+
70
+ * **Remove tests for Rails 3.0 and Rails 3.1**
71
+
72
+ As of the 7.0 release, the Ruby agent stopped supporting Rails 3.0 and Rails 3.1. Despite this, we still had tests for these versions running on the agent's CI. Those tests are now removed.
73
+
74
+ * **Update test Gemfiles for patched versions**
75
+
76
+ The gem has individual Gemfiles it uses to test against different common user setups. Rails 5.2, 6.0, and 6.1 have been updated to the latest patch versions in the test Gemfiles. Rack was updated in the Rails61 test suite to 2.1.4 to resolve a security vulnerability.
77
+
78
+ * **Remove Merb Support**
79
+
80
+ This release removes the remaining support for the [Merb](https://weblog.rubyonrails.org/2008/12/23/merb-gets-merged-into-rails-3/) framework. It merged with Rails during the 3.0 release. Now that the Ruby agent supports Rails 3.2 and above, we thought it was time to say goodbye.
81
+
82
+ * **Remove deprecated method External.start_segment**
83
+
84
+ The method `NewRelic::Agent::External.start_segment` has been deprecated as of Ruby Agent 6.0.0. This method is now removed.
85
+
86
+ * **Added testing and support for the following gem versions**
87
+
88
+ - activemerchant 1.121.0
89
+ - bunny 2.19.0
90
+ - excon 0.85.0
91
+ - mongo 2.14.0, 2.15.1
92
+ - padrino 0.15.1
93
+ - resque 2.1.0
94
+ - sequel 5.48.0
95
+ - yajl-ruby 1.4.1
96
+
97
+ * **This version adds support for ARM64/Graviton2 platform using Ruby 3.0.2+**
98
+
99
+
3
100
  ## v7.2.0
4
101
 
5
102
  * **Expected Errors and Ignore Errors**
@@ -17,23 +114,22 @@
17
114
  Thanks to @wyhaines for this fix that prevents "can't add a new key into hash during iteration" errors from occuring when iterating over environment data.
18
115
 
19
116
  * **Bugfix: kwarg support fixed for Rack middleware instrumentation**
20
-
21
- Thanks to @walro for submitting this fix. This fixes the rack instrumentation when using kwargs.
117
+
118
+ Thanks to @walro for submitting this fix. This fixes the rack instrumentation when using kwargs.
22
119
 
23
120
  * **Update known conflicts with use of Module#Prepend**
24
121
 
25
122
  With our release of v7.0.0, we updated our instrumentation to use Module#Prepend by default, instead of method chaining. We have received reports of conflicts and added a check for these known conflicts. If a known conflict with prepend is detected while using the default value of 'auto' for gem instrumentation, the agent will instead install method chaining instrumentation in order to avoid this conflict. This check can be bypassed by setting the instrumentation method for the gem to 'prepend'.
26
123
 
27
-
28
124
  ## v7.1.0
29
125
 
30
126
  * **Add support for CSP nonces when using our API to insert the browser agent**
31
-
127
+
32
128
  We now support passing in a nonce to our API method `browser_timing_header` to allow the browser agent to run on applications using CSP nonces. This allows users to inject the browser agent themselves and use the nonce required for the script to run. In order to utilize this new feature, you must disable auto instrumentation for the browser agent, and use the API method browser_timing_header to pass the nonce in and inject the script manually.
33
-
129
+
34
130
  * **Removed MD5 use in the SQL sampler**
35
131
 
36
- In order to allow the agent to run in FIPS compliant environments, the usage of MD5 for aggregating slow sql traces has been replaced with SHA1.
132
+ In order to allow the agent to run in FIPS compliant environments, the usage of MD5 for aggregating slow sql traces has been replaced with SHA1.
37
133
 
38
134
  * **Enable server-side configuration of distributed tracing**
39
135
 
@@ -41,7 +137,7 @@
41
137
 
42
138
  * **Bugfix: Fix for missing part of a previous bugfix**
43
139
 
44
- Our previous fix of "nil Middlewares injection now prevented and gracefully handled in Sinatra" released in 7.0.0 was partially overwritten by some of the other changes in that release. This release adds back those missing sections of the bugfix, and should resolve the issue for sinatra users.
140
+ Our previous fix of "nil Middlewares injection now prevented and gracefully handled in Sinatra" released in 7.0.0 was partially overwritten by some of the other changes in that release. This release adds back those missing sections of the bugfix, and should resolve the issue for sinatra users.
45
141
 
46
142
  * **Update known conflicts with use of Module#Prepend**
47
143
 
@@ -60,8 +156,8 @@
60
156
  correctly when running in a non-forking Resque worker process.
61
157
 
62
158
  * **Bugfix: Added check for ruby2_keywords in add_transaction_tracer**
63
-
64
- Thanks @beauraF for the contribution! Previously, the add_transaction_tracer was not updated when we added support for ruby 3. In order to correctly support `**kwargs`, ruby2_keywords was added to correctly update the method signature to use **kwargs in ruby versions that support that.
159
+
160
+ Thanks @beauraF for the contribution! Previously, the add_transaction_tracer was not updated when we added support for ruby 3. In order to correctly support `**kwargs`, ruby2_keywords was added to correctly update the method signature to use **kwargs in ruby versions that support that.
65
161
 
66
162
  * **Confirmed support for yajl 1.4.0**
67
163
 
data/README.md CHANGED
@@ -11,6 +11,8 @@ to help you improve the customer experience and make data-driven business decisi
11
11
  The New Relic Ruby Agent is dual-purposed as a either a Gem or a Rails plugin,
12
12
  hosted on [github](https://github.com/newrelic/newrelic-ruby-agent).
13
13
 
14
+ [![Gem Version](https://badge.fury.io/rb/newrelic_rpm.svg)](https://badge.fury.io/rb/newrelic_rpm)
15
+
14
16
  ## Supported Environments
15
17
 
16
18
  An up-to-date list of Ruby versions and frameworks for the latest agent
@@ -13,7 +13,7 @@ module NewRelic
13
13
  @sampled_count = 0
14
14
  @period_duration = period_duration
15
15
  @first_period = true
16
- @period_start = Time.now.to_f
16
+ @period_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
17
17
  @lock = Mutex.new
18
18
  register_config_callbacks
19
19
  end
@@ -53,7 +53,7 @@ module NewRelic
53
53
  private
54
54
 
55
55
  def reset_if_period_expired!
56
- now = Time.now.to_f
56
+ now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
57
57
  return unless @period_start + @period_duration <= now
58
58
 
59
59
  elapsed_periods = Integer((now - @period_start) / @period_duration)
@@ -215,7 +215,7 @@ module NewRelic
215
215
  @connected_pid = Process.pid
216
216
  else
217
217
  ::NewRelic::Agent.logger.debug("Child process #{Process.pid} not reporting to non-connected parent (process #{Process.ppid}).")
218
- @service.shutdown(Time.now)
218
+ @service.shutdown
219
219
  disconnect
220
220
  end
221
221
  end
@@ -1123,7 +1123,7 @@ module NewRelic
1123
1123
  end
1124
1124
 
1125
1125
  def transmit_single_data_type(harvest_method, supportability_name)
1126
- now = Time.now
1126
+ now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
1127
1127
 
1128
1128
  msg = "Sending #{supportability_name} data to New Relic Service"
1129
1129
  ::NewRelic::Agent.logger.debug msg
@@ -1132,12 +1132,12 @@ module NewRelic
1132
1132
  self.send(harvest_method)
1133
1133
  end
1134
1134
  ensure
1135
- duration = (Time.now - now).to_f
1135
+ duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - now
1136
1136
  NewRelic::Agent.record_metric("Supportability/#{supportability_name}Harvest", duration)
1137
1137
  end
1138
1138
 
1139
1139
  def transmit_data
1140
- now = Time.now
1140
+ now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
1141
1141
  ::NewRelic::Agent.logger.debug "Sending data to New Relic Service"
1142
1142
 
1143
1143
  @events.notify(:before_harvest)
@@ -1154,7 +1154,7 @@ module NewRelic
1154
1154
  end
1155
1155
  ensure
1156
1156
  NewRelic::Agent::Database.close_connections
1157
- duration = (Time.now - now).to_f
1157
+ duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - now
1158
1158
  NewRelic::Agent.record_metric('Supportability/Harvest', duration)
1159
1159
  end
1160
1160
 
@@ -1179,7 +1179,7 @@ module NewRelic
1179
1179
 
1180
1180
  if @connected_pid == $$ && !@service.kind_of?(NewRelic::Agent::NewRelicService)
1181
1181
  ::NewRelic::Agent.logger.debug "Sending New Relic service agent run shutdown message"
1182
- @service.shutdown(Time.now.to_f)
1182
+ @service.shutdown
1183
1183
  else
1184
1184
  ::NewRelic::Agent.logger.debug "This agent connected from parent process #{@connected_pid}--not sending shutdown"
1185
1185
  end
@@ -38,7 +38,7 @@ module NewRelic
38
38
  agent_command.arguments
39
39
  )
40
40
 
41
- @started_at = Time.now
41
+ @started_at = Process.clock_gettime(Process::CLOCK_REALTIME)
42
42
  @duration = profile.duration if profile
43
43
  end
44
44
 
@@ -51,7 +51,9 @@ module NewRelic
51
51
  end
52
52
 
53
53
  def harvest
54
- NewRelic::Agent.logger.debug("Harvesting from Thread Profiler #{@finished_profile.to_log_description unless @finished_profile.nil?}")
54
+ NewRelic::Agent.logger.debug(
55
+ "Harvesting from Thread Profiler #{@finished_profile.to_log_description unless @finished_profile.nil?}"
56
+ )
55
57
  profile = @finished_profile
56
58
  @backtrace_service.profile_agent_code = false
57
59
  @finished_profile = nil
@@ -72,7 +74,9 @@ module NewRelic
72
74
  end
73
75
 
74
76
  def past_time?
75
- @started_at && (Time.now > @started_at + @duration)
77
+ @started_at && (
78
+ Process.clock_gettime(Process::CLOCK_REALTIME) > @started_at + @duration
79
+ )
76
80
  end
77
81
 
78
82
  def stopped?
@@ -39,6 +39,8 @@ module NewRelic
39
39
  end
40
40
  end
41
41
 
42
+ # Marks the config option as deprecated in the documentation once generated.
43
+ # Does not appear in logs.
42
44
  def self.deprecated_description new_setting, description
43
45
  link_ref = new_setting.to_s.gsub(".", "-")
44
46
  %{Please see: [#{new_setting}](docs/agents/ruby-agent/configuration/ruby-agent-configuration##{link_ref}). \n\n#{description}}
@@ -120,7 +122,6 @@ module NewRelic
120
122
  Proc.new {
121
123
  case
122
124
  when defined?(::NewRelic::TEST) then :test
123
- when defined?(::Merb) && defined?(::Merb::Plugins) then :merb
124
125
  when defined?(::Rails::VERSION)
125
126
  case Rails::VERSION::MAJOR
126
127
  when 0..2
@@ -1479,11 +1480,15 @@ module NewRelic
1479
1480
  :description => 'List of trusted New Relic account IDs for the purposes of cross-application tracing. Inbound requests from applications including cross-application headers that do not come from an account in this list will be ignored.'
1480
1481
  },
1481
1482
  :"cross_application_tracer.enabled" => {
1482
- :default => Proc.new { !NewRelic::Agent.config[:'distributed_tracing.enabled'] },
1483
+ :default => false,
1483
1484
  :public => true,
1484
1485
  :type => Boolean,
1485
1486
  :allowed_from_server => true,
1486
- :description => 'If `true`, enables [cross-application tracing](/docs/apm/transactions/cross-application-traces/cross-application-tracing).'
1487
+ :deprecated => true,
1488
+ :description => deprecated_description(
1489
+ :'distributed_tracing-enabled',
1490
+ 'If `true`, enables [cross-application tracing](/docs/agents/ruby-agent/features/cross-application-tracing-ruby/)'
1491
+ )
1487
1492
  },
1488
1493
  :cross_application_tracing => {
1489
1494
  :default => nil,
@@ -1492,7 +1497,7 @@ module NewRelic
1492
1497
  :type => Boolean,
1493
1498
  :allowed_from_server => false,
1494
1499
  :deprecated => true,
1495
- :description => 'Deprecated in favor of cross_application_tracer.enabled'
1500
+ :description => 'Deprecated in favor of distributed_tracing.enabled'
1496
1501
  },
1497
1502
  :encoding_key => {
1498
1503
  :default => '',
@@ -1792,7 +1797,10 @@ module NewRelic
1792
1797
  :type => Array,
1793
1798
  :allowed_from_server => true,
1794
1799
  :transform => DefaultSource.method(:convert_to_regexp_list),
1795
- :description => 'Define transactions you want the agent to ignore, by specifying a list of patterns matching the URI you want to ignore.'
1800
+ :description => 'Define transactions you want the agent to ignore, by specifying a list of patterns matching the URI you want to ignore.' \
1801
+ '*Note:* This will only ignore transaction events, not spans or traces from the same transation. See documentation on ' \
1802
+ '(Ignoring Specific Transactions)[https://docs.newrelic.com/docs/agents/ruby-agent/api-guides/ignoring-specific-transactions/#config-ignoring] ' \
1803
+ 'for more details.'
1796
1804
  },
1797
1805
  :'synthetics.traces_limit' => {
1798
1806
  :default => 20,
@@ -2127,7 +2135,7 @@ module NewRelic
2127
2135
  :description => 'The primary id associated with this application.'
2128
2136
  },
2129
2137
  :'distributed_tracing.enabled' => {
2130
- :default => false,
2138
+ :default => true,
2131
2139
  :public => true,
2132
2140
  :type => Boolean,
2133
2141
  :allowed_from_server => true,
@@ -2171,7 +2179,7 @@ module NewRelic
2171
2179
  :description => "Sets the maximum number of span events to buffer when streaming to the trace observer."
2172
2180
  },
2173
2181
  :'span_events.max_samples_stored' => {
2174
- :default => 1000,
2182
+ :default => 2000,
2175
2183
  :public => true,
2176
2184
  :type => Integer,
2177
2185
  :allowed_from_server => true,
@@ -13,12 +13,13 @@ module NewRelic
13
13
  :analytic_event_data => :'analytics_events.max_samples_stored',
14
14
  :custom_event_data => :'custom_insights_events.max_samples_stored',
15
15
  :error_event_data => :'error_collector.max_event_samples_stored',
16
- :span_event_data => :'span_events.max_samples_stored'
17
16
  }
18
17
 
19
18
  def from_config(config)
20
- {:harvest_limits => EVENT_HARVEST_CONFIG_KEY_MAPPING.inject({}) do
21
- |connect_payload, (connect_payload_key, config_key)|
19
+ {:harvest_limits =>
20
+ EVENT_HARVEST_CONFIG_KEY_MAPPING.merge(
21
+ :span_event_data => :'span_events.max_samples_stored'
22
+ ).inject({}) do |connect_payload, (connect_payload_key, config_key)|
22
23
  connect_payload[connect_payload_key] = config[config_key]
23
24
  connect_payload
24
25
  end
@@ -27,16 +28,31 @@ module NewRelic
27
28
 
28
29
  def to_config_hash(connect_reply)
29
30
  event_harvest_interval = connect_reply['event_harvest_config']['report_period_ms'] / 1000
30
- config_hash = EVENT_HARVEST_CONFIG_KEY_MAPPING.inject({}) do
31
- |event_harvest_config, (connect_payload_key, config_key)|
32
- if harvest_limit = connect_reply['event_harvest_config']['harvest_limits'][connect_payload_key.to_s]
33
- event_harvest_config[config_key] = harvest_limit
34
- report_period_key = :"event_report_period.#{connect_payload_key}"
35
- event_harvest_config[report_period_key] = event_harvest_interval
36
- end
37
- event_harvest_config
38
- end
31
+ config_hash = transform_event_harvest_config_keys(connect_reply, event_harvest_interval)
39
32
  config_hash[:event_report_period] = event_harvest_interval
33
+ config_hash = transform_span_event_harvest_config(config_hash, connect_reply)
34
+ config_hash
35
+ end
36
+
37
+ private
38
+
39
+ def transform_event_harvest_config_keys(connect_reply, event_harvest_interval)
40
+ EVENT_HARVEST_CONFIG_KEY_MAPPING.inject({}) do |event_harvest_config, (connect_payload_key, config_key)|
41
+ if harvest_limit = connect_reply['event_harvest_config']['harvest_limits'][connect_payload_key.to_s]
42
+ event_harvest_config[config_key] = harvest_limit
43
+ report_period_key = :"event_report_period.#{connect_payload_key}"
44
+ event_harvest_config[report_period_key] = event_harvest_interval
45
+ end
46
+ event_harvest_config
47
+ end
48
+ end
49
+
50
+ def transform_span_event_harvest_config(config_hash, connect_reply)
51
+ if span_harvest = connect_reply['span_event_harvest_config']
52
+ config_hash[:'span_events.max_samples_stored'] = span_harvest['harvest_limit'] if span_harvest['harvest_limit']
53
+ config_hash[:'event_report_period.span_event_data'] = span_harvest['report_period_ms'] if span_harvest['report_period_ms']
54
+ end
55
+
40
56
  config_hash
41
57
  end
42
58
  end
@@ -15,7 +15,6 @@ module NewRelic
15
15
  module Agent
16
16
  module Configuration
17
17
  class Manager
18
-
19
18
  # Defining these explicitly saves object allocations that we incur
20
19
  # if we use Forwardable and def_delegators.
21
20
  def [](key)
@@ -79,8 +79,9 @@ module NewRelic
79
79
  :'analytics_events.max_samples_stored' => 'Supportability/EventHarvest/AnalyticEventData/HarvestLimit',
80
80
  :'custom_insights_events.max_samples_stored' => 'Supportability/EventHarvest/CustomEventData/HarvestLimit',
81
81
  :'error_collector.max_event_samples_stored'=> 'Supportability/EventHarvest/ErrorEventData/HarvestLimit',
82
- :'span_events.max_samples_stored'=> 'Supportability/EventHarvest/SpanEventData/HarvestLimit',
83
- :event_report_period => 'Supportability/EventHarvest/ReportPeriod'
82
+ :'span_events.max_samples_stored' => 'Supportability/SpanEvent/Limit',
83
+ :event_report_period => 'Supportability/EventHarvest/ReportPeriod',
84
+ :'event_report_period.span_event_data' => 'Supportability/SpanEvent/ReportPeriod',
84
85
  }
85
86
 
86
87
  def add_event_harvest_config(merged_settings, connect_reply)
@@ -11,6 +11,10 @@ module NewRelic
11
11
  attr_accessor :file_path, :failures
12
12
  attr_reader :generated_for_user, :license_key
13
13
 
14
+ # These are configuration options that have a value of a Hash
15
+ # This is used in YamlSource#dot_flattened prevent flattening these values
16
+ CONFIG_WITH_HASH_VALUE = ['expected_messages', 'ignore_messages']
17
+
14
18
  def initialize(path, env)
15
19
  @path = path
16
20
  config = {}
@@ -99,7 +103,12 @@ module NewRelic
99
103
 
100
104
  def process_yaml(file, env, config, path)
101
105
  if file
102
- confighash = YAML.load(file)
106
+ confighash = if YAML.respond_to?(:unsafe_load)
107
+ YAML.unsafe_load(file)
108
+ else
109
+ YAML.load(file)
110
+ end
111
+
103
112
  unless confighash.key?(env)
104
113
  log_failure("Config file at #{path} doesn't include a '#{env}' section!")
105
114
  end
@@ -141,6 +150,18 @@ module NewRelic
141
150
  ::NewRelic::Agent.logger.error(*messages)
142
151
  messages.each { |message| @failures << message }
143
152
  end
153
+
154
+ def dot_flattened(nested_hash, names=[], result={})
155
+ nested_hash.each do |key, val|
156
+ next if val == nil
157
+ if val.respond_to?(:has_key?) && !CONFIG_WITH_HASH_VALUE.include?(key)
158
+ dot_flattened(val, names + [key], result)
159
+ else
160
+ result[(names + [key]).join('.')] = val
161
+ end
162
+ end
163
+ result
164
+ end
144
165
  end
145
166
  end
146
167
  end
@@ -46,7 +46,8 @@ module NewRelic
46
46
 
47
47
  def create_event(type, priority, attributes)
48
48
  [
49
- { TYPE => type, TIMESTAMP => Time.now.to_i,
49
+ { TYPE => type,
50
+ TIMESTAMP => Process.clock_gettime(Process::CLOCK_REALTIME).to_i,
50
51
  PRIORITY => priority
51
52
  },
52
53
  AttributeProcessing.flatten_and_coerce(attributes)
@@ -228,9 +228,12 @@ module NewRelic
228
228
  def explain
229
229
  return unless explainable?
230
230
  handle_exception_in_explain do
231
- start = Time.now
231
+ start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
232
232
  plan = @explainer.call(self)
233
- ::NewRelic::Agent.record_metric("Supportability/Database/execute_explain_plan", Time.now - start)
233
+ ::NewRelic::Agent.record_metric(
234
+ "Supportability/Database/execute_explain_plan",
235
+ Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
236
+ )
234
237
  return process_resultset(plan, adapter) if plan
235
238
  end
236
239
  end
@@ -7,22 +7,17 @@ module NewRelic
7
7
  module Datastores
8
8
  module Mongo
9
9
  def self.is_supported_version?
10
- # No version constant in < 2.0 versions of Mongo :(
11
- defined?(::Mongo) && (defined?(::Mongo::MongoClient) || is_monitoring_enabled?)
12
- end
13
-
14
- def self.is_monitoring_enabled?
15
- defined?(::Mongo::Monitoring) # @since 2.1.0
10
+ defined?(::Mongo) && is_monitoring_enabled?
16
11
  end
17
12
 
18
13
  def self.is_unsupported_2x?
19
- defined?(::Mongo::VERSION) && Gem::Version.new(::Mongo::VERSION).segments[0] == 2 &&
14
+ defined?(::Mongo::VERSION) &&
15
+ Gem::Version.new(::Mongo::VERSION).segments[0] == 2 &&
20
16
  !self.is_monitoring_enabled?
21
17
  end
22
18
 
23
- def self.is_version_1_10_or_later?
24
- # Again, no VERSION constant in 1.x, so we have to rely on constant checks
25
- defined?(::Mongo::CollectionOperationWriter)
19
+ def self.is_monitoring_enabled?
20
+ defined?(::Mongo::Monitoring) # @since 2.1.0
26
21
  end
27
22
  end
28
23
  end
@@ -21,7 +21,7 @@ module NewRelic
21
21
  # query content into Transaction Traces. Use wrap if you want to provide
22
22
  # that functionality.
23
23
  #
24
- # @param [Class] clazz the class to instrument
24
+ # @param [Class] klass the class to instrument
25
25
  #
26
26
  # @param [String, Symbol] method_name the name of instance method to
27
27
  # instrument
@@ -33,16 +33,16 @@ module NewRelic
33
33
  #
34
34
  # @api public
35
35
  #
36
- def self.trace(clazz, method_name, product, operation = method_name)
36
+ def self.trace(klass, method_name, product, operation = method_name)
37
37
  NewRelic::Agent.record_api_supportability_metric(:trace)
38
38
 
39
- clazz.class_eval do
39
+ klass.class_eval do
40
40
  method_name_without_newrelic = "#{method_name}_without_newrelic"
41
41
 
42
- if NewRelic::Helper.instance_methods_include?(clazz, method_name) &&
43
- !NewRelic::Helper.instance_methods_include?(clazz, method_name_without_newrelic)
42
+ if NewRelic::Helper.instance_methods_include?(klass, method_name) &&
43
+ !NewRelic::Helper.instance_methods_include?(klass, method_name_without_newrelic)
44
44
 
45
- visibility = NewRelic::Helper.instance_method_visibility(clazz, method_name)
45
+ visibility = NewRelic::Helper.instance_method_visibility(klass, method_name)
46
46
 
47
47
  alias_method method_name_without_newrelic, method_name
48
48
 
@@ -123,7 +123,7 @@ module NewRelic
123
123
  ensure
124
124
  begin
125
125
  if callback
126
- elapsed_time = (Time.now - segment.start_time).to_f
126
+ elapsed_time = Process.clock_gettime(Process::CLOCK_REALTIME) - segment.start_time
127
127
  callback.call(result, segment.name, elapsed_time)
128
128
  end
129
129
  ensure
@@ -19,15 +19,15 @@ module NewRelic
19
19
  end
20
20
 
21
21
  def as_json_array(content_length)
22
- queue_time_in_seconds = [transaction.queue_time.to_f, 0.0].max
23
- start_time_in_seconds = [transaction.start_time.to_f, 0.0].max
24
- app_time_in_seconds = Time.now.to_f - start_time_in_seconds
22
+ queue_time_in_seconds = [transaction.queue_time, 0.0].max
23
+ start_time_in_seconds = [transaction.start_time, 0.0].max
24
+ app_time_in_seconds = Process.clock_gettime(Process::CLOCK_REALTIME) - start_time_in_seconds
25
25
 
26
26
  [
27
27
  NewRelic::Agent.config[:cross_process_id],
28
28
  transaction.best_name,
29
- queue_time_in_seconds.to_f,
30
- app_time_in_seconds.to_f,
29
+ queue_time_in_seconds,
30
+ app_time_in_seconds,
31
31
  content_length,
32
32
  transaction.guid,
33
33
  false
@@ -54,6 +54,7 @@ module NewRelic
54
54
 
55
55
  def insert_cross_app_header headers
56
56
  return unless CrossAppTracing.cross_app_enabled?
57
+
57
58
  @is_cross_app_caller = true
58
59
  txn_guid = transaction.guid
59
60
  trip_id = cat_trip_id
@@ -65,17 +66,20 @@ module NewRelic
65
66
  def add_message_cat_headers headers
66
67
  return unless CrossAppTracing.cross_app_enabled?
67
68
  @is_cross_app_caller = true
68
- insert_message_headers headers,
69
- transaction.guid,
70
- cat_trip_id,
71
- cat_path_hash,
69
+ insert_message_headers headers,
70
+ transaction.guid,
71
+ cat_trip_id,
72
+ cat_path_hash,
72
73
  transaction.raw_synthetics_header
73
74
  end
74
75
 
75
76
  def record_cross_app_metrics
76
77
  if (id = cross_app_payload && cross_app_payload.id)
77
- app_time_in_seconds = [Time.now.to_f - transaction.start_time.to_f, 0.0].max
78
- NewRelic::Agent.record_metric "ClientApplication/#{id}/all", app_time_in_seconds
78
+ app_time_in_seconds = [
79
+ Process.clock_gettime(Process::CLOCK_REALTIME) - transaction.start_time,
80
+ 0.0
81
+ ].max
82
+ NewRelic::Agent.record_metric("ClientApplication/#{id}/all", app_time_in_seconds)
79
83
  end
80
84
  end
81
85
 
@@ -64,7 +64,6 @@ module NewRelic
64
64
  destination[PARENT_TYPE_KEY] = trace_payload.parent_type
65
65
  destination[PARENT_APP_KEY] = trace_payload.parent_app_id
66
66
  destination[PARENT_ACCOUNT_ID_KEY] = trace_payload.parent_account_id
67
-
68
67
  destination[PARENT_TRANSPORT_DURATION_KEY] = transaction.calculate_transport_duration trace_payload
69
68
 
70
69
  if parent_transaction_id = transaction.distributed_tracer.parent_transaction_id