newrelic_rpm 10.9.0 → 10.9.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +5 -2
- data/lib/new_relic/agent/instrumentation/grpc/client/request_wrapper.rb +2 -1
- data/lib/new_relic/agent/instrumentation/grpc/server/instrumentation.rb +13 -1
- data/lib/new_relic/agent/instrumentation/parallel/chain.rb +3 -1
- data/lib/new_relic/agent/instrumentation/parallel/instrumentation.rb +6 -0
- data/lib/new_relic/agent/instrumentation/parallel/prepend.rb +3 -1
- data/lib/new_relic/agent/monitors/synthetics_monitor.rb +7 -4
- data/lib/new_relic/agent/pipe_channel_manager.rb +3 -2
- data/lib/new_relic/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 76701fc98dcc89355b941dcf726ee2864d9a2badad1519d783d22e033532aa73
|
|
4
|
+
data.tar.gz: 7bfb863d02d054cac5e396b220b0d88aed86bc386f9fab2cb7ce4901f75aa4cf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: feec753d9d9e92e15a1fe7fa6903af4742aab5714bfc30c9a1100bc4278c614d9a62b0b57119930d9015deda23780ec264f6f5e775f846ea24f6f5f741119ffd
|
|
7
|
+
data.tar.gz: 85cfbf5ae32b4778a3ce743d030ba4995b1da13e9cc8ebaa4c7fe94204be2b3a8e84055ea52b5993e0501976c1a25657fd4626c4192d5bbc794a3e2c1af2473e
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# New Relic Ruby Agent Release Notes
|
|
2
2
|
|
|
3
|
+
## v10.9.1
|
|
4
|
+
|
|
5
|
+
- **Bugfix: Action Controller instrumentation no longer errors when it can't identify the controller class**
|
|
6
|
+
|
|
7
|
+
When the agent could not identify a request's controller class, it logged `TypeError: no implicit conversion of nil into String` and then `NoMethodError: undefined method 'finish' for nil`, and recorded no data for that request. These transactions are now named `Controller/(unknown)/<action>` and recorded normally. [PR#3691](https://github.com/newrelic/newrelic-ruby-agent/pull/3691)
|
|
8
|
+
|
|
9
|
+
- **Bugfix: Prevent `Parallel` workers from hanging when reporting large payloads**
|
|
10
|
+
|
|
11
|
+
When `parallel` instrumentation was enabled, `Parallel.each`/`Parallel.map` with `in_processes:` could hang forever. Each worker inherited the pipe write ends the agent registered for its earlier siblings, so those pipes couldn't reach end-of-file, and the agent's pipe listener thread blocked waiting on one of them. Any worker whose data exceeded the operating system pipe buffer then blocked on exit. Now, the agent closes each pipe's write end in the parent right after forking, and the listener no longer blocks on a single pipe while others still have data waiting. Thank you to [@yayamochi](https://github.com/yayamochi) for reporting this bug. [Issue#3680](https://github.com/newrelic/newrelic-ruby-agent/issues/3680) [PR#3688](https://github.com/newrelic/newrelic-ruby-agent/pull/3688)
|
|
12
|
+
|
|
13
|
+
- **Bugfix: gRPC calls no longer fail on requests from Synthetics monitors**
|
|
14
|
+
|
|
15
|
+
When a request from a Synthetics monitor made a gRPC call, the agent added `X-NewRelic-Synthetics` to the call's metadata. gRPC only allows lowercase metadata keys, so the call raised `ArgumentError: 'X-NewRelic-Synthetics' is an invalid header key`. The agent now sends the synthetics headers in lowercase. gRPC server transactions also now read the synthetics headers from incoming metadata, so a gRPC service called during a Synthetics check records its trace and Synthetics attributes. [PR#3693](https://github.com/newrelic/newrelic-ruby-agent/pull/3693)
|
|
16
|
+
|
|
3
17
|
## v10.9.0
|
|
4
18
|
|
|
5
19
|
- **Feature: Continuous Profiling (preview)**
|
|
@@ -33,10 +33,10 @@ module NewRelic
|
|
|
33
33
|
&& !should_ignore(payload, controller_class(payload))
|
|
34
34
|
|
|
35
35
|
if exception = exception_object(payload)
|
|
36
|
-
finishable
|
|
36
|
+
finishable&.notice_error(exception)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
finishable
|
|
39
|
+
finishable&.finish
|
|
40
40
|
else
|
|
41
41
|
Agent.instance.pop_trace_execution_flag
|
|
42
42
|
end
|
|
@@ -75,6 +75,9 @@ module NewRelic
|
|
|
75
75
|
def format_metric_name(metric_action, controller)
|
|
76
76
|
controller_class = controller.is_a?(Class) ? controller : Object.const_get(controller)
|
|
77
77
|
"Controller/#{controller_class.controller_path}/#{metric_action}"
|
|
78
|
+
rescue StandardError => e
|
|
79
|
+
NewRelic::Agent.logger.debug("#{e.class} : #{e.message} - Error encountered trying to identify Rails controller name")
|
|
80
|
+
"Controller/#{NewRelic::Agent::UNKNOWN_METRIC}/#{metric_action}"
|
|
78
81
|
end
|
|
79
82
|
|
|
80
83
|
def controller_class(payload)
|
|
@@ -14,6 +14,9 @@ module NewRelic
|
|
|
14
14
|
INSTRUMENTATION_NAME = 'gRPC_Server'
|
|
15
15
|
|
|
16
16
|
DT_KEYS = [NewRelic::NEWRELIC_KEY, NewRelic::TRACEPARENT_KEY, NewRelic::TRACESTATE_KEY].freeze
|
|
17
|
+
SYNTHETICS_KEY = 'x-newrelic-synthetics'
|
|
18
|
+
SYNTHETICS_INFO_KEY = 'x-newrelic-synthetics-info'
|
|
19
|
+
NEWRELIC_KEYS = (DT_KEYS + [SYNTHETICS_KEY, SYNTHETICS_INFO_KEY]).freeze
|
|
17
20
|
INSTANCE_VAR_HOST = :@host_nr
|
|
18
21
|
INSTANCE_VAR_PORT = :@port_nr
|
|
19
22
|
INSTANCE_VAR_METHOD = :@method_nr
|
|
@@ -33,6 +36,7 @@ module NewRelic
|
|
|
33
36
|
trace_options)
|
|
34
37
|
add_attributes(txn, metadata, streamer_type)
|
|
35
38
|
process_distributed_tracing_headers(metadata)
|
|
39
|
+
process_synthetics_headers(metadata)
|
|
36
40
|
|
|
37
41
|
begin
|
|
38
42
|
yield
|
|
@@ -75,6 +79,14 @@ module NewRelic
|
|
|
75
79
|
::NewRelic::Agent::DistributedTracing::accept_distributed_trace_headers(metadata, 'Other')
|
|
76
80
|
end
|
|
77
81
|
|
|
82
|
+
def process_synthetics_headers(metadata)
|
|
83
|
+
return unless metadata && !metadata.empty?
|
|
84
|
+
|
|
85
|
+
::NewRelic::Agent.agent.monitors.synthetics_monitor.accept_headers(
|
|
86
|
+
metadata[SYNTHETICS_KEY], metadata[SYNTHETICS_INFO_KEY]
|
|
87
|
+
)
|
|
88
|
+
end
|
|
89
|
+
|
|
78
90
|
def host_and_port_from_host_string(host_string)
|
|
79
91
|
return unless host_string
|
|
80
92
|
|
|
@@ -101,7 +113,7 @@ module NewRelic
|
|
|
101
113
|
end
|
|
102
114
|
|
|
103
115
|
def grpc_headers(metadata)
|
|
104
|
-
metadata.reject { |k, v|
|
|
116
|
+
metadata.reject { |k, v| NEWRELIC_KEYS.include?(k) }
|
|
105
117
|
end
|
|
106
118
|
|
|
107
119
|
def grpc_params(metadata, streamer_type)
|
|
@@ -22,9 +22,11 @@ module NewRelic::Agent::Instrumentation
|
|
|
22
22
|
channel_id = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
|
|
23
23
|
NewRelic::Agent.register_report_channel(channel_id)
|
|
24
24
|
|
|
25
|
-
worker_without_newrelic(job_factory, options) do |*args|
|
|
25
|
+
worker = worker_without_newrelic(job_factory, options) do |*args|
|
|
26
26
|
worker_with_tracing(channel_id) { yield(*args) }
|
|
27
27
|
end
|
|
28
|
+
close_report_channel_write_end(channel_id)
|
|
29
|
+
worker
|
|
28
30
|
end
|
|
29
31
|
end
|
|
30
32
|
end
|
|
@@ -17,6 +17,12 @@ module NewRelic::Agent::Instrumentation
|
|
|
17
17
|
yield
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
# Runs in the parent right after the fork. Parallel forks every worker back-to-back,
|
|
21
|
+
# so waiting for the child's READY marker would let later siblings inherit this write end.
|
|
22
|
+
def close_report_channel_write_end(channel_id)
|
|
23
|
+
NewRelic::Agent::PipeChannelManager.channels[channel_id]&.after_fork_in_parent
|
|
24
|
+
end
|
|
25
|
+
|
|
20
26
|
def setup_for_txn_metric_merge_at_exit
|
|
21
27
|
# Clear out any existing transaction metrics to prevent duplicates
|
|
22
28
|
# when merging metrics back in at the end of the forked process
|
|
@@ -17,9 +17,11 @@ module NewRelic::Agent::Instrumentation
|
|
|
17
17
|
channel_id = Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
|
|
18
18
|
NewRelic::Agent.register_report_channel(channel_id)
|
|
19
19
|
|
|
20
|
-
super do |*args|
|
|
20
|
+
worker = super do |*args|
|
|
21
21
|
worker_with_tracing(channel_id) { yield(*args) }
|
|
22
22
|
end
|
|
23
|
+
close_report_channel_write_end(channel_id)
|
|
24
|
+
worker
|
|
23
25
|
end
|
|
24
26
|
end
|
|
25
27
|
end
|
|
@@ -17,9 +17,11 @@ module NewRelic
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def on_before_call(request) # THREAD_LOCAL_ACCESS
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
accept_headers(request[SYNTHETICS_HEADER_KEY], request[SYNTHETICS_INFO_HEADER_KEY])
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def accept_headers(encoded_header, info_header)
|
|
24
|
+
return unless encoded_header && (txn = Tracer.current_transaction)
|
|
23
25
|
|
|
24
26
|
incoming_payload = deserialize_header(encoded_header, SYNTHETICS_HEADER_KEY)
|
|
25
27
|
|
|
@@ -28,11 +30,12 @@ module NewRelic
|
|
|
28
30
|
SyntheticsMonitor.is_supported_version?(incoming_payload) &&
|
|
29
31
|
SyntheticsMonitor.is_trusted?(incoming_payload)
|
|
30
32
|
|
|
31
|
-
txn = Tracer.current_transaction
|
|
32
33
|
txn.raw_synthetics_header = encoded_header
|
|
33
34
|
txn.raw_synthetics_info_header = info_header
|
|
34
35
|
txn.synthetics_payload = incoming_payload
|
|
35
36
|
txn.synthetics_info_payload = load_json(info_header, SYNTHETICS_INFO_HEADER_KEY)
|
|
37
|
+
rescue => e
|
|
38
|
+
NewRelic::Agent.logger.debug('Failure accepting synthetics headers', e)
|
|
36
39
|
end
|
|
37
40
|
|
|
38
41
|
def load_json(header, key)
|
|
@@ -237,6 +237,9 @@ module NewRelic
|
|
|
237
237
|
|
|
238
238
|
def merge_data_from_pipe(pipe_handle)
|
|
239
239
|
pipe = find_pipe_for_handle(pipe_handle)
|
|
240
|
+
|
|
241
|
+
return pipe.close if pipe.eof?
|
|
242
|
+
|
|
240
243
|
raw_payload = pipe.read
|
|
241
244
|
if raw_payload && !raw_payload.empty?
|
|
242
245
|
if raw_payload == Pipe::READY_MARKER
|
|
@@ -249,8 +252,6 @@ module NewRelic
|
|
|
249
252
|
end
|
|
250
253
|
end
|
|
251
254
|
end
|
|
252
|
-
|
|
253
|
-
pipe.close if pipe.eof?
|
|
254
255
|
end
|
|
255
256
|
|
|
256
257
|
def unmarshal(data)
|
data/lib/new_relic/version.rb
CHANGED