newrelic_rpm 8.11.0 → 8.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -3
  3. data/Brewfile +1 -0
  4. data/CHANGELOG.md +45 -16
  5. data/bin/nrdebug +2 -0
  6. data/docker-compose.yml +22 -0
  7. data/lib/new_relic/agent/agent/shutdown.rb +1 -0
  8. data/lib/new_relic/agent/agent/special_startup.rb +2 -0
  9. data/lib/new_relic/agent/agent/startup.rb +1 -0
  10. data/lib/new_relic/agent/attributes.rb +1 -0
  11. data/lib/new_relic/agent/audit_logger.rb +1 -0
  12. data/lib/new_relic/agent/commands/thread_profiler_session.rb +1 -0
  13. data/lib/new_relic/agent/configuration/default_source.rb +26 -4
  14. data/lib/new_relic/agent/configuration/dotted_hash.rb +1 -0
  15. data/lib/new_relic/agent/configuration/environment_source.rb +1 -0
  16. data/lib/new_relic/agent/configuration/high_security_source.rb +1 -0
  17. data/lib/new_relic/agent/configuration/manager.rb +3 -0
  18. data/lib/new_relic/agent/configuration/security_policy_source.rb +10 -0
  19. data/lib/new_relic/agent/configuration/yaml_source.rb +1 -0
  20. data/lib/new_relic/agent/connect/request_builder.rb +1 -0
  21. data/lib/new_relic/agent/database/obfuscation_helpers.rb +1 -0
  22. data/lib/new_relic/agent/database.rb +7 -0
  23. data/lib/new_relic/agent/database_adapter.rb +2 -0
  24. data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +3 -2
  25. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +1 -1
  26. data/lib/new_relic/agent/datastores/nosql_obfuscator.rb +41 -0
  27. data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +3 -0
  28. data/lib/new_relic/agent/distributed_tracing/distributed_trace_attributes.rb +3 -0
  29. data/lib/new_relic/agent/distributed_tracing/distributed_trace_metrics.rb +1 -0
  30. data/lib/new_relic/agent/distributed_tracing/distributed_trace_payload.rb +1 -0
  31. data/lib/new_relic/agent/distributed_tracing/trace_context.rb +1 -0
  32. data/lib/new_relic/agent/encoding_normalizer.rb +2 -0
  33. data/lib/new_relic/agent/error_collector.rb +3 -0
  34. data/lib/new_relic/agent/error_filter.rb +1 -0
  35. data/lib/new_relic/agent/error_trace_aggregator.rb +1 -0
  36. data/lib/new_relic/agent/event_aggregator.rb +1 -0
  37. data/lib/new_relic/agent/event_loop.rb +2 -0
  38. data/lib/new_relic/agent/http_clients/abstract.rb +2 -0
  39. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +1 -0
  40. data/lib/new_relic/agent/instrumentation/active_merchant.rb +1 -0
  41. data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +2 -0
  42. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +1 -0
  43. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +1 -0
  44. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +1 -0
  45. data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +29 -0
  46. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +66 -0
  47. data/lib/new_relic/agent/instrumentation/elasticsearch/prepend.rb +13 -0
  48. data/lib/new_relic/agent/instrumentation/elasticsearch.rb +31 -0
  49. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +1 -0
  50. data/lib/new_relic/agent/instrumentation/logger/instrumentation.rb +4 -0
  51. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +2 -0
  52. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +2 -0
  53. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +3 -0
  54. data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +1 -0
  55. data/lib/new_relic/agent/instrumentation/sidekiq.rb +1 -0
  56. data/lib/new_relic/agent/instrumentation/sinatra.rb +1 -0
  57. data/lib/new_relic/agent/instrumentation/thread/instrumentation.rb +1 -0
  58. data/lib/new_relic/agent/instrumentation/tilt/instrumentation.rb +1 -0
  59. data/lib/new_relic/agent/javascript_instrumentor.rb +1 -0
  60. data/lib/new_relic/agent/local_log_decorator.rb +1 -0
  61. data/lib/new_relic/agent/log_event_aggregator.rb +1 -0
  62. data/lib/new_relic/agent/messaging.rb +1 -0
  63. data/lib/new_relic/agent/method_tracer.rb +4 -0
  64. data/lib/new_relic/agent/monitors/distributed_tracing_monitor.rb +1 -0
  65. data/lib/new_relic/agent/new_relic_service.rb +2 -0
  66. data/lib/new_relic/agent/pipe_channel_manager.rb +2 -0
  67. data/lib/new_relic/agent/rules_engine.rb +1 -0
  68. data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -0
  69. data/lib/new_relic/agent/samplers/memory_sampler.rb +5 -0
  70. data/lib/new_relic/agent/span_event_primitive.rb +1 -0
  71. data/lib/new_relic/agent/stats.rb +1 -0
  72. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +1 -0
  73. data/lib/new_relic/agent/system_info.rb +3 -0
  74. data/lib/new_relic/agent/threading/agent_thread.rb +1 -0
  75. data/lib/new_relic/agent/threading/backtrace_service.rb +1 -0
  76. data/lib/new_relic/agent/threading/thread_profile.rb +3 -0
  77. data/lib/new_relic/agent/tracer.rb +4 -0
  78. data/lib/new_relic/agent/transaction/abstract_segment.rb +3 -0
  79. data/lib/new_relic/agent/transaction/datastore_segment.rb +3 -0
  80. data/lib/new_relic/agent/transaction/distributed_tracer.rb +4 -0
  81. data/lib/new_relic/agent/transaction/distributed_tracing.rb +1 -0
  82. data/lib/new_relic/agent/transaction/external_request_segment.rb +1 -0
  83. data/lib/new_relic/agent/transaction/message_broker_segment.rb +1 -0
  84. data/lib/new_relic/agent/transaction/segment.rb +1 -0
  85. data/lib/new_relic/agent/transaction/trace.rb +4 -0
  86. data/lib/new_relic/agent/transaction/trace_node.rb +1 -0
  87. data/lib/new_relic/agent/transaction/transaction_sample_buffer.rb +2 -0
  88. data/lib/new_relic/agent/transaction.rb +10 -0
  89. data/lib/new_relic/agent/transaction_event_aggregator.rb +1 -0
  90. data/lib/new_relic/agent/transaction_time_aggregator.rb +1 -0
  91. data/lib/new_relic/agent/utilization/pcf.rb +1 -0
  92. data/lib/new_relic/agent/utilization/vendor.rb +2 -0
  93. data/lib/new_relic/agent/utilization_data.rb +3 -0
  94. data/lib/new_relic/agent.rb +4 -2
  95. data/lib/new_relic/cli/commands/install.rb +1 -0
  96. data/lib/new_relic/coerce.rb +6 -0
  97. data/lib/new_relic/collection_helper.rb +1 -0
  98. data/lib/new_relic/control/frameworks/rails.rb +5 -0
  99. data/lib/new_relic/control/instrumentation.rb +2 -0
  100. data/lib/new_relic/dependency_detection.rb +2 -0
  101. data/lib/new_relic/helper.rb +1 -0
  102. data/lib/new_relic/language_support.rb +1 -0
  103. data/lib/new_relic/latest_changes.rb +1 -0
  104. data/lib/new_relic/local_environment.rb +6 -0
  105. data/lib/new_relic/metric_spec.rb +2 -0
  106. data/lib/new_relic/rack/agent_middleware.rb +2 -0
  107. data/lib/new_relic/traced_thread.rb +1 -0
  108. data/lib/new_relic/version.rb +1 -1
  109. data/lib/tasks/helpers/format.rb +3 -0
  110. data/lib/tasks/instrumentation_generator/instrumentation.thor +27 -5
  111. data/lib/tasks/instrumentation_generator/templates/chain.tt +2 -1
  112. data/lib/tasks/instrumentation_generator/templates/chain_method.tt +3 -2
  113. data/lib/tasks/instrumentation_generator/templates/instrumentation.tt +2 -1
  114. data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +1 -1
  115. data/lib/tasks/instrumentation_generator/templates/prepend.tt +1 -1
  116. data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +1 -1
  117. data/lib/tasks/instrumentation_generator/templates/test.tt +1 -1
  118. data/newrelic.yml +13 -3
  119. data/newrelic_rpm.gemspec +6 -6
  120. data/test/agent_helper.rb +6 -0
  121. metadata +11 -77
  122. data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +0 -43
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d0513ed874184a3e737b2663f0fb404f10ddc0f4660da2b85678a1b93f1de1c2
4
- data.tar.gz: b82877030feb527d17c10732a4bfbe9625c36c0f4a3b5fc2e57d4d389f41a857
3
+ metadata.gz: 5b512b5154279638e712582a488b0021e9aa834163183b3172e8489701bdcc0c
4
+ data.tar.gz: d44c55615a3b25be8900bf565ed29f5270be9bf6905f163f4bce9865610526cb
5
5
  SHA512:
6
- metadata.gz: e6ea4eaf8332be93253b1d3d9b894e59c5dee712bad8c098bc1b8c60bff904389b2ae4fb416f1d4d08b4ea36087327955d157101d523e43d1b5ddc97e382c2dc
7
- data.tar.gz: 2139d99e93eb289e976611535a46d58a826f66477931bc93ea5577a8f2c287bc9c49fd2ea9abcaf3f7b739a8c952ed58500c9aeab8daecbbd12f57f2b4d4fe4b
6
+ metadata.gz: 861c112f97dd3c843127264c3a50a34f5601a50addd7378ceec59c8663e58130d5da152f89e2e91cb47ccc6b70cc56f7ad22484357597c4d4b5ae08d01687142
7
+ data.tar.gz: 584f780e7fdc1029b1d97494a545f488c627c59e3fe1a5729cb7f8f3463ad1cf969ada3f77dbf01c1e4e53fa2c84189a88e22f59c1e1d0ab9abfeb8a00d3fbc9
data/.rubocop.yml CHANGED
@@ -132,9 +132,6 @@ Layout/EmptyComment:
132
132
  AllowBorderComment: true
133
133
  AllowMarginComment: true
134
134
 
135
- Layout/EmptyLineAfterGuardClause:
136
- Enabled: false
137
-
138
135
  # Disabling for now
139
136
  Layout/EmptyLineAfterMagicComment:
140
137
  Enabled: false
data/Brewfile CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ brew 'elasticsearch'
2
3
  brew 'imagemagick'
3
4
  brew 'memcached'
4
5
  tap 'mongodb/brew'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # New Relic Ruby Agent Release Notes #
2
2
 
3
+ ## v8.12.0
4
+
5
+ Version 8.12.0 of the agent delivers new Elasticsearch instrumentation, increases the default number of recorded Custom Events, announces the deprecation of Ruby 2.3, and brings some valuable code cleanup.
6
+
7
+ * **Support for Elasticsearch instrumentation**
8
+
9
+ This release adds support to automatically instrument the [elasticsearch](https://rubygems.org/gems/elasticsearch) gem. Versions 7.x and 8.x are supported. [PR#1525](https://github.com/newrelic/newrelic-ruby-agent/pull/1525)
10
+
11
+ | Configuration name | Default | Behavior |
12
+ | ----------- | ----------- |----------- |
13
+ | `instrumentation.elasticsearch` | auto | Controls auto-instrumentation of the elasticsearch library at start up. May be one of `auto`, `prepend`, `chain`, `disabled`. |
14
+ | `elasticsearch.capture_queries` | true | If `true`, the agent captures Elasticsearch queries in transaction traces. |
15
+ | `elasticsearch.obfuscate_queries` | true | If `true`, the agent obfuscates Elasticsearch queries in transaction traces. |
16
+
17
+ * **Custom Event Limit Increase**
18
+
19
+ This version increases the default limit of custom events from 1000 events per minute to 3000 events per minute. In the scenario that custom events were being limited, this change will allow more custom events to be sent to New Relic. There is also a new configurable maximum limit of 100,000 events per minute. To change the limits, see the documentation for [max_samples_stored](https://docs.newrelic.com/docs/apm/agents/ruby-agent/configuration/ruby-agent-configuration/#custom_insights_events-max_samples_stored). To learn more about the change and how to determine if custom events are being dropped, see our Explorers Hub [post](https://discuss.newrelic.com/t/send-more-custom-events-with-the-latest-apm-agents/190497). [PR#1541](https://github.com/newrelic/newrelic-ruby-agent/pull/1541)
20
+
21
+ * **Deprecate support for Ruby 2.3**
22
+
23
+ Ruby 2.3 reached end of life on March 31, 2019. The Ruby agent has deprecated support for Ruby 2.3 and will make breaking changes for this version in its next major release, v9.0.0 (release date not yet planned). All 8.x.x versions of the agent will remain compatible with Ruby 2.3.
24
+
25
+ * **Cleanup: Remove orphaned code**
26
+
27
+ In both the agent and unit tests, changes have taken place over the years that have left certain bits of code unreachable. This orphaned code can complicate code maintenance and refactoring, so getting it squared away can be very helpful. Commmuniy member [@ohbarye](https://github.com/ohbarye) contributed two separate cleanup PRs for this release; one for the agent and one for the tests. [PR#1537](https://github.com/newrelic/newrelic-ruby-agent/pull/1537) [PR#1548](https://github.com/newrelic/newrelic-ruby-agent/pull/1548)
28
+
29
+ Thank you to [@ohbarye](https://github.com/ohbarye) for contributing this helpful cleanup!
30
+
31
+
3
32
  ## v8.11.0
4
33
 
5
34
  Version 8.11.0 of the agent updates the `newrelic deployments` command to work with API keys issued to newer accounts, fixes a memory leak in the instrumentation of Curb error handling, further preps for Ruby 3.2.0 support, and includes several community member driven cleanup and improvement efforts. Thank you to everyone involved!
@@ -49,15 +78,15 @@
49
78
 
50
79
 
51
80
  * **Bugfix: Missing unscoped metrics when instrumentation.thread.tracing is enabled**
52
-
81
+
53
82
  Previously, when `instrumentation.thread.tracing` was set to true, some puma applications encountered a bug where a varying number of unscoped metrics would be missing. The agent now will correctly store and send all unscoped metrics.
54
-
83
+
55
84
  Thank you to @texpert for providing details of their situation to help resolve the issue.
56
-
57
-
85
+
86
+
58
87
  * **Bugfix: gRPC instrumentation causes ArgumentError when other Google gems are present**
59
88
 
60
- Previously, when the agent had gRPC instrumentation enabled in an application using other gems (such as google-ads-googleads), the instrumentation could cause the error `ArgumentError: wrong number of arguments (given 3, expected 2)`. The gRPC instrumentation has been updated to prevent this issue from occurring in the future.
89
+ Previously, when the agent had gRPC instrumentation enabled in an application using other gems (such as google-ads-googleads), the instrumentation could cause the error `ArgumentError: wrong number of arguments (given 3, expected 2)`. The gRPC instrumentation has been updated to prevent this issue from occurring in the future.
61
90
 
62
91
  Thank you to @FeminismIsAwesome for bringing this issue to our attention.
63
92
 
@@ -94,26 +123,26 @@
94
123
 
95
124
 
96
125
  * **Bugfix: Error when setting the yaml configuration with `transaction_tracer.transaction_threshold: apdex_f`**
97
-
98
- Originally, the agent was only checking the `transaction_tracer.transaction_threshold` from the newrelic.yml correctly if it was on two lines.
126
+
127
+ Originally, the agent was only checking the `transaction_tracer.transaction_threshold` from the newrelic.yml correctly if it was on two lines.
99
128
 
100
129
  Example:
101
130
 
102
131
  ```
103
132
  # newrelic.yml
104
133
  transaction_tracer:
105
- transaction_threshold: apdex_f
134
+ transaction_threshold: apdex_f
106
135
  ```
107
136
 
108
- When this was instead changed to be on one line, the agent was not able to correctly identify the value of apdex_f.
137
+ When this was instead changed to be on one line, the agent was not able to correctly identify the value of apdex_f.
109
138
 
110
139
  Example:
111
140
  ```
112
141
  # newrelic.yml
113
142
  transaction_tracer.transaction_threshold: apdex_f
114
143
  ```
115
- This would cause prevent transactions from finishing due to the error `ArgumentError: comparison of Float with String failed`. This has now been corrected and the agent is able to process newrelic.yml with a one line `transaction_tracer.transaction_threshold: apdex_f` correctly now.
116
-
144
+ This would cause prevent transactions from finishing due to the error `ArgumentError: comparison of Float with String failed`. This has now been corrected and the agent is able to process newrelic.yml with a one line `transaction_tracer.transaction_threshold: apdex_f` correctly now.
145
+
117
146
  Thank you to @oboxodo for bringing this to our attention.
118
147
 
119
148
 
@@ -123,8 +152,8 @@
123
152
 
124
153
 
125
154
  ## v8.9.0
126
-
127
-
155
+
156
+
128
157
  * **Add support for Dalli 3.1.0 to Dalli 3.2.2**
129
158
 
130
159
  Dalli versions 3.1.0 and above include breaking changes where the agent previously hooked into the gem. We have updated our instrumentation to correctly hook into Dalli 3.1.0 and above. At this time, 3.2.2 is the latest Dalli version and is confirmed to be supported.
@@ -136,9 +165,9 @@
136
165
 
137
166
  * **Bugfix: Use read_nonblock instead of read on pipe**
138
167
 
139
- Previously, our PipeChannelManager was using read which could cause Resque jobs to get stuck in some versions. This change updates the PipeChannelManager to use read_nonblock instead. This method can leverage error handling to allow the instrumentation to gracefully log a message and exit the stuck Resque job.
168
+ Previously, our PipeChannelManager was using read which could cause Resque jobs to get stuck in some versions. This change updates the PipeChannelManager to use read_nonblock instead. This method can leverage error handling to allow the instrumentation to gracefully log a message and exit the stuck Resque job.
169
+
140
170
 
141
-
142
171
  ## v8.8.0
143
172
 
144
173
  * **Support Makara database adapters with ActiveRecord**
@@ -235,7 +264,7 @@
235
264
  * **Bugfix: Error events missing attributes when created outside of a transaction**
236
265
 
237
266
  Previously the agent was not assigning a priority to error events that were created by calling notice_error outside the scope of a transaction. This caused issues with sampling when the error event buffer was full, resulting in a `NoMethodError: undefined method '<' for nil:NilClass` in the newrelic_agent.log. This bugfix ensures that a priority is always assigned on error events so that the agent will be able to sample these error events correctly. Thank you to @olleolleolle for bringing this issue to our attention.
238
-
267
+
239
268
 
240
269
 
241
270
  ## v8.6.0
data/bin/nrdebug CHANGED
@@ -219,6 +219,7 @@ class ProcessReport
219
219
  if c_backtraces =~ /could not attach/i
220
220
  fail("Failed to attach to target process. Please try again with sudo.")
221
221
  end
222
+
222
223
  section(f, "C Backtraces") { c_backtraces }
223
224
  section(f, "Ruby Backtrace(s)") { ruby_backtraces }
224
225
  end
@@ -282,6 +283,7 @@ end
282
283
  if !target.alive?
283
284
  fail("Could not find process with PID #{target_pid}")
284
285
  end
286
+
285
287
  target_cmd = target.procline
286
288
 
287
289
  prompt_for_confirmation(target_pid, target_cmd)
data/docker-compose.yml CHANGED
@@ -1,5 +1,25 @@
1
1
  version: "3.9"
2
2
  services:
3
+ elasticsearch7:
4
+ image: elasticsearch:7.16.2
5
+ ports:
6
+ - "9200:9200"
7
+ environment:
8
+ - discovery.type=single-node
9
+ - bootstrap.memory_lock=true
10
+ - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
11
+ mem_limit: 1g
12
+ elasticsearch8:
13
+ image: elasticsearch:8.4.2
14
+ ports:
15
+ - "9250:9250"
16
+ environment:
17
+ - discovery.type=single-node
18
+ - xpack.security.enabled=false
19
+ - http.port=9250
20
+ - bootstrap.memory_lock=true
21
+ - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
22
+ mem_limit: 1g
3
23
  mysql:
4
24
  image: mysql:5.7
5
25
  restart: always
@@ -68,6 +88,8 @@ services:
68
88
  volumes:
69
89
  - ".:/usr/src/app"
70
90
  depends_on:
91
+ - elasticsearch7
92
+ - elasticsearch8
71
93
  - mysql
72
94
  - memcached
73
95
  - mongodb
@@ -9,6 +9,7 @@ module NewRelic
9
9
  # data.
10
10
  def shutdown
11
11
  return unless started?
12
+
12
13
  ::NewRelic::Agent.logger.info("Starting Agent shutdown")
13
14
 
14
15
  stop_event_loop
@@ -57,11 +57,13 @@ module NewRelic
57
57
 
58
58
  def should_install_exit_handler?
59
59
  return false unless Agent.config[:send_data_on_exit]
60
+
60
61
  !sinatra_classic_app? || Agent.config[:force_install_exit_handler]
61
62
  end
62
63
 
63
64
  def install_exit_handler
64
65
  return unless should_install_exit_handler?
66
+
65
67
  NewRelic::Agent.logger.debug("Installing at_exit handler")
66
68
  at_exit { shutdown }
67
69
  end
@@ -37,6 +37,7 @@ module NewRelic
37
37
  def check_config_and_start_agent
38
38
  return unless monitoring? && has_correct_license_key?
39
39
  return if using_forking_dispatcher?
40
+
40
41
  setup_and_start_agent
41
42
  end
42
43
 
@@ -58,6 +58,7 @@ module NewRelic
58
58
  def merge_custom_attributes(other)
59
59
  return unless Agent.config[:'custom_attributes.enabled']
60
60
  return if other.empty?
61
+
61
62
  AttributeProcessing.flatten_and_coerce(other) do |k, v|
62
63
  add_custom_attribute(k, v)
63
64
  end
@@ -29,6 +29,7 @@ module NewRelic
29
29
 
30
30
  def log_request_headers(uri, headers)
31
31
  return unless enabled? && allowed_endpoint?(uri)
32
+
32
33
  @log.info("REQUEST HEADERS: #{headers}")
33
34
  rescue StandardError, SystemStackError, SystemCallError => e
34
35
  ::NewRelic::Agent.logger.warn("Failed writing request headers to audit log", e)
@@ -42,6 +42,7 @@ module NewRelic
42
42
 
43
43
  def stop(report_data)
44
44
  return unless running?
45
+
45
46
  NewRelic::Agent.logger.debug("Stopping Thread Profiler.")
46
47
  @finished_profile = @backtrace_service.harvest(NewRelic::Agent::Threading::BacktraceService::ALL_TRANSACTIONS)
47
48
  @backtrace_service.unsubscribe(NewRelic::Agent::Threading::BacktraceService::ALL_TRANSACTIONS)
@@ -467,7 +467,7 @@ When `true`, the agent captures HTTP request parameters and attaches them to tra
467
467
  :public => false,
468
468
  :type => Array,
469
469
  :allowed_from_server => false,
470
- :description => "An array of candidate locations for the agent\'s configuration file."
470
+ :description => "An array of candidate locations for the agent's configuration file."
471
471
  },
472
472
  :dispatcher => {
473
473
  :default => DefaultSource.dispatcher,
@@ -916,6 +916,14 @@ If `true`, disables agent middleware for Sinatra. This middleware is responsible
916
916
  :allowed_from_server => false,
917
917
  :description => 'Controls auto-instrumentation of bunny at start up. May be one of [auto|prepend|chain|disabled].'
918
918
  },
919
+ :'instrumentation.elasticsearch' => {
920
+ :default => 'auto',
921
+ :public => true,
922
+ :type => String,
923
+ :dynamic_name => true,
924
+ :allowed_from_server => false,
925
+ :description => 'Controls auto-instrumentation of the elasticsearch library at start up. May be one of [auto|prepend|chain|disabled].'
926
+ },
919
927
  :'instrumentation.httprb' => {
920
928
  :default => instrumentation_value_of(:disable_httprb),
921
929
  :documentation_default => 'auto',
@@ -1187,7 +1195,7 @@ If `true`, disables agent middleware for Sinatra. This middleware is responsible
1187
1195
  :type => Boolean,
1188
1196
  :deprecated => true,
1189
1197
  :allowed_from_server => false,
1190
- :description => deprecated_description(:'instrumentation.memcache', "If `true`, disables instrumentation for the dalli gem\'s additional CAS client support.")
1198
+ :description => deprecated_description(:'instrumentation.memcache', "If `true`, disables instrumentation for the dalli gem's additional CAS client support.")
1191
1199
  },
1192
1200
  :disable_memcache_instrumentation => {
1193
1201
  :default => false,
@@ -1407,6 +1415,20 @@ If `true`, disables agent middleware for Sinatra. This middleware is responsible
1407
1415
  :allowed_from_server => true,
1408
1416
  :description => 'If `true`, the agent obfuscates Mongo queries in transaction traces.'
1409
1417
  },
1418
+ :'elasticsearch.capture_queries' => {
1419
+ :default => true,
1420
+ :public => true,
1421
+ :type => Boolean,
1422
+ :allowed_from_server => true,
1423
+ :description => 'If `true`, the agent captures Elasticsearch queries in transaction traces.'
1424
+ },
1425
+ :'elasticsearch.obfuscate_queries' => {
1426
+ :default => true,
1427
+ :public => true,
1428
+ :type => Boolean,
1429
+ :allowed_from_server => true,
1430
+ :description => 'If `true`, the agent obfuscates Elasticsearch queries in transaction traces.'
1431
+ },
1410
1432
  :'error_collector.enabled' => {
1411
1433
  :default => true,
1412
1434
  :public => true,
@@ -1972,7 +1994,7 @@ A map of error classes to a list of messages. When an error of one of the classe
1972
1994
  :public => true,
1973
1995
  :type => String,
1974
1996
  :allowed_from_server => false,
1975
- :description => "Manual override for the path to your local CA bundle. This CA bundle will be used to validate the SSL certificate presented by New Relic\'s data collection service."
1997
+ :description => "Manual override for the path to your local CA bundle. This CA bundle will be used to validate the SSL certificate presented by New Relic's data collection service."
1976
1998
  },
1977
1999
  :'rules.ignore_url_regexes' => {
1978
2000
  :default => [],
@@ -2004,7 +2026,7 @@ A map of error classes to a list of messages. When an error of one of the classe
2004
2026
  :description => 'If `true`, the agent captures [custom events](/docs/insights/new-relic-insights/adding-querying-data/inserting-custom-events-new-relic-apm-agents).'
2005
2027
  },
2006
2028
  :'custom_insights_events.max_samples_stored' => {
2007
- :default => 1000,
2029
+ :default => 3000,
2008
2030
  :public => true,
2009
2031
  :type => Integer,
2010
2032
  :allowed_from_server => true,
@@ -36,6 +36,7 @@ module NewRelic
36
36
  def dot_flattened(nested_hash, names = [], result = {})
37
37
  nested_hash.each do |key, val|
38
38
  next if val.nil?
39
+
39
40
  if val.respond_to?(:has_key?)
40
41
  dot_flattened(val, names + [key], result)
41
42
  else
@@ -34,6 +34,7 @@ module NewRelic
34
34
  set_dotted_alias(config_setting)
35
35
 
36
36
  return unless value[:aliases]
37
+
37
38
  value[:aliases].each do |config_alias|
38
39
  self.alias_map[config_alias] = config_setting
39
40
  end
@@ -18,6 +18,7 @@ module NewRelic
18
18
  :'transaction_tracer.record_sql' => record_sql_setting(local_settings, :'transaction_tracer.record_sql'),
19
19
  :'slow_sql.record_sql' => record_sql_setting(local_settings, :'slow_sql.record_sql'),
20
20
  :'mongo.obfuscate_queries' => true,
21
+ :'elasticsearch.obfuscate_queries' => true,
21
22
  :'transaction_tracer.record_redis_arguments' => false,
22
23
 
23
24
  :'custom_insights_events.enabled' => false,
@@ -36,6 +36,7 @@ module NewRelic
36
36
 
37
37
  def add_config_for_testing(source, level = 0)
38
38
  raise 'Invalid config type for testing' unless [Hash, DottedHash].include?(source.class)
39
+
39
40
  invoke_callbacks(:add, source)
40
41
  @configs_for_testing << [source.freeze, level]
41
42
  reset_cache
@@ -110,6 +111,7 @@ module NewRelic
110
111
  def fetch(key)
111
112
  config_stack.each do |config|
112
113
  next unless config
114
+
113
115
  accessor = key.to_sym
114
116
 
115
117
  if config.has_key?(accessor)
@@ -160,6 +162,7 @@ module NewRelic
160
162
 
161
163
  def invoke_callbacks(direction, source)
162
164
  return unless source
165
+
163
166
  source.keys.each do |key|
164
167
  begin
165
168
  # we need to evaluate and apply transformations for the value to deal with procs as values
@@ -79,6 +79,15 @@ module NewRelic
79
79
  change_setting(policies, :'mongo.obfuscate_queries', true)
80
80
  }
81
81
  },
82
+ {
83
+ option: :'elasticsearch.capture_queries',
84
+ supported: true,
85
+ enabled_fn: method(:enabled?),
86
+ disabled_value: false,
87
+ permitted_fn: proc { |policies|
88
+ change_setting(policies, :'elasticsearch.obfuscate_queries', true)
89
+ }
90
+ },
82
91
  {
83
92
  option: :'transaction_tracer.record_redis_arguments',
84
93
  supported: true,
@@ -212,6 +221,7 @@ module NewRelic
212
221
  security_policies.inject({}) do |settings, (policy_name, policy_settings)|
213
222
  SECURITY_SETTINGS_MAP[policy_name].each do |policy|
214
223
  next unless policy[:supported]
224
+
215
225
  if policy_settings[ENABLED]
216
226
  if policy[:enabled_fn].call(policy[:option])
217
227
  if permitted_fn = policy[:permitted_fn]
@@ -156,6 +156,7 @@ module NewRelic
156
156
  def dot_flattened(nested_hash, names = [], result = {})
157
157
  nested_hash.each do |key, val|
158
158
  next if val.nil?
159
+
159
160
  if val.respond_to?(:has_key?) && !CONFIG_WITH_HASH_VALUE.include?(key)
160
161
  dot_flattened(val, names + [key], result)
161
162
  else
@@ -42,6 +42,7 @@ module NewRelic
42
42
  # clear out so downstream code doesn't have to check again.
43
43
  def sanitize_environment_report(environment_report)
44
44
  return NewRelic::EMPTY_ARRAY unless @service.valid_to_marshal?(environment_report)
45
+
45
46
  environment_report
46
47
  end
47
48
 
@@ -53,6 +53,7 @@ module NewRelic
53
53
 
54
54
  def obfuscate_single_quote_literals(sql)
55
55
  return sql unless sql =~ COMPONENTS_REGEX_MAP[:single_quotes]
56
+
56
57
  sql.gsub(COMPONENTS_REGEX_MAP[:single_quotes], PLACEHOLDER)
57
58
  end
58
59
 
@@ -32,6 +32,8 @@ module NewRelic
32
32
  # Take care not to the dup the query more than once as
33
33
  # correctly encoded may also dup the query.
34
34
  def capture_query(query)
35
+ return unless query
36
+
35
37
  id = query.object_id
36
38
  query = Helper.correctly_encoded(truncate_query(query))
37
39
  if query.object_id == id
@@ -42,6 +44,8 @@ module NewRelic
42
44
  end
43
45
 
44
46
  def truncate_query(query)
47
+ return unless query
48
+
45
49
  if query.length > (MAX_QUERY_LENGTH - 4)
46
50
  query[0..MAX_QUERY_LENGTH - 4] << ELLIPSIS
47
51
  else
@@ -114,6 +118,7 @@ module NewRelic
114
118
  # in a report period, selected for shipment to New Relic
115
119
  def explain_sql(statement)
116
120
  return nil unless statement.sql && statement.explainer && statement.config
121
+
117
122
  statement.sql = statement.sql.split(";\n")[0] # only explain the first
118
123
  return statement.explain || []
119
124
  end
@@ -223,6 +228,7 @@ module NewRelic
223
228
 
224
229
  def explain
225
230
  return unless explainable?
231
+
226
232
  handle_exception_in_explain do
227
233
  start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
228
234
  plan = @explainer.call(self)
@@ -238,6 +244,7 @@ module NewRelic
238
244
 
239
245
  def append_sql(new_sql)
240
246
  return if new_sql.empty?
247
+
241
248
  @sql = Database.truncate_query(@sql << NEWLINE << new_sql)
242
249
  end
243
250
 
@@ -13,6 +13,7 @@ module NewRelic
13
13
 
14
14
  def self.value
15
15
  return unless defined? ActiveRecord::Base
16
+
16
17
  new(::NewRelic::Control.instance.env, ActiveRecord::VERSION::STRING).value
17
18
  end
18
19
 
@@ -26,6 +27,7 @@ module NewRelic
26
27
  def value
27
28
  match = VERSIONS.keys.find { |key| version >= Gem::Version.new(key) }
28
29
  return unless match
30
+
29
31
  VERSIONS[match].call(env)
30
32
  end
31
33
  end
@@ -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 'new_relic/agent/datastores/mongo/obfuscator'
5
+ require_relative '../nosql_obfuscator'
6
6
 
7
7
  module NewRelic
8
8
  module Agent
@@ -26,6 +26,7 @@ module NewRelic
26
26
 
27
27
  command.each do |key, value|
28
28
  next if DENYLISTED_KEYS.include?(key)
29
+
29
30
  if OBFUSCATE_KEYS.include?(key)
30
31
  obfuscated = obfuscate(value)
31
32
  result[key] = obfuscated if obfuscated
@@ -38,7 +39,7 @@ module NewRelic
38
39
 
39
40
  def self.obfuscate(statement)
40
41
  if NewRelic::Agent.config[:'mongo.obfuscate_queries']
41
- statement = Obfuscator.obfuscate_statement(statement)
42
+ statement = NewRelic::Agent::Datastores::NosqlObfuscator.obfuscate_statement(statement)
42
43
  end
43
44
  statement
44
45
  end
@@ -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 'new_relic/agent/datastores/mongo/obfuscator'
5
+ require 'new_relic/agent/datastores/nosql_obfuscator'
6
6
  require 'new_relic/agent/datastores/metric_helper'
7
7
 
8
8
  module NewRelic
@@ -0,0 +1,41 @@
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 Datastores
8
+ module NosqlObfuscator
9
+ ALLOWLIST = [:operation].freeze
10
+
11
+ def self.obfuscate_statement(source, allowlist = ALLOWLIST)
12
+ if source.is_a?(Hash)
13
+ obfuscated = {}
14
+ source.each do |key, value|
15
+ if allowlist.include?(key)
16
+ obfuscated[key] = value
17
+ else
18
+ obfuscated[key] = obfuscate_value(value, allowlist)
19
+ end
20
+ end
21
+ obfuscated
22
+ else
23
+ obfuscate_value(source, allowlist)
24
+ end
25
+ end
26
+
27
+ QUESTION_MARK = '?'.freeze
28
+
29
+ def self.obfuscate_value(value, allowlist = ALLOWLIST)
30
+ if value.is_a?(Hash)
31
+ obfuscate_statement(value, allowlist)
32
+ elsif value.is_a?(Array)
33
+ value.map { |v| obfuscate_value(v, allowlist) }
34
+ else
35
+ QUESTION_MARK
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -64,6 +64,7 @@ module NewRelic
64
64
 
65
65
  def add_message_cat_headers(headers)
66
66
  return unless CrossAppTracing.cross_app_enabled?
67
+
67
68
  @is_cross_app_caller = true
68
69
  insert_message_headers(headers,
69
70
  transaction.guid,
@@ -112,9 +113,11 @@ module NewRelic
112
113
  end
113
114
 
114
115
  return unless transaction.include_guid?
116
+
115
117
  payload[:guid] = transaction.guid
116
118
 
117
119
  return unless is_cross_app?
120
+
118
121
  trip_id = cat_trip_id
119
122
  path_hash = cat_path_hash
120
123
  referring_path_hash = cat_referring_path_hash
@@ -25,6 +25,7 @@ module NewRelic
25
25
  # inserts them into the specified destination.
26
26
  def copy_to_hash(transaction_payload, destination)
27
27
  return unless enabled?
28
+
28
29
  INTRINSIC_KEYS.each do |key|
29
30
  value = transaction_payload[key]
30
31
  destination[key] = value unless value.nil?
@@ -35,8 +36,10 @@ module NewRelic
35
36
  # inserts them as intrinsics in the specified transaction_attributes
36
37
  def copy_to_attributes(transaction_payload, destination)
37
38
  return unless enabled?
39
+
38
40
  INTRINSIC_KEYS.each do |key|
39
41
  next unless transaction_payload.key?(key)
42
+
40
43
  destination.add_intrinsic_attribute(key, transaction_payload[key])
41
44
  end
42
45
  end
@@ -23,6 +23,7 @@ module NewRelic
23
23
 
24
24
  def record_metrics_for_transaction(transaction)
25
25
  return unless Agent.config[:'distributed_tracing.enabled']
26
+
26
27
  dt = transaction.distributed_tracer
27
28
  payload = dt.distributed_trace_payload || dt.trace_state_payload
28
29
 
@@ -58,6 +58,7 @@ module NewRelic
58
58
  def from_json(serialized_payload)
59
59
  raw_payload = JSON.parse(serialized_payload)
60
60
  return raw_payload if raw_payload.nil?
61
+
61
62
  payload_data = raw_payload[DATA_KEY]
62
63
 
63
64
  payload = new
@@ -96,6 +96,7 @@ module NewRelic
96
96
  def extract_traceparent(format, carrier)
97
97
  header_name = trace_parent_header_for_format(format)
98
98
  return unless header = carrier[header_name]
99
+
99
100
  if matchdata = header.match(TRACE_PARENT_REGEX)
100
101
  TRACE_PARENT_REGEX.named_captures.inject({}) do |hash, (name, (index))|
101
102
  hash[name] = matchdata[index]
@@ -19,9 +19,11 @@ module NewRelic
19
19
  normalize_string(object.to_s)
20
20
  when Array
21
21
  return object if object.empty?
22
+
22
23
  object.map { |x| normalize_object(x) }
23
24
  when Hash
24
25
  return object if object.empty?
26
+
25
27
  hash = {}
26
28
  object.each_pair do |k, v|
27
29
  k = normalize_string(k) if k.is_a?(String)