newrelic_rpm 9.17.0 → 9.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.build_ignore +1 -0
  3. data/CHANGELOG.md +57 -1
  4. data/lib/new_relic/agent/agent.rb +2 -0
  5. data/lib/new_relic/agent/agent_helpers/connect.rb +3 -3
  6. data/lib/new_relic/agent/agent_helpers/harvest.rb +3 -3
  7. data/lib/new_relic/agent/agent_helpers/shutdown.rb +1 -1
  8. data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +1 -1
  9. data/lib/new_relic/agent/agent_helpers/startup.rb +4 -4
  10. data/lib/new_relic/agent/configuration/default_source.rb +105 -80
  11. data/lib/new_relic/agent/configuration/yaml_source.rb +2 -2
  12. data/lib/new_relic/agent/http_clients/uri_util.rb +1 -1
  13. data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +6 -2
  14. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +1 -0
  15. data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +3 -3
  16. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +0 -2
  17. data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delay_extensions.rb +24 -0
  18. data/lib/new_relic/agent/instrumentation/sidekiq.rb +9 -1
  19. data/lib/new_relic/agent/new_relic_service.rb +2 -2
  20. data/lib/new_relic/agent/opentelemetry/trace/span.rb +23 -0
  21. data/lib/new_relic/agent/opentelemetry/trace/tracer.rb +38 -0
  22. data/lib/new_relic/agent/opentelemetry/trace/tracer_provider.rb +18 -0
  23. data/lib/new_relic/agent/opentelemetry/trace.rb +15 -0
  24. data/lib/new_relic/agent/opentelemetry_bridge.rb +26 -0
  25. data/lib/new_relic/agent/span_event_primitive.rb +3 -1
  26. data/lib/new_relic/agent/transaction/abstract_segment.rb +2 -1
  27. data/lib/new_relic/agent/transaction/request_attributes.rb +1 -6
  28. data/lib/new_relic/agent/transaction/trace_context.rb +33 -4
  29. data/lib/new_relic/agent/transaction/tracing.rb +4 -5
  30. data/lib/new_relic/agent/transaction.rb +2 -1
  31. data/lib/new_relic/agent/utilization_data.rb +15 -5
  32. data/lib/new_relic/control/instance_methods.rb +5 -0
  33. data/lib/new_relic/version.rb +1 -1
  34. data/lib/tasks/helpers/newrelicyml.rb +4 -2
  35. data/newrelic.yml +72 -35
  36. metadata +8 -15
  37. data/lib/tasks/instrumentation_generator/README.md +0 -63
  38. data/lib/tasks/instrumentation_generator/TODO.md +0 -33
  39. data/lib/tasks/instrumentation_generator/instrumentation.thor +0 -130
  40. data/lib/tasks/instrumentation_generator/templates/Envfile.tt +0 -9
  41. data/lib/tasks/instrumentation_generator/templates/chain.tt +0 -21
  42. data/lib/tasks/instrumentation_generator/templates/chain_method.tt +0 -7
  43. data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +0 -32
  44. data/lib/tasks/instrumentation_generator/templates/instrumentation.tt +0 -13
  45. data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +0 -3
  46. data/lib/tasks/instrumentation_generator/templates/newrelic.yml.tt +0 -19
  47. data/lib/tasks/instrumentation_generator/templates/prepend.tt +0 -13
  48. data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +0 -3
  49. data/lib/tasks/instrumentation_generator/templates/test.tt +0 -15
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.17.0
4
+ version: 9.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanna McClure
@@ -10,7 +10,7 @@ authors:
10
10
  - Hannah Ramadan
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2025-01-29 00:00:00.000000000 Z
13
+ date: 2025-04-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -555,6 +555,7 @@ files:
555
555
  - lib/new_relic/agent/instrumentation/sequel_helper.rb
556
556
  - lib/new_relic/agent/instrumentation/sidekiq.rb
557
557
  - lib/new_relic/agent/instrumentation/sidekiq/client.rb
558
+ - lib/new_relic/agent/instrumentation/sidekiq/extensions/delay_extensions.rb
558
559
  - lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb
559
560
  - lib/new_relic/agent/instrumentation/sidekiq/server.rb
560
561
  - lib/new_relic/agent/instrumentation/sinatra.rb
@@ -613,6 +614,11 @@ files:
613
614
  - lib/new_relic/agent/noticeable_error.rb
614
615
  - lib/new_relic/agent/null_logger.rb
615
616
  - lib/new_relic/agent/obfuscator.rb
617
+ - lib/new_relic/agent/opentelemetry/trace.rb
618
+ - lib/new_relic/agent/opentelemetry/trace/span.rb
619
+ - lib/new_relic/agent/opentelemetry/trace/tracer.rb
620
+ - lib/new_relic/agent/opentelemetry/trace/tracer_provider.rb
621
+ - lib/new_relic/agent/opentelemetry_bridge.rb
616
622
  - lib/new_relic/agent/parameter_filtering.rb
617
623
  - lib/new_relic/agent/payload_metric_mapping.rb
618
624
  - lib/new_relic/agent/pipe_channel_manager.rb
@@ -746,19 +752,6 @@ files:
746
752
  - lib/tasks/helpers/prompt.rb
747
753
  - lib/tasks/helpers/version_bump.rb
748
754
  - lib/tasks/install.rake
749
- - lib/tasks/instrumentation_generator/README.md
750
- - lib/tasks/instrumentation_generator/TODO.md
751
- - lib/tasks/instrumentation_generator/instrumentation.thor
752
- - lib/tasks/instrumentation_generator/templates/Envfile.tt
753
- - lib/tasks/instrumentation_generator/templates/chain.tt
754
- - lib/tasks/instrumentation_generator/templates/chain_method.tt
755
- - lib/tasks/instrumentation_generator/templates/dependency_detection.tt
756
- - lib/tasks/instrumentation_generator/templates/instrumentation.tt
757
- - lib/tasks/instrumentation_generator/templates/instrumentation_method.tt
758
- - lib/tasks/instrumentation_generator/templates/newrelic.yml.tt
759
- - lib/tasks/instrumentation_generator/templates/prepend.tt
760
- - lib/tasks/instrumentation_generator/templates/prepend_method.tt
761
- - lib/tasks/instrumentation_generator/templates/test.tt
762
755
  - lib/tasks/newrelic.rb
763
756
  - lib/tasks/newrelicyml.rake
764
757
  - lib/tasks/tests.rake
@@ -1,63 +0,0 @@
1
- # Instrumentation Generator
2
-
3
- ## Usage
4
-
5
- `thor list` can be passed to get a list of all available thor commands
6
-
7
- ### instrumentation:scaffold
8
-
9
- This task requires one parameter by default: the name of the library or class you are instrumenting. This task generates the basic file structure needed to add new instrumentation to the Ruby agent.
10
-
11
- Run it using:
12
-
13
- `thor instrumentation:scaffold gem_name`
14
-
15
- It accepts two optional parameters:
16
-
17
- - `--method`: the name of a method to instrument. Only one method can be accepted at this time. Defaults to `method_to_instrument`
18
- - `--args`: the arguments for the instrumented method. A comma-separated list can be given if there are multiple arguments. Defaults to `*args`.
19
-
20
- With the optional parameters, the task can be run like so:
21
-
22
- `thor instrumentation:scaffold gem_name --method=method_to_instrument --args=arg1,arg2,arg3`
23
-
24
- ### WIP: instrumentation:add_new_method
25
-
26
- Are you trying add instrumentation for a method within library we already instrument? This task is for you! Instead of building the entire scaffold, this task inserts only the changes needed within the `instrumentation.rb` and test files to instrument the new method. It requires one argument, the name of the existing instrumentation to add the method to. If the instrumented library does not already exist, it will create a new scaffold for that library.
27
-
28
- Run it using:
29
-
30
- `thor instrumentation:scaffold gem_name`
31
-
32
- It accepts two optional parameters:
33
-
34
- - `--method`: the name of a method to instrument. Only one method can be accepted at this time. Defaults to `method_to_instrument`
35
- - `--args`: the arguments for the instrumented method. A comma-separated list can be given if there are multiple arguments. Defaults to `*args`.
36
-
37
- With the optional parameters, the task can be run like so:
38
-
39
- `thor instrumentation:add_new_method gem_name --method=method_to_instrument --args=arg1,arg2,arg3`
40
-
41
- ## Idea
42
-
43
- Create a CLI, similar to Rails’ generators and scaffold scripts, to create the required files and basic classes for instrumenting new libraries. The hope is that the parts of adding new instrumentation that is repetitive can be eliminated and/or reduced so that it takes less time to add new instrumentation and we can spend development time considering the best attributes to collect and interactions to measure. I also hope this project will reduce the overall toil related to adding new instrumentation.
44
-
45
- The files we create with little variation besides library and method names are:
46
-
47
- - Lib
48
- - Dependency detection
49
- - Chain
50
- - Prepend
51
- - Instrumentation
52
- - Tests
53
- - configuration/newrelic.yml
54
- - Envfile
55
- - Test file
56
-
57
- Furthermore, we also create very similar snippets inside the default source configuration file that could be generated by this project as well.
58
-
59
- ## Outcome
60
-
61
- A prototype outside the agent was first created. This prototype generated the required files to add instrumentation. The prototype accepted three arguments: name (name of the library), method (method to instrument), args (arguments for the method). This prototype has evolved into the current directory.
62
-
63
- This project leverages the Ruby gem Thor, a toolkit for building powerful command-line interfaces used in Bundler, Vagrant, Rails and others powers this CLI.
@@ -1,33 +0,0 @@
1
- # TODO
2
-
3
- # - [X] Create instrumentation file
4
-
5
- # - [X] Create chain file
6
-
7
- # - [X] Create prepend file
8
-
9
- # - [X] Create dependency detection file
10
-
11
- # - [X] Add config to default source
12
-
13
- # - [X] Create multiverse suite
14
-
15
- # - [X] Create Envfile
16
-
17
- # - [X] Create test file with examples
18
-
19
- # - [X] Create option for method names to instrument
20
-
21
- # - [X] Add entry to newrelic.yml
22
-
23
- # - [ ] Append a new method to instrument to an existing instrumentation class (with tests?)
24
-
25
- # - [ ] Documentation: examples of what to add in each gap (Good examples of tests, instrumentation, etc. as comments to guide users)
26
-
27
- # - [ ] Handle multi-word gem names (camel case for classes, handle hyphens, concurrent-ruby as example)
28
-
29
- # - [ ] Allow multiple method arguments to be passed to the command line
30
-
31
- # - [ ] Add tests for the instrumentation_generator code
32
-
33
- # - [ ] See if instrumentation PRs can get automatically generated when an already instrumented library adds methods to its codebase
@@ -1,130 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- require_relative '../../new_relic/language_support'
6
- require 'thor'
7
-
8
- class Instrumentation < Thor
9
- include Thor::Actions
10
-
11
- INSTRUMENTATION_ROOT = 'lib/new_relic/agent/instrumentation/'
12
- MULTIVERSE_SUITE_ROOT = 'test/multiverse/suites/'
13
- DEFAULT_SOURCE_LOCATION = 'lib/new_relic/agent/configuration/default_source.rb'
14
- NEWRELIC_YML_LOCATION = 'newrelic.yml'
15
-
16
- desc('scaffold NAME', 'Scaffold the required files for adding new instrumentation')
17
- long_desc <<~LONGDESC
18
- `instrumentation scaffold` requires one parameter by default: the name of the
19
- library or class you are instrumenting. This task generates the basic
20
- file structure needed to add new instrumentation to the Ruby agent.
21
- LONGDESC
22
-
23
- source_root(File.dirname(__FILE__))
24
-
25
- option :method,
26
- default: 'method_to_instrument',
27
- desc: 'The method you would like to prepend or chain instrumentation onto'
28
- option :args,
29
- default: '*args',
30
- desc: 'The arguments associated with the original method'
31
-
32
- def scaffold(name)
33
- @name = name
34
- @snake_name = snake_name(@name)
35
- @method = options[:method] if options[:method]
36
- @args = options[:args] if options[:args]
37
- @class_name = ::NewRelic::LanguageSupport.camelize(name)
38
- base_path = "#{INSTRUMENTATION_ROOT}#{@snake_name}"
39
-
40
- empty_directory(base_path)
41
- create_instrumentation_files(base_path)
42
- append_to_default_source(@name, @snake_name)
43
- # append_to_newrelic_yml(@name, @snake_name) # This is now done on release, we don't need it anymore, but leaving it to be sure.
44
- create_tests(name)
45
- end
46
-
47
- desc 'add_new_method NAME', 'Inserts a new method into an existing piece of instrumentation'
48
-
49
- option :method, required: true, desc: 'The name of the method to instrument'
50
- option :args, default: '*args', desc: 'The arguments associated with the instrumented method'
51
-
52
- def add_new_method(name, method_name)
53
- # Verify that existing instrumentation exists
54
- # if it doesn't, should we just call the #scaffold method instead since we have all the stuff
55
- # otherwise, inject the new method into the instrumentation matching the first arg
56
- # add to only chain, instrumentation, prepend
57
- # move the method content to a partial
58
- end
59
-
60
- private
61
-
62
- def create_instrumentation_files(base_path)
63
- %w[chain instrumentation prepend].each do |file|
64
- template("templates/#{file}.tt", "#{base_path}/#{file}.rb")
65
- end
66
-
67
- template('templates/dependency_detection.tt', "#{base_path}.rb")
68
- end
69
-
70
- def create_tests(name)
71
- @name = name
72
- @instrumentation_method_global_erb_snippet = '<%= $instrumentation_method %>'
73
- @snake_name = snake_name(@name)
74
- base_path = "#{MULTIVERSE_SUITE_ROOT}#{@snake_name}"
75
- empty_directory(base_path)
76
- template('templates/Envfile.tt', "#{base_path}/Envfile")
77
- template('templates/test.tt', "#{base_path}/#{@snake_name}_instrumentation_test.rb")
78
-
79
- empty_directory("#{base_path}/config")
80
- template('templates/newrelic.yml.tt', "#{base_path}/config/newrelic.yml")
81
- end
82
-
83
- def append_to_default_source(name, snake_name)
84
- insert_into_file(
85
- DEFAULT_SOURCE_LOCATION,
86
- config_block(name, snake_name),
87
- after: ":description => 'Controls auto-instrumentation of bunny at start-up. May be one of: `auto`, `prepend`, `chain`, `disabled`.'
88
- },\n"
89
- )
90
- end
91
-
92
- def append_to_newrelic_yml(name, snake_name)
93
- insert_into_file(
94
- NEWRELIC_YML_LOCATION,
95
- yaml_block(name, snake_name),
96
- after: "# instrumentation.bunny: auto\n"
97
- )
98
- end
99
-
100
- def config_block(name, snake_name)
101
- # Don't change to <<~
102
- # We want to preserve the whitespace so the config is correctly indented
103
- <<-CONFIG
104
- :'instrumentation.#{snake_name}' => {
105
- :default => 'auto',
106
- :documentation_default => 'auto',
107
- :public => true,
108
- :type => String,
109
- :dynamic_name => true,
110
- :allowed_from_server => false,
111
- :description => 'Controls auto-instrumentation of the #{name} library at start-up. May be one of `auto`, `prepend`, `chain`, `disabled`.'
112
- },
113
- CONFIG
114
- end
115
-
116
- def yaml_block(name, snake_name)
117
- <<~HEREDOC
118
-
119
- # Controls auto-instrumentation of #{name} at start-up.
120
- # May be one of [auto|prepend|chain|disabled]
121
- # instrumentation.#{snake_name}: auto
122
- HEREDOC
123
- end
124
-
125
- def snake_name(name)
126
- name.downcase.tr('-', '_')
127
- end
128
- end
129
-
130
- Instrumentation.start(ARGV)
@@ -1,9 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- instrumentation_methods :chain, :prepend
6
-
7
- gemfile <<~RB
8
- gem '<%= @name.downcase %>'
9
- RB
@@ -1,21 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- module NewRelic::Agent::Instrumentation
6
- module <%= @class_name %>::Chain
7
- def self.instrument!
8
- ::<%= @class_name %>.class_eval do
9
- include NewRelic::Agent::Instrumentation::<%= @class_name %>
10
-
11
- alias_method(:<%= @method.downcase %>_without_new_relic, :<%= @method.downcase %>)
12
-
13
- def <%= @method.downcase %><%= "(#{@args})" unless @args.empty? %>
14
- <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %> do
15
- <%= @method.downcase %>_without_new_relic<%= "(#{@args})" unless @args.empty? %>
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,7 +0,0 @@
1
- alias_method(:<%= @method.downcase %>_without_new_relic, :<%= @method.downcase %>)
2
-
3
- def <%= @method.downcase %><%= "(#{@args})" unless @args.empty? %>
4
- <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %> do
5
- <%= @method.downcase %>_without_new_relic<%= "(#{@args})" unless @args.empty? %>
6
- end
7
- end
@@ -1,32 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- DependencyDetection.defer do
6
- named :<%= @snake_name %>
7
-
8
- depends_on do
9
- # The class that needs to be defined to prepend/chain onto. This can be used
10
- # to determine whether the library is installed.
11
- defined?(<%= @class_name %>)
12
- # Add any additional requirements to verify whether this instrumentation
13
- # should be installed
14
- end
15
-
16
- executes do
17
- require_relative '<%= @snake_name.downcase %>/instrumentation'
18
-
19
- # prepend_instrument and chain_instrument call extract_supportability_name
20
- # to get the library name for supportability metrics and info-level logging.
21
- # This is done by spliting on the 2nd to last spot of the instrumented
22
- # module. If this isn't how we want the name to appear, pass in the desired
23
- # name as a third argument.
24
- if use_prepend?
25
- require_relative '<%= @snake_name.downcase %>/prepend'
26
- prepend_instrument <%= @class_name %>, NewRelic::Agent::Instrumentation::<%= @class_name %>::Prepend
27
- else
28
- require_relative '<%= @snake_name.downcase %>/chain'
29
- chain_instrument NewRelic::Agent::Instrumentation::<%= @class_name %>::Chain
30
- end
31
- end
32
- end
@@ -1,13 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- module NewRelic::Agent::Instrumentation
6
- module <%= @class_name %>
7
-
8
- def <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %>
9
- # add instrumentation content here
10
- yield
11
- end
12
- end
13
- end
@@ -1,3 +0,0 @@
1
- def <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %>
2
- # add instrumentation content here
3
- end
@@ -1,19 +0,0 @@
1
- ---
2
- development:
3
- error_collector:
4
- enabled: true
5
- apdex_t: 0.5
6
- monitor_mode: true
7
- license_key: bootstrap_newrelic_admin_license_key_000
8
- instrumentation:
9
- <%= @snake_name %>: <%= @instrumentation_method_global_erb_snippet %>
10
- app_name: test
11
- log_level: debug
12
- host: 127.0.0.1
13
- api_host: 127.0.0.1
14
- transaction_trace:
15
- record_sql: obfuscated
16
- enabled: true
17
- stack_trace_threshold: 0.5
18
- transaction_threshold: 1.0
19
- capture_params: false
@@ -1,13 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- module NewRelic::Agent::Instrumentation
6
- module <%= @class_name %>::Prepend
7
- include NewRelic::Agent::Instrumentation::<%= @class_name %>
8
-
9
- def <%= @method.downcase %><%= "(#{@args})" unless @args.empty? %>
10
- <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %> { super }
11
- end
12
- end
13
- end
@@ -1,3 +0,0 @@
1
- def <%= @method.downcase %><%= "(#{@args})" unless @args.empty? %>
2
- <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %> { super }
3
- end
@@ -1,15 +0,0 @@
1
- # This file is distributed under New Relic's license terms.
2
- # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
- # frozen_string_literal: true
4
-
5
- class <%= @class_name %>InstrumentationTest < Minitest::Test
6
- def setup
7
- @stats_engine = NewRelic::Agent.instance.stats_engine
8
- end
9
-
10
- def teardown
11
- NewRelic::Agent.instance.stats_engine.clear_stats
12
- end
13
-
14
- # Add tests here
15
- end