newrelic_rpm 9.19.0 → 9.20.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +38 -0
- data/lib/new_relic/agent/configuration/default_source.rb +85 -85
- data/lib/new_relic/agent/configuration/manager.rb +5 -2
- data/lib/new_relic/agent/configuration/yaml_source.rb +2 -2
- data/lib/new_relic/agent/database.rb +1 -1
- data/lib/new_relic/agent/database_adapter.rb +1 -1
- data/lib/new_relic/agent/datastores/redis.rb +1 -1
- data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +1 -1
- data/lib/new_relic/agent/distributed_tracing.rb +2 -0
- data/lib/new_relic/agent/external.rb +2 -0
- data/lib/new_relic/agent/instrumentation/action_dispatch.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_mailbox.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_mailer.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_job.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_record.rb +6 -4
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +2 -2
- data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +11 -9
- data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +2 -2
- data/lib/new_relic/agent/instrumentation/async_http.rb +1 -1
- data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +1 -1
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/curb.rb +1 -1
- data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +1 -2
- data/lib/new_relic/agent/instrumentation/elasticsearch.rb +1 -1
- data/lib/new_relic/agent/instrumentation/ethon.rb +1 -1
- data/lib/new_relic/agent/instrumentation/excon.rb +1 -1
- data/lib/new_relic/agent/instrumentation/fiber/chain.rb +1 -1
- data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +1 -1
- data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -4
- data/lib/new_relic/agent/instrumentation/httpx/instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/httpx.rb +1 -1
- data/lib/new_relic/agent/instrumentation/logstasher.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache/helper.rb +2 -2
- data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +1 -1
- data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/net_http.rb +2 -1
- data/lib/new_relic/agent/instrumentation/rake.rb +1 -1
- data/lib/new_relic/agent/instrumentation/rdkafka/chain.rb +2 -2
- data/lib/new_relic/agent/instrumentation/rdkafka/prepend.rb +2 -2
- data/lib/new_relic/agent/instrumentation/redis/constants.rb +2 -2
- data/lib/new_relic/agent/instrumentation/resque.rb +2 -2
- data/lib/new_relic/agent/instrumentation/roda.rb +1 -1
- data/lib/new_relic/agent/instrumentation/ruby_kafka/prepend.rb +1 -1
- data/lib/new_relic/agent/instrumentation/ruby_openai.rb +2 -2
- data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +1 -1
- data/lib/new_relic/agent/instrumentation/stripe.rb +1 -1
- data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +2 -2
- data/lib/new_relic/agent/llm/chat_completion_summary.rb +1 -1
- data/lib/new_relic/agent/llm/embedding.rb +1 -1
- data/lib/new_relic/agent/local_log_decorator.rb +1 -1
- data/lib/new_relic/agent/logging.rb +1 -1
- data/lib/new_relic/agent/messaging.rb +5 -0
- data/lib/new_relic/agent/method_tracer.rb +3 -0
- data/lib/new_relic/agent/monitors/inbound_request_monitor.rb +1 -1
- data/lib/new_relic/agent/monitors/synthetics_monitor.rb +1 -1
- data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +2 -2
- data/lib/new_relic/agent/opentelemetry/context/propagation/trace_propagator.rb +66 -0
- data/lib/new_relic/agent/opentelemetry/context/propagation.rb +15 -0
- data/lib/new_relic/agent/opentelemetry/context.rb +13 -0
- data/lib/new_relic/agent/opentelemetry/trace/span.rb +15 -7
- data/lib/new_relic/agent/opentelemetry/trace/tracer.rb +106 -15
- data/lib/new_relic/agent/opentelemetry/transaction_patch.rb +69 -0
- data/lib/new_relic/agent/opentelemetry_bridge.rb +7 -1
- data/lib/new_relic/agent/parameter_filtering.rb +1 -1
- data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -1
- data/lib/new_relic/agent/samplers/memory_sampler.rb +1 -1
- data/lib/new_relic/agent/span_event_primitive.rb +5 -0
- data/lib/new_relic/agent/tracer.rb +1 -1
- data/lib/new_relic/agent/transaction/datastore_segment.rb +1 -1
- data/lib/new_relic/agent/transaction/distributed_tracer.rb +3 -3
- data/lib/new_relic/agent/transaction/message_broker_segment.rb +1 -1
- data/lib/new_relic/agent/transaction/trace_context.rb +4 -4
- data/lib/new_relic/agent/transaction_time_aggregator.rb +1 -1
- data/lib/new_relic/agent/utilization/ecs.rb +22 -0
- data/lib/new_relic/agent/utilization/ecs_v4.rb +22 -0
- data/lib/new_relic/agent/utilization_data.rb +25 -0
- data/lib/new_relic/agent/vm/c_ruby_vm.rb +3 -3
- data/lib/new_relic/agent.rb +28 -0
- data/lib/new_relic/constants.rb +1 -0
- data/lib/new_relic/control/instrumentation.rb +1 -1
- data/lib/new_relic/dependency_detection.rb +0 -1
- data/lib/new_relic/helper.rb +7 -0
- data/lib/new_relic/version.rb +1 -1
- data/lib/sequel/extensions/new_relic_instrumentation.rb +1 -1
- data/lib/tasks/helpers/newrelicyml.rb +2 -0
- data/newrelic.yml +14 -14
- data/newrelic_rpm.gemspec +1 -1
- metadata +11 -6
@@ -0,0 +1,15 @@
|
|
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 OpenTelemetry
|
8
|
+
module Context
|
9
|
+
module Propagation
|
10
|
+
require_relative 'propagation/trace_propagator'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
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 OpenTelemetry
|
8
|
+
module Context
|
9
|
+
require_relative 'context/propagation'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -7,14 +7,22 @@ module NewRelic
|
|
7
7
|
module OpenTelemetry
|
8
8
|
module Trace
|
9
9
|
class Span < ::OpenTelemetry::Trace::Span
|
10
|
-
|
10
|
+
attr_accessor :finishable
|
11
11
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
)
|
12
|
+
def finish(end_timestamp: nil)
|
13
|
+
finishable&.finish
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_attribute(key, value)
|
17
|
+
NewRelic::Agent.add_custom_span_attributes(key => value)
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_attributes(attributes)
|
21
|
+
NewRelic::Agent.add_custom_span_attributes(attributes)
|
22
|
+
end
|
23
|
+
|
24
|
+
def record_exception(exception, attributes: nil)
|
25
|
+
NewRelic::Agent.notice_error(exception, attributes: attributes)
|
18
26
|
end
|
19
27
|
end
|
20
28
|
end
|
@@ -12,25 +12,116 @@ module NewRelic
|
|
12
12
|
@version = version || ''
|
13
13
|
end
|
14
14
|
|
15
|
+
def start_span(name, with_parent: nil, attributes: nil, links: nil, start_timestamp: nil, kind: nil)
|
16
|
+
parent_otel_context = ::OpenTelemetry::Trace.current_span(with_parent).context
|
17
|
+
|
18
|
+
finishable = if can_start_transaction?(parent_otel_context)
|
19
|
+
return if internal_span_kind_with_invalid_parent?(kind, parent_otel_context)
|
20
|
+
|
21
|
+
nr_item = NewRelic::Agent::Tracer.start_transaction_or_segment(name: name, category: :otel)
|
22
|
+
add_remote_context_to_txn(nr_item, parent_otel_context)
|
23
|
+
nr_item
|
24
|
+
else
|
25
|
+
NewRelic::Agent::Tracer.start_segment(name: name)
|
26
|
+
end
|
27
|
+
|
28
|
+
otel_span = get_otel_span_from_finishable(finishable)
|
29
|
+
otel_span.finishable = finishable
|
30
|
+
add_remote_context_to_otel_span(otel_span, parent_otel_context)
|
31
|
+
otel_span.add_attributes(attributes) if attributes
|
32
|
+
otel_span
|
33
|
+
end
|
34
|
+
|
15
35
|
def in_span(name, attributes: nil, links: nil, start_timestamp: nil, kind: nil)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
36
|
+
span = start_span(name, attributes: attributes, links: links, start_timestamp: start_timestamp, kind: kind)
|
37
|
+
begin
|
38
|
+
yield
|
39
|
+
rescue => e
|
40
|
+
# TODO: Update for segment errors if finishable is a segment
|
41
|
+
NewRelic::Agent.notice_error(e)
|
42
|
+
raise
|
43
|
+
end
|
44
|
+
ensure
|
45
|
+
span&.finish
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def get_otel_span_from_finishable(finishable)
|
51
|
+
case finishable
|
52
|
+
when NewRelic::Agent::Transaction
|
53
|
+
finishable.segments.first.instance_variable_get(:@otel_span)
|
54
|
+
when NewRelic::Agent::Transaction::Segment
|
55
|
+
finishable.instance_variable_get(:@otel_span)
|
30
56
|
else
|
31
|
-
NewRelic::Agent.logger.
|
57
|
+
NewRelic::Agent.logger.warn('Tracer#get_otel_span_from_finishable failed to get span from finishable - finishable is not a transaction or segment')
|
58
|
+
nil
|
32
59
|
end
|
33
60
|
end
|
61
|
+
|
62
|
+
def can_start_transaction?(parent_otel_context)
|
63
|
+
parent_otel_context.remote? || !parent_otel_context.valid?
|
64
|
+
end
|
65
|
+
|
66
|
+
def internal_span_kind_with_invalid_parent?(kind, parent_otel_context)
|
67
|
+
!parent_otel_context.valid? && kind == :internal
|
68
|
+
end
|
69
|
+
|
70
|
+
def transaction_and_remote_parent?(txn, parent_otel_context)
|
71
|
+
txn.is_a?(NewRelic::Agent::Transaction) && parent_otel_context.remote?
|
72
|
+
end
|
73
|
+
|
74
|
+
def add_remote_context_to_txn(txn, parent_otel_context)
|
75
|
+
return unless transaction_and_remote_parent?(txn, parent_otel_context)
|
76
|
+
|
77
|
+
txn.trace_id = parent_otel_context.trace_id
|
78
|
+
txn.parent_span_id = parent_otel_context.span_id
|
79
|
+
|
80
|
+
set_tracestate(txn.distributed_tracer, parent_otel_context)
|
81
|
+
end
|
82
|
+
|
83
|
+
def set_tracestate(distributed_tracer, otel_context)
|
84
|
+
case otel_context.tracestate
|
85
|
+
when ::OpenTelemetry::Trace::Tracestate
|
86
|
+
set_otel_trace_state(distributed_tracer, otel_context)
|
87
|
+
when NewRelic::Agent::TraceContextPayload
|
88
|
+
set_nr_trace_state(distributed_tracer, otel_context)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def set_nr_trace_state(distributed_tracer, otel_context)
|
93
|
+
distributed_tracer.instance_variable_set(:@trace_state_payload, otel_context.tracestate)
|
94
|
+
distributed_tracer.parent_transaction_id = distributed_tracer.trace_state_payload.transaction_id
|
95
|
+
distributed_tracer.determine_sampling_decision(otel_context.tracestate, otel_context.trace_flags)
|
96
|
+
end
|
97
|
+
|
98
|
+
def set_otel_trace_state(distributed_tracer, otel_context)
|
99
|
+
nr_entry = otel_context.tracestate.value(Transaction::TraceContext::AccountHelpers.trace_state_entry_key)
|
100
|
+
return unless nr_entry
|
101
|
+
|
102
|
+
nr_payload = NewRelic::Agent::TraceContextPayload.from_s(nr_entry)
|
103
|
+
distributed_tracer.instance_variable_set(:@trace_state_payload, nr_payload)
|
104
|
+
distributed_tracer.parent_transaction_id = distributed_tracer.trace_state_payload.transaction_id
|
105
|
+
trace_flags = parse_trace_flags(otel_context.trace_flags)
|
106
|
+
distributed_tracer.determine_sampling_decision(nr_payload, trace_flags)
|
107
|
+
end
|
108
|
+
|
109
|
+
def parse_trace_flags(trace_flags)
|
110
|
+
case trace_flags
|
111
|
+
when String
|
112
|
+
trace_flags
|
113
|
+
when Integer
|
114
|
+
trace_flags.to_s
|
115
|
+
when ::OpenTelemetry::Trace::TraceFlags
|
116
|
+
trace_flags.sampled? ? '01' : '00'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def add_remote_context_to_otel_span(otel_span, parent_otel_context)
|
121
|
+
return unless transaction_and_remote_parent?(otel_span.finishable, parent_otel_context)
|
122
|
+
|
123
|
+
otel_span.context.instance_variable_set(:@trace_id, otel_span.finishable.trace_id)
|
124
|
+
end
|
34
125
|
end
|
35
126
|
end
|
36
127
|
end
|
@@ -0,0 +1,69 @@
|
|
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 OpenTelemetry
|
8
|
+
module TransactionPatch
|
9
|
+
attr_accessor :opentelemetry_context
|
10
|
+
|
11
|
+
def initialize(_category, _options)
|
12
|
+
@opentelemetry_context = {}
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_current_segment(new_segment)
|
17
|
+
@current_segment_lock.synchronize do
|
18
|
+
unless opentelemetry_context.empty?
|
19
|
+
::OpenTelemetry::Context.detach(opentelemetry_context[otel_current_span_key])
|
20
|
+
end
|
21
|
+
|
22
|
+
span = find_or_create_span(new_segment)
|
23
|
+
ctx = ::OpenTelemetry::Context.current.set_value(otel_current_span_key, span)
|
24
|
+
token = ::OpenTelemetry::Context.attach(ctx)
|
25
|
+
|
26
|
+
opentelemetry_context[otel_current_span_key] = token
|
27
|
+
end
|
28
|
+
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def remove_current_segment_by_thread_id(id)
|
33
|
+
# make sure the context is fully detached when the transaction ends
|
34
|
+
@current_segment_lock.synchronize do
|
35
|
+
::OpenTelemetry::Context.detach(opentelemetry_context[otel_current_span_key])
|
36
|
+
opentelemetry_context.delete(id)
|
37
|
+
end
|
38
|
+
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def find_or_create_span(segment)
|
45
|
+
if segment.instance_variable_defined?(:@otel_span)
|
46
|
+
segment.instance_variable_get(:@otel_span)
|
47
|
+
else
|
48
|
+
span = Trace::Span.new(span_context: span_context_from_segment(segment))
|
49
|
+
segment.instance_variable_set(:@otel_span, span)
|
50
|
+
span
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def span_context_from_segment(segment)
|
55
|
+
::OpenTelemetry::Trace::SpanContext.new(
|
56
|
+
trace_id: segment.transaction.trace_id,
|
57
|
+
span_id: segment.guid,
|
58
|
+
remote: false
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
def otel_current_span_key
|
63
|
+
# CURRENT_SPAN_KEY is a private constant
|
64
|
+
::OpenTelemetry::Trace.const_get(:CURRENT_SPAN_KEY)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -18,8 +18,14 @@ module NewRelic
|
|
18
18
|
def self.install
|
19
19
|
require 'opentelemetry' # requires the opentelemetry-api gem
|
20
20
|
require_relative 'opentelemetry/trace'
|
21
|
+
require_relative 'opentelemetry/transaction_patch'
|
22
|
+
require_relative 'opentelemetry/context'
|
21
23
|
|
22
|
-
|
24
|
+
# TODO: Add a warning if SDK gem is installed
|
25
|
+
|
26
|
+
::OpenTelemetry.tracer_provider = OpenTelemetry::Trace::TracerProvider.new
|
27
|
+
Transaction.prepend(OpenTelemetry::TransactionPatch)
|
28
|
+
::OpenTelemetry.propagation = OpenTelemetry::Context::Propagation::TracePropagator.new
|
23
29
|
end
|
24
30
|
end
|
25
31
|
end
|
@@ -9,7 +9,7 @@ module NewRelic
|
|
9
9
|
|
10
10
|
ACTION_DISPATCH_PARAMETER_FILTER ||= 'action_dispatch.parameter_filter'.freeze
|
11
11
|
|
12
|
-
if defined?(Rails) &&
|
12
|
+
if defined?(Rails) && NewRelic::Helper.version_satisfied?(::Rails::VERSION::STRING, '>=', '5.0.0')
|
13
13
|
Rails.application.config.to_prepare do
|
14
14
|
RAILS_FILTER_CLASS ||= if defined?(ActiveSupport::ParameterFilter)
|
15
15
|
ActiveSupport::ParameterFilter
|
@@ -42,7 +42,7 @@ module NewRelic
|
|
42
42
|
# Process.times on JRuby < 1.7.0 reports wall clock elapsed time,
|
43
43
|
# not actual cpu time used, so this sampler can only be used on JRuby >= 1.7.0.
|
44
44
|
if defined?(JRuby)
|
45
|
-
return JRUBY_VERSION >= '1.7.0'
|
45
|
+
return NewRelic::Helper.version_satisfied?(JRUBY_VERSION, '>=', '1.7.0')
|
46
46
|
end
|
47
47
|
|
48
48
|
true
|
@@ -40,6 +40,7 @@ module NewRelic
|
|
40
40
|
SERVER_ADDRESS_KEY = 'server.address'
|
41
41
|
SERVER_PORT_KEY = 'server.port'
|
42
42
|
SPAN_KIND_KEY = 'span.kind'
|
43
|
+
STACKTRACE_KEY = 'code.stacktrace'
|
43
44
|
ENTRY_POINT_KEY = 'nr.entryPoint'
|
44
45
|
TRUSTED_PARENT_KEY = 'trustedParentId'
|
45
46
|
TRACING_VENDORS_KEY = 'tracingVendors'
|
@@ -122,6 +123,10 @@ module NewRelic
|
|
122
123
|
agent_attributes[DB_STATEMENT_KEY] = truncate(segment.nosql_statement, DB_STATEMENT_MAX_BYTES)
|
123
124
|
end
|
124
125
|
|
126
|
+
if segment.params[:backtrace]
|
127
|
+
agent_attributes[STACKTRACE_KEY] = segment.params[:backtrace]
|
128
|
+
end
|
129
|
+
|
125
130
|
[intrinsics, custom_attributes(segment), agent_attributes.merge(agent_attributes(segment))]
|
126
131
|
end
|
127
132
|
|
@@ -11,7 +11,7 @@ module NewRelic
|
|
11
11
|
module Agent
|
12
12
|
class Transaction
|
13
13
|
class DatastoreSegment < Segment
|
14
|
-
UNKNOWN =
|
14
|
+
UNKNOWN = NewRelic::UNKNOWN_LOWER
|
15
15
|
|
16
16
|
attr_reader :product, :operation, :collection, :sql_statement, :nosql_statement, :host, :port_path_or_id
|
17
17
|
attr_accessor :database_name, :record_sql
|
@@ -35,7 +35,7 @@ module NewRelic
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def caller_transport_type
|
38
|
-
@caller_transport_type ||=
|
38
|
+
@caller_transport_type ||= NewRelic::UNKNOWN
|
39
39
|
end
|
40
40
|
|
41
41
|
def accept_transport_type_from_api(value)
|
@@ -127,7 +127,7 @@ module NewRelic
|
|
127
127
|
def consume_message_synthetics_headers(headers)
|
128
128
|
synthetics_header = headers[CrossAppTracing::NR_MESSAGE_BROKER_SYNTHETICS_HEADER]
|
129
129
|
if synthetics_header and
|
130
|
-
incoming_payload = ::JSON.
|
130
|
+
incoming_payload = ::JSON.parse(deobfuscate(synthetics_header)) and
|
131
131
|
SyntheticsMonitor.is_valid_payload?(incoming_payload) and
|
132
132
|
SyntheticsMonitor.is_supported_version?(incoming_payload) and
|
133
133
|
SyntheticsMonitor.is_trusted?(incoming_payload)
|
@@ -167,7 +167,7 @@ module NewRelic
|
|
167
167
|
return unless CrossAppTracing.trusted_valid_cross_app_id?(decoded_id)
|
168
168
|
|
169
169
|
txn_header = headers[CrossAppTracing::NR_MESSAGE_BROKER_TXN_HEADER]
|
170
|
-
txn_info = ::JSON.
|
170
|
+
txn_info = ::JSON.parse(deobfuscate(txn_header))
|
171
171
|
payload = CrossAppPayload.new(decoded_id, transaction, txn_info)
|
172
172
|
|
173
173
|
@cross_app_payload = payload
|
@@ -136,7 +136,7 @@ module NewRelic
|
|
136
136
|
|
137
137
|
transaction.distributed_tracer.parent_transaction_id = payload.transaction_id
|
138
138
|
|
139
|
-
determine_sampling_decision(payload, header_data)
|
139
|
+
determine_sampling_decision(payload, header_data.trace_parent['trace_flags'])
|
140
140
|
|
141
141
|
NewRelic::Agent.increment_metric(ACCEPT_SUCCESS_METRIC)
|
142
142
|
true
|
@@ -146,10 +146,10 @@ module NewRelic
|
|
146
146
|
false
|
147
147
|
end
|
148
148
|
|
149
|
-
def determine_sampling_decision(payload,
|
150
|
-
if
|
149
|
+
def determine_sampling_decision(payload, trace_flags)
|
150
|
+
if trace_flags == '01'
|
151
151
|
set_priority_and_sampled(NewRelic::Agent.config[:'distributed_tracing.sampler.remote_parent_sampled'], payload)
|
152
|
-
elsif
|
152
|
+
elsif trace_flags == '00'
|
153
153
|
set_priority_and_sampled(NewRelic::Agent.config[:'distributed_tracing.sampler.remote_parent_not_sampled'], payload)
|
154
154
|
else
|
155
155
|
use_nr_tracestate_sampled(payload)
|
@@ -150,7 +150,7 @@ module NewRelic
|
|
150
150
|
# rubocop:disable Style/SafeNavigation
|
151
151
|
transaction_name = transaction_name = Tracer.current_transaction &&
|
152
152
|
Tracer.current_transaction.best_name ||
|
153
|
-
|
153
|
+
NewRelic::UNKNOWN_LOWER
|
154
154
|
# rubocop:enable Style/SafeNavigation
|
155
155
|
NewRelic::Agent.logger.warn("Unable to calculate elapsed transaction time for #{transaction_name}")
|
156
156
|
end
|
@@ -0,0 +1,22 @@
|
|
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 'new_relic/agent/utilization/vendor'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
module Utilization
|
10
|
+
class ECS < Vendor
|
11
|
+
vendor_name 'ecs'
|
12
|
+
endpoint ENV['ECS_CONTAINER_METADATA_URI'] || ''
|
13
|
+
headers 'Metadata' => 'true'
|
14
|
+
keys %w[DockerId]
|
15
|
+
|
16
|
+
def transform_key(key)
|
17
|
+
'ecs' + key
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
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 'new_relic/agent/utilization/vendor'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
module Utilization
|
10
|
+
class ECSV4 < Vendor
|
11
|
+
vendor_name 'ecs_v4'
|
12
|
+
endpoint ENV['ECS_CONTAINER_METADATA_URI_V4'] || ''
|
13
|
+
headers 'Metadata' => 'true'
|
14
|
+
keys %w[DockerId]
|
15
|
+
|
16
|
+
def transform_key(key)
|
17
|
+
'ecs' + key
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -6,6 +6,8 @@ require 'new_relic/agent/utilization/aws'
|
|
6
6
|
require 'new_relic/agent/utilization/gcp'
|
7
7
|
require 'new_relic/agent/utilization/azure'
|
8
8
|
require 'new_relic/agent/utilization/pcf'
|
9
|
+
require 'new_relic/agent/utilization/ecs'
|
10
|
+
require 'new_relic/agent/utilization/ecs_v4'
|
9
11
|
|
10
12
|
module NewRelic
|
11
13
|
module Agent
|
@@ -84,10 +86,32 @@ module NewRelic
|
|
84
86
|
result
|
85
87
|
end
|
86
88
|
|
89
|
+
def append_ecs_info(collector_hash)
|
90
|
+
return unless Agent.config[:'utilization.detect_aws']
|
91
|
+
|
92
|
+
Thread.new do
|
93
|
+
# try v4 first, and only try unversioned endpoint if v4 fails
|
94
|
+
ecs = Utilization::ECSV4.new
|
95
|
+
if ecs.detect
|
96
|
+
collector_hash[:vendors] ||= {}
|
97
|
+
collector_hash[:vendors][:ecs] = ecs.metadata
|
98
|
+
else
|
99
|
+
ecs = Utilization::ECS.new
|
100
|
+
if ecs.detect
|
101
|
+
collector_hash[:vendors] ||= {}
|
102
|
+
collector_hash[:vendors][:ecs] = ecs.metadata
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
87
108
|
def append_vendor_info(collector_hash)
|
88
109
|
threads = []
|
89
110
|
complete = false
|
90
111
|
|
112
|
+
# ecs needs be checked even if AWS check succeeds
|
113
|
+
ecs_thread = append_ecs_info(collector_hash)
|
114
|
+
|
91
115
|
VENDORS.each_pair do |klass, config_option|
|
92
116
|
next unless Agent.config[config_option]
|
93
117
|
|
@@ -106,6 +130,7 @@ module NewRelic
|
|
106
130
|
while complete == false && threads.any?(&:alive?)
|
107
131
|
sleep 0.01
|
108
132
|
end
|
133
|
+
ecs_thread&.join
|
109
134
|
end
|
110
135
|
|
111
136
|
def append_docker_info(collector_hash)
|
@@ -61,7 +61,7 @@ module NewRelic
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def gather_constant_cache_invalidations
|
64
|
-
RubyVM.stat[RUBY_VERSION >= '3.2.0' ? :constant_cache_invalidations : :global_constant_state]
|
64
|
+
RubyVM.stat[NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '3.2.0') ? :constant_cache_invalidations : :global_constant_state]
|
65
65
|
end
|
66
66
|
|
67
67
|
def gather_constant_cache_misses
|
@@ -86,9 +86,9 @@ module NewRelic
|
|
86
86
|
when :gc_total_time
|
87
87
|
NewRelic::LanguageSupport.gc_profiler_enabled?
|
88
88
|
when :method_cache_invalidations
|
89
|
-
RUBY_VERSION < '3.0.0'
|
89
|
+
NewRelic::Helper.version_satisfied?(RUBY_VERSION, '<', '3.0.0')
|
90
90
|
when :constant_cache_misses
|
91
|
-
RUBY_VERSION >= '3.2.0'
|
91
|
+
NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '3.2.0')
|
92
92
|
else
|
93
93
|
false
|
94
94
|
end
|