newrelic_rpm 8.10.0 → 8.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +12 -3
- data/.rubocop_todo.yml +243 -0
- data/.simplecov +9 -2
- data/CHANGELOG.md +23 -1
- data/Thorfile +6 -0
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +8 -4
- data/lib/new_relic/agent/instrumentation/grpc/client/chain.rb +0 -8
- data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +10 -8
- data/lib/new_relic/agent/instrumentation/grpc/client/prepend.rb +0 -5
- data/lib/new_relic/agent/instrumentation/grpc/helper.rb +2 -0
- data/lib/new_relic/agent/threading/agent_thread.rb +10 -6
- data/lib/new_relic/agent/tracer.rb +5 -3
- data/lib/new_relic/control/frameworks/external.rb +0 -0
- data/lib/new_relic/control/frameworks/sinatra.rb +0 -0
- data/lib/new_relic/language_support.rb +5 -0
- data/lib/new_relic/version.rb +1 -1
- data/lib/tasks/coverage_report.rake +21 -11
- data/lib/tasks/instrumentation_generator/README.md +63 -0
- data/lib/tasks/instrumentation_generator/TODO.md +33 -0
- data/lib/tasks/instrumentation_generator/instrumentation.thor +96 -0
- data/lib/tasks/instrumentation_generator/templates/Envfile.tt +10 -0
- data/lib/tasks/instrumentation_generator/templates/chain.tt +22 -0
- data/lib/tasks/instrumentation_generator/templates/chain_method.tt +7 -0
- data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +30 -0
- data/lib/tasks/instrumentation_generator/templates/instrumentation.tt +13 -0
- data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +3 -0
- data/lib/tasks/instrumentation_generator/templates/newrelic.yml.tt +19 -0
- data/lib/tasks/instrumentation_generator/templates/prepend.tt +14 -0
- data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +3 -0
- data/lib/tasks/instrumentation_generator/templates/test.tt +16 -0
- data/newrelic_rpm.gemspec +13 -17
- data/test/agent_helper.rb +5 -19
- metadata +41 -98
- data/bin/mongrel_rpm +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5293c4968708ee7ff95720c57446722d8649e7095fd44f03b88f562d156b7cbf
|
4
|
+
data.tar.gz: df7b918b393af7aa8852bbb2867e0f7468a0ce7e78316f3a0cb8e0cedeb2aaeb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 863115396ffd0b911d11da3d0ccbe8a4e7bc98f6d406080261c4a41272a78139406146524e0f3f121ae0f729635235b40c8666caf8b70b9e20182d82b178789c
|
7
|
+
data.tar.gz: 24f7b15184ec2fd778712a215e4f6fc7d029c37b3cfb3f1efe9d0d085999abe2e795b6f644c6ac420904de3a5c7759797e462c94deb73173566c536c8bf3cb54
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,5 +1,12 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
2
|
+
|
1
3
|
require:
|
4
|
+
# Default minitest configurations: https://github.com/rubocop/rubocop-minitest/blob/master/config/default.yml
|
5
|
+
- rubocop-minitest
|
6
|
+
# Default performance configurations: https://github.com/rubocop/rubocop-performance/blob/master/config/default.yml
|
2
7
|
- rubocop-performance
|
8
|
+
# Default rake configurations: https://github.com/rubocop/rubocop-rake/blob/master/config/default.yml
|
9
|
+
<%= '- rubocop-rake' if RUBY_VERSION >= '2.4.0' %>
|
3
10
|
|
4
11
|
AllCops:
|
5
12
|
TargetRubyVersion: 2.7
|
@@ -256,7 +263,9 @@ Layout/LineEndStringConcatenationIndentation:
|
|
256
263
|
Enabled: false
|
257
264
|
|
258
265
|
Layout/LineLength:
|
259
|
-
|
266
|
+
# TODO: get this down to something closer to the 80 col ideal
|
267
|
+
# we should be able to manage 120
|
268
|
+
Max: 576
|
260
269
|
|
261
270
|
Layout/MultilineArrayBraceLayout:
|
262
271
|
Enabled: true
|
@@ -1466,7 +1475,7 @@ Style/MapToHash:
|
|
1466
1475
|
|
1467
1476
|
Style/MethodCallWithArgsParentheses:
|
1468
1477
|
Enabled: true
|
1469
|
-
|
1478
|
+
AllowedMethods:
|
1470
1479
|
- puts
|
1471
1480
|
- require
|
1472
1481
|
- raise
|
@@ -1479,7 +1488,7 @@ Style/MethodCallWithArgsParentheses:
|
|
1479
1488
|
|
1480
1489
|
Style/MethodCallWithoutArgsParentheses:
|
1481
1490
|
Enabled: false
|
1482
|
-
|
1491
|
+
AllowedMethods: []
|
1483
1492
|
|
1484
1493
|
Style/MethodCalledOnDoEndBlock:
|
1485
1494
|
Enabled: false
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,243 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2022-09-09 22:01:39 UTC using RuboCop version 1.36.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 4
|
10
|
+
# This cop supports safe autocorrection (--autocorrect).
|
11
|
+
# Configuration parameters: EnforcedStyle.
|
12
|
+
# SupportedStyles: empty_lines, no_empty_lines
|
13
|
+
Layout/EmptyLinesAroundBlockBody:
|
14
|
+
Exclude:
|
15
|
+
- 'test/multiverse/suites/active_record/db/schema.rb'
|
16
|
+
- 'test/multiverse/suites/active_record_pg/db/schema.rb'
|
17
|
+
|
18
|
+
# Offense count: 52
|
19
|
+
# This cop supports safe autocorrection (--autocorrect).
|
20
|
+
Minitest/AssertEmptyLiteral:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
# Offense count: 13
|
24
|
+
# This cop supports safe autocorrection (--autocorrect).
|
25
|
+
Minitest/AssertEqual:
|
26
|
+
Exclude:
|
27
|
+
- 'test/multiverse/suites/config_file_loading/config_file_loading_test.rb'
|
28
|
+
- 'test/new_relic/agent/configuration/default_source_test.rb'
|
29
|
+
- 'test/new_relic/agent/error_trace_aggregator_test.rb'
|
30
|
+
- 'test/new_relic/agent/method_tracer_helpers_test.rb'
|
31
|
+
- 'test/new_relic/agent/method_tracer_test.rb'
|
32
|
+
- 'test/new_relic/agent/transaction_sampler_test.rb'
|
33
|
+
- 'test/new_relic/metric_data_test.rb'
|
34
|
+
|
35
|
+
# Offense count: 145
|
36
|
+
# This cop supports safe autocorrection (--autocorrect).
|
37
|
+
Minitest/AssertInDelta:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
# Offense count: 22
|
41
|
+
# This cop supports safe autocorrection (--autocorrect).
|
42
|
+
Minitest/AssertIncludes:
|
43
|
+
Exclude:
|
44
|
+
- 'test/agent_helper.rb'
|
45
|
+
- 'test/multiverse/suites/rails/active_support_logger_test.rb'
|
46
|
+
- 'test/multiverse/suites/sequel/sequel_plugin_test.rb'
|
47
|
+
- 'test/multiverse/suites/sinatra_agent_disabled/shim_test.rb'
|
48
|
+
- 'test/new_relic/agent/audit_logger_test.rb'
|
49
|
+
- 'test/new_relic/agent/configuration/manager_test.rb'
|
50
|
+
- 'test/new_relic/agent/configuration/orphan_configuration_test.rb'
|
51
|
+
- 'test/new_relic/agent/error_trace_aggregator_test.rb'
|
52
|
+
- 'test/new_relic/agent/javascript_instrumentor_test.rb'
|
53
|
+
- 'test/new_relic/agent/method_visibility_test.rb'
|
54
|
+
- 'test/new_relic/agent/sampler_test.rb'
|
55
|
+
- 'test/new_relic/agent/tracer_state_test.rb'
|
56
|
+
- 'test/new_relic/control/instance_methods_test.rb'
|
57
|
+
- 'test/new_relic/environment_report_test.rb'
|
58
|
+
- 'test/new_relic/metric_data_test.rb'
|
59
|
+
|
60
|
+
# Offense count: 4
|
61
|
+
# This cop supports safe autocorrection (--autocorrect).
|
62
|
+
Minitest/AssertKindOf:
|
63
|
+
Exclude:
|
64
|
+
- 'test/new_relic/agent/agent_test.rb'
|
65
|
+
- 'test/new_relic/agent/pipe_channel_manager_test.rb'
|
66
|
+
- 'test/new_relic/agent_test.rb'
|
67
|
+
|
68
|
+
# Offense count: 4
|
69
|
+
# This cop supports safe autocorrection (--autocorrect).
|
70
|
+
Minitest/AssertNil:
|
71
|
+
Exclude:
|
72
|
+
- 'test/multiverse/suites/agent_only/log_events_test.rb'
|
73
|
+
|
74
|
+
# Offense count: 5
|
75
|
+
# This cop supports safe autocorrection (--autocorrect).
|
76
|
+
Minitest/AssertPathExists:
|
77
|
+
Exclude:
|
78
|
+
- 'infinite_tracing/test/support/fixtures.rb'
|
79
|
+
- 'test/multiverse/suites/mongo/helpers/mongo_server_test.rb'
|
80
|
+
|
81
|
+
# Offense count: 140
|
82
|
+
# This cop supports safe autocorrection (--autocorrect).
|
83
|
+
Minitest/AssertPredicate:
|
84
|
+
Enabled: false
|
85
|
+
|
86
|
+
# Offense count: 6
|
87
|
+
Minitest/AssertRaisesCompoundBody:
|
88
|
+
Exclude:
|
89
|
+
- 'test/new_relic/agent/collector_response_code_test.rb'
|
90
|
+
- 'test/new_relic/agent/new_relic_service_test.rb'
|
91
|
+
- 'test/new_relic/cli/commands/deployments_test.rb'
|
92
|
+
|
93
|
+
# Offense count: 9
|
94
|
+
# This cop supports safe autocorrection (--autocorrect).
|
95
|
+
Minitest/AssertRespondTo:
|
96
|
+
Exclude:
|
97
|
+
- 'test/multiverse/suites/sequel/sequel_plugin_test.rb'
|
98
|
+
- 'test/multiverse/suites/sinatra_agent_disabled/shim_test.rb'
|
99
|
+
- 'test/new_relic/agent/configuration/default_source_test.rb'
|
100
|
+
- 'test/new_relic/collection_helper_test.rb'
|
101
|
+
- 'test/new_relic/data_container_tests.rb'
|
102
|
+
|
103
|
+
# Offense count: 35
|
104
|
+
# This cop supports safe autocorrection (--autocorrect).
|
105
|
+
Minitest/AssertTruthy:
|
106
|
+
Exclude:
|
107
|
+
- 'test/multiverse/suites/agent_only/error_events_test.rb'
|
108
|
+
- 'test/multiverse/suites/rack/puma_rack_urlmap_test.rb'
|
109
|
+
- 'test/multiverse/suites/sequel/sequel_safety_test.rb'
|
110
|
+
- 'test/new_relic/agent/commands/thread_profiler_session_test.rb'
|
111
|
+
- 'test/new_relic/agent/configuration/environment_source_test.rb'
|
112
|
+
- 'test/new_relic/agent/configuration/manager_test.rb'
|
113
|
+
- 'test/new_relic/agent/configuration/security_policy_source_test.rb'
|
114
|
+
- 'test/new_relic/agent/configuration/yaml_source_test.rb'
|
115
|
+
- 'test/new_relic/agent/distributed_tracing/distributed_trace_payload_test.rb'
|
116
|
+
- 'test/new_relic/agent/distributed_tracing/trace_context_payload_test.rb'
|
117
|
+
- 'test/new_relic/agent/priority_sampled_buffer_test.rb'
|
118
|
+
- 'test/new_relic/agent/transaction/distributed_tracing_test.rb'
|
119
|
+
- 'test/new_relic/agent_test.rb'
|
120
|
+
- 'test/new_relic/gem_notifications_tests.rb'
|
121
|
+
- 'test/new_relic/language_support_test.rb'
|
122
|
+
|
123
|
+
# Offense count: 27
|
124
|
+
Minitest/AssertWithExpectedArgument:
|
125
|
+
Exclude:
|
126
|
+
- 'infinite_tracing/test/infinite_tracing/worker_test.rb'
|
127
|
+
- 'test/agent_helper.rb'
|
128
|
+
- 'test/multiverse/suites/grpc/grpc_client_test.rb'
|
129
|
+
- 'test/multiverse/suites/rails/error_tracing_test.rb'
|
130
|
+
- 'test/multiverse/suites/sidekiq/sidekiq_instrumentation_test.rb'
|
131
|
+
- 'test/new_relic/agent/agent_test.rb'
|
132
|
+
- 'test/new_relic/agent/configuration/default_source_test.rb'
|
133
|
+
- 'test/new_relic/agent/configuration/orphan_configuration_test.rb'
|
134
|
+
- 'test/new_relic/agent/datastores/redis_test.rb'
|
135
|
+
- 'test/new_relic/agent/distributed_tracing/distributed_tracing_cross_agent_test.rb'
|
136
|
+
- 'test/new_relic/agent/method_tracer_helpers_test.rb'
|
137
|
+
- 'test/new_relic/control_test.rb'
|
138
|
+
|
139
|
+
# Offense count: 4
|
140
|
+
Minitest/DuplicateTestRun:
|
141
|
+
Exclude:
|
142
|
+
- 'test/multiverse/suites/rails/error_tracing_test.rb'
|
143
|
+
- 'test/multiverse/suites/sinatra/ignoring_test.rb'
|
144
|
+
|
145
|
+
# Offense count: 38
|
146
|
+
# This cop supports safe autocorrection (--autocorrect).
|
147
|
+
Minitest/LiteralAsActualArgument:
|
148
|
+
Exclude:
|
149
|
+
- 'test/multiverse/suites/rails/active_support_logger_test.rb'
|
150
|
+
- 'test/new_relic/agent/configuration/environment_source_test.rb'
|
151
|
+
- 'test/new_relic/agent/connect/request_builder_test.rb'
|
152
|
+
- 'test/new_relic/agent/error_trace_aggregator_test.rb'
|
153
|
+
- 'test/new_relic/agent/instrumentation/controller_instrumentation_test.rb'
|
154
|
+
- 'test/new_relic/agent/new_relic_service_test.rb'
|
155
|
+
- 'test/new_relic/agent/samplers/cpu_sampler_test.rb'
|
156
|
+
- 'test/new_relic/agent/samplers/memory_sampler_test.rb'
|
157
|
+
- 'test/new_relic/agent/stats_test.rb'
|
158
|
+
- 'test/new_relic/agent/transaction/abstract_segment_test.rb'
|
159
|
+
- 'test/new_relic/agent/transaction/datastore_segment_test.rb'
|
160
|
+
- 'test/new_relic/agent/transaction_sampler_test.rb'
|
161
|
+
- 'test/new_relic/gem_notifications_tests.rb'
|
162
|
+
- 'test/new_relic/marshalling_test_cases.rb'
|
163
|
+
- 'test/new_relic/noticed_error_test.rb'
|
164
|
+
|
165
|
+
# Offense count: 260
|
166
|
+
Minitest/MultipleAssertions:
|
167
|
+
Max: 28
|
168
|
+
|
169
|
+
# Offense count: 9
|
170
|
+
# This cop supports safe autocorrection (--autocorrect).
|
171
|
+
Minitest/RefuteEqual:
|
172
|
+
Exclude:
|
173
|
+
- 'test/agent_helper.rb'
|
174
|
+
- 'test/multiverse/suites/config_file_loading/config_file_loading_test.rb'
|
175
|
+
- 'test/new_relic/agent/agent_test.rb'
|
176
|
+
- 'test/new_relic/agent/configuration/manager_test.rb'
|
177
|
+
- 'test/new_relic/marshalling_test_cases.rb'
|
178
|
+
|
179
|
+
# Offense count: 121
|
180
|
+
# This cop supports safe autocorrection (--autocorrect).
|
181
|
+
Minitest/RefuteFalse:
|
182
|
+
Enabled: false
|
183
|
+
|
184
|
+
# Offense count: 16
|
185
|
+
# This cop supports safe autocorrection (--autocorrect).
|
186
|
+
Minitest/RefuteIncludes:
|
187
|
+
Exclude:
|
188
|
+
- 'test/multiverse/suites/datamapper/datamapper_test.rb'
|
189
|
+
- 'test/multiverse/suites/grpc/grpc_server_test.rb'
|
190
|
+
- 'test/multiverse/suites/mongo/helpers/mongo_operation_tests.rb'
|
191
|
+
- 'test/multiverse/suites/mongo/mongo2_instrumentation_test.rb'
|
192
|
+
- 'test/multiverse/suites/rack/rack_cascade_test.rb'
|
193
|
+
- 'test/new_relic/agent/configuration/manager_test.rb'
|
194
|
+
- 'test/new_relic/control/instance_methods_test.rb'
|
195
|
+
|
196
|
+
# Offense count: 3
|
197
|
+
# This cop supports safe autocorrection (--autocorrect).
|
198
|
+
Minitest/RefutePathExists:
|
199
|
+
Exclude:
|
200
|
+
- 'test/multiverse/suites/mongo/helpers/mongo_server_test.rb'
|
201
|
+
|
202
|
+
# Offense count: 96
|
203
|
+
# This cop supports safe autocorrection (--autocorrect).
|
204
|
+
Minitest/RefutePredicate:
|
205
|
+
Enabled: false
|
206
|
+
|
207
|
+
# Offense count: 27
|
208
|
+
# This cop supports safe autocorrection (--autocorrect).
|
209
|
+
Minitest/TestMethodName:
|
210
|
+
Enabled: false
|
211
|
+
|
212
|
+
# Offense count: 2
|
213
|
+
# This cop supports safe autocorrection (--autocorrect).
|
214
|
+
Rake/Desc:
|
215
|
+
Exclude:
|
216
|
+
- 'Rakefile'
|
217
|
+
- 'lib/tasks/config.rake'
|
218
|
+
|
219
|
+
# Offense count: 15
|
220
|
+
Rake/MethodDefinitionInTask:
|
221
|
+
Exclude:
|
222
|
+
- 'Rakefile'
|
223
|
+
- 'infinite_tracing/tasks/proto.rake'
|
224
|
+
- 'lib/tasks/config.rake'
|
225
|
+
- 'lib/tasks/tests.rake'
|
226
|
+
|
227
|
+
# Offense count: 2
|
228
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
229
|
+
# Configuration parameters: EnforcedStyle.
|
230
|
+
# SupportedStyles: always, always_true, never
|
231
|
+
Style/FrozenStringLiteralComment:
|
232
|
+
Exclude:
|
233
|
+
- 'test/multiverse/suites/active_record/db/schema.rb'
|
234
|
+
- 'test/multiverse/suites/active_record_pg/db/schema.rb'
|
235
|
+
|
236
|
+
# Offense count: 26
|
237
|
+
# This cop supports safe autocorrection (--autocorrect).
|
238
|
+
# Configuration parameters: IgnoreMacros, AllowedMethods, IgnoredMethods, AllowedPatterns, IgnoredPatterns, IncludedMacros, AllowParenthesesInMultilineCall, AllowParenthesesInChaining, AllowParenthesesInCamelCaseMethod, AllowParenthesesInStringInterpolation, EnforcedStyle.
|
239
|
+
# SupportedStyles: require_parentheses, omit_parentheses
|
240
|
+
Style/MethodCallWithArgsParentheses:
|
241
|
+
Exclude:
|
242
|
+
- 'test/multiverse/suites/active_record/db/schema.rb'
|
243
|
+
- 'test/multiverse/suites/active_record_pg/db/schema.rb'
|
data/.simplecov
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
random = SecureRandom.uuid
|
5
|
+
SimpleCov.command_name(random)
|
6
|
+
SimpleCov.coverage_dir("coverage_#{random}")
|
7
|
+
|
2
8
|
SimpleCov.start do
|
3
|
-
enable_coverage
|
9
|
+
enable_coverage(:branch)
|
4
10
|
SimpleCov.root(File.join(File.dirname(__FILE__), '/lib'))
|
5
|
-
track_files
|
11
|
+
track_files("**/*.rb")
|
12
|
+
formatter(SimpleCov::Formatter::SimpleFormatter)
|
6
13
|
end
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,23 @@
|
|
1
1
|
# New Relic Ruby Agent Release Notes #
|
2
2
|
|
3
3
|
|
4
|
+
## v8.10.1
|
5
|
+
|
6
|
+
|
7
|
+
* **Bugfix: Missing unscoped metrics when instrumentation.thread.tracing is enabled**
|
8
|
+
|
9
|
+
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.
|
10
|
+
|
11
|
+
Thank you to @texpert for providing details of their situation to help resolve the issue.
|
12
|
+
|
13
|
+
|
14
|
+
* **Bugfix: gRPC instrumentation causes ArgumentError when other Google gems are present**
|
15
|
+
|
16
|
+
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.
|
17
|
+
|
18
|
+
Thank you to @FeminismIsAwesome for bringing this issue to our attention.
|
19
|
+
|
20
|
+
|
4
21
|
## v8.10.0
|
5
22
|
|
6
23
|
|
@@ -17,12 +34,17 @@
|
|
17
34
|
| `instrumentation.grpc.host_denylist` | "" | Provide a comma delimited list of host regex patterns (ex: "private.com$,exception.*") |
|
18
35
|
|
19
36
|
|
37
|
+
* **Code-level metrics functionality is enabled by default**
|
38
|
+
|
39
|
+
The code-level metrics functionality for the Ruby agent's [CodeStream integration](https://docs.newrelic.com/docs/apm/agents/ruby-agent/features/ruby-codestream-integration) is now enabled by default after we have received positive feedback and no open bugs for the past two releases.
|
40
|
+
|
41
|
+
|
20
42
|
* **Performance: Rework timing range overlap calculations for multiple transaction segments**
|
21
43
|
|
22
44
|
Many thanks to GitHub community members @bmulholland and @hkdnet. @bmulholland alerted us to [rmosolgo/graphql-ruby#3945](https://github.com/rmosolgo/graphql-ruby/issues/3945). That Issue essentially notes that the New Relic Ruby agent incurs a significant perfomance hit when the `graphql` RubyGem (which ships with New Relic Ruby agent support) is used with DataLoader to generate a high number of transactions. Then @hkdnet diagnosed the root cause in the Ruby agent and put together both a proof of concept fix and a full blown PR to resolve the problem. The agent keeps track multiple segments that are concurrently in play for a given transaction in order to merge the ones whose start and stop times intersect. The logic for doing this find-and-merge operation has been reworked to a) be deferred entirely until the transaction is ready to be recorded, and b) made more performant when it is needed. GraphQL DataLoader users and other users who generate lots of activity for monitoring within a short amount of time will hopefully see some good performance gains from these changes.
|
23
45
|
|
24
46
|
|
25
|
-
* **Performance: Make frozen string literals the default for the agent
|
47
|
+
* **Performance: Make frozen string literals the default for the agent**
|
26
48
|
|
27
49
|
The Ruby `frozen_string_literal: true` magic source code comment has now been applied consistently across all Ruby files belonging to the agent. This can provide a performance boost, given that Ruby can rely on the strings remaining immutable. Previously only about a third of the agent's code was freezing string literals by default. Now that 100% of the code freezes string literals by default, we have internally observed some related performance gains through testing. We are hopeful that these will translate into some real world gains in production capacities.
|
28
50
|
|
data/Thorfile
ADDED
@@ -12,13 +12,10 @@ module NewRelic
|
|
12
12
|
module Instrumentation
|
13
13
|
class ActionControllerSubscriber < NotificationsSubscriber
|
14
14
|
def start(name, id, payload) # THREAD_LOCAL_ACCESS
|
15
|
-
# @req is a historically stable but not guaranteed Rails header property
|
16
|
-
request = payload[:headers].instance_variable_get(:@req)
|
17
|
-
|
18
15
|
controller_class = controller_class(payload)
|
19
16
|
|
20
17
|
if state.is_execution_traced? && !should_ignore(payload, controller_class)
|
21
|
-
finishable = start_transaction_or_segment(payload,
|
18
|
+
finishable = start_transaction_or_segment(payload, request_for_payload(payload), controller_class)
|
22
19
|
push_segment(id, finishable)
|
23
20
|
else
|
24
21
|
# if this transaction is ignored, make sure child
|
@@ -98,6 +95,13 @@ module NewRelic
|
|
98
95
|
QueueTime.parse_frontend_timestamp(request.env, Process.clock_gettime(Process::CLOCK_REALTIME))
|
99
96
|
end
|
100
97
|
end
|
98
|
+
|
99
|
+
def request_for_payload(payload)
|
100
|
+
# @req is a historically stable but not guaranteed Rails header property
|
101
|
+
return unless payload[:headers].instance_variables.include?(:@req)
|
102
|
+
|
103
|
+
payload[:headers].instance_variable_get(:@req)
|
104
|
+
end
|
101
105
|
end
|
102
106
|
end
|
103
107
|
end
|
@@ -13,14 +13,6 @@ module NewRelic::Agent::Instrumentation
|
|
13
13
|
::GRPC::ClientStub.class_eval do
|
14
14
|
include NewRelic::Agent::Instrumentation::GRPC::Client
|
15
15
|
|
16
|
-
def initialize_with_newrelic_trace(*args)
|
17
|
-
@trace_with_newrelic = trace_with_newrelic?(args.first)
|
18
|
-
initialize_without_newrelic_trace(*args)
|
19
|
-
end
|
20
|
-
|
21
|
-
alias initialize_without_newrelic_trace initialize
|
22
|
-
alias initialize initialize_with_newrelic_trace
|
23
|
-
|
24
16
|
def bidi_streamer_with_new_relic_trace(method, requests, marshal, unmarshal,
|
25
17
|
deadline: nil,
|
26
18
|
return_op: false,
|
@@ -70,16 +70,18 @@ module NewRelic
|
|
70
70
|
"grpc://#{@host}/#{method}"
|
71
71
|
end
|
72
72
|
|
73
|
-
def
|
74
|
-
|
75
|
-
|
76
|
-
do_trace = instance_variable_get(:@trace_with_newrelic)
|
77
|
-
return do_trace unless do_trace.nil? # check for nil, not falsey
|
73
|
+
def interceptor?
|
74
|
+
self.class.name.eql?('GRPC::InterceptorRegistry')
|
75
|
+
end
|
78
76
|
|
79
|
-
|
80
|
-
return
|
77
|
+
def trace_with_newrelic?
|
78
|
+
return @trace_with_newrelic unless @trace_with_newrelic.nil? # check for nil, not false
|
81
79
|
|
82
|
-
|
80
|
+
@trace_with_newrelic = if interceptor?
|
81
|
+
false
|
82
|
+
else
|
83
|
+
!host_denylisted?(@host)
|
84
|
+
end
|
83
85
|
end
|
84
86
|
end
|
85
87
|
end
|
@@ -13,11 +13,6 @@ module NewRelic
|
|
13
13
|
module Prepend
|
14
14
|
include NewRelic::Agent::Instrumentation::GRPC::Client
|
15
15
|
|
16
|
-
def initialize(*args)
|
17
|
-
@trace_with_newrelic = trace_with_newrelic?(args.first)
|
18
|
-
super(*args)
|
19
|
-
end
|
20
|
-
|
21
16
|
def bidi_streamer(method, requests, marshal, unmarshal,
|
22
17
|
deadline: nil,
|
23
18
|
return_op: false,
|
@@ -8,21 +8,25 @@ module NewRelic
|
|
8
8
|
module Threading
|
9
9
|
class AgentThread
|
10
10
|
def self.create(label, &blk)
|
11
|
-
::NewRelic::Agent.logger.debug("Creating
|
11
|
+
::NewRelic::Agent.logger.debug("Creating AgentThread: #{label}")
|
12
12
|
wrapped_blk = Proc.new do
|
13
|
+
if ::Thread.current[:newrelic_tracer_state] && Thread.current[:newrelic_tracer_state].current_transaction
|
14
|
+
txn = ::Thread.current[:newrelic_tracer_state].current_transaction
|
15
|
+
::NewRelic::Agent.logger.warn("AgentThread created with current transaction #{txn.best_name}")
|
16
|
+
end
|
13
17
|
begin
|
14
18
|
blk.call
|
15
19
|
rescue => e
|
16
|
-
::NewRelic::Agent.logger.error("
|
20
|
+
::NewRelic::Agent.logger.error("AgentThread #{label} exited with error", e)
|
17
21
|
rescue Exception => e
|
18
|
-
::NewRelic::Agent.logger.error("
|
22
|
+
::NewRelic::Agent.logger.error("AgentThread #{label} exited with exception. Re-raising in case of interrupt.", e)
|
19
23
|
raise
|
20
24
|
ensure
|
21
|
-
::NewRelic::Agent.logger.debug("Exiting
|
25
|
+
::NewRelic::Agent.logger.debug("Exiting AgentThread: #{label}")
|
22
26
|
end
|
23
27
|
end
|
24
|
-
|
25
|
-
thread = backing_thread_class.new(&wrapped_blk)
|
28
|
+
thread = nil
|
29
|
+
NewRelic::Agent.disable_all_tracing { thread = backing_thread_class.new(&wrapped_blk) }
|
26
30
|
thread[:newrelic_label] = label
|
27
31
|
thread
|
28
32
|
end
|
@@ -407,11 +407,13 @@ module NewRelic
|
|
407
407
|
alias_method :tl_clear, :clear_state
|
408
408
|
|
409
409
|
def thread_block_with_current_transaction(*args, &block)
|
410
|
-
current_txn = ::Thread.current[:newrelic_tracer_state].current_transaction if ::Thread.current[:newrelic_tracer_state]
|
410
|
+
current_txn = ::Thread.current[:newrelic_tracer_state].current_transaction if ::Thread.current[:newrelic_tracer_state] && ::Thread.current[:newrelic_tracer_state].is_execution_traced?
|
411
411
|
Proc.new do
|
412
412
|
begin
|
413
|
-
|
414
|
-
|
413
|
+
if current_txn
|
414
|
+
NewRelic::Agent::Tracer.state.current_transaction = current_txn
|
415
|
+
segment = NewRelic::Agent::Tracer.start_segment(name: "Ruby/Thread/#{::Thread.current.object_id}")
|
416
|
+
end
|
415
417
|
block.call(*args) if block.respond_to?(:call)
|
416
418
|
ensure
|
417
419
|
segment.finish if segment
|
File without changes
|
File without changes
|
@@ -73,6 +73,11 @@ module NewRelic
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
+
def camelize(string)
|
77
|
+
camelized = string.downcase
|
78
|
+
camelized.split(/\-|\_/).map(&:capitalize).join
|
79
|
+
end
|
80
|
+
|
76
81
|
def bundled_gem?(gem_name)
|
77
82
|
defined?(Bundler) && Bundler.rubygems.all_specs.map(&:name).include?(gem_name)
|
78
83
|
rescue => e
|
data/lib/new_relic/version.rb
CHANGED
@@ -7,17 +7,27 @@ namespace :coverage do
|
|
7
7
|
desc "Collates all result sets generated by the different test runners"
|
8
8
|
task :report do
|
9
9
|
require 'simplecov'
|
10
|
-
require '
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
require 'fileutils'
|
11
|
+
|
12
|
+
SimpleCov.coverage_dir('coverage_results')
|
13
|
+
|
14
|
+
if ENV['CI']
|
15
|
+
SimpleCov.collate(Dir['*/coverage_*/.resultset.json']) do
|
16
|
+
formatter SimpleCov::Formatter::HTMLFormatter
|
17
|
+
refuse_coverage_drop
|
18
|
+
end
|
19
|
+
else
|
20
|
+
SimpleCov.collate(Dir['lib/coverage_*/.resultset.json']) do
|
21
|
+
formatter SimpleCov::Formatter::HTMLFormatter
|
22
|
+
end
|
21
23
|
end
|
24
|
+
|
25
|
+
Dir['lib/coverage_{[!r][!e][!s][!u][!l][!t][!s]}*'].each { |dir| FileUtils.rm_rf(dir) }
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "Removes all coverage_* directories"
|
29
|
+
task :clear do
|
30
|
+
require 'fileutils'
|
31
|
+
Dir["lib/coverage_*"].each { |dir| FileUtils.rm_rf(dir) }
|
22
32
|
end
|
23
33
|
end
|
@@ -0,0 +1,63 @@
|
|
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 paramters:
|
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 has been created that generates the required files to create new instrumentation. This prototype accepts three arguments: name (name of the library), method (method to instrument), args (arguments for the method).
|
62
|
+
|
63
|
+
The Ruby gem Thor, a toolkit for building powerful command-line interfaces used in Bundler, Vagrant, Rails and others powers this CLI.
|