Class: NewRelic::Agent::OpenTelemetry::MessagingTranslator

Inherits:
BaseTranslator
  • Object
show all
Defined in:
lib/new_relic/agent/opentelemetry/translators/messaging_translator.rb

Constant Summary collapse

DESTINATION_TYPES_MAP =

OTel seems to be inconsistent with dot or underscore, so we handle both just in case.

{
  consumer: {
    'kafka' => :topic,
    'rabbitmq' => :queue,
    'aws.sqs' => :queue,
    'aws_sqs' => :queue,
    'aws.sns' => :topic,
    'aws_sns' => :topic,
    'aws.kinesis' => :stream,
    'aws_kinesis' => :stream
  },
  producer: {
    'kafka' => :topic,
    'rabbitmq' => :exchange,
    'aws.sqs' => :queue,
    'aws_sqs' => :queue,
    'aws.sns' => :topic,
    'aws_sns' => :topic,
    'aws.kinesis' => :stream,
    'aws_kinesis' => :stream
  }
}.freeze
DESTINATION_KIND_MAP =

‘messaging.destination_kind` is a v1.17 attribute that we should honor when present.

{
  'queue' => :queue,
  'topic' => :topic
}.freeze
TEMP_MAP =
{
  queue: :temporary_queue,
  topic: :temporary_topic
}.freeze
ACTION_MAP =
{
  consumer: :consume,
  producer: :produce
}.freeze
LIBRARY_MAP =

Capitalize the OTel ‘messaging.system` value to match the casing used by NR messaging instrumentation.

{
  'kafka' => 'Kafka',
  'rabbitmq' => 'RabbitMQ',
  'aws.sqs' => 'SQS',
  'aws_sqs' => 'SQS',
  'aws.sns' => 'SNS',
  'aws_sns' => 'SNS',
  'aws.kinesis' => 'Kinesis',
  'aws_kinesis' => 'Kinesis'
}.freeze
ROUTING_KEY_OTEL_KEYS =
[
  'messaging.kafka.message.key',
  'messaging.rabbitmq.destination.routing_key'
].freeze
CORRELATION_ID_OTEL_KEY =
'messaging.message.conversation_id'

Constants included from AttributeMappings

AttributeMappings::DATASTORE_MAPPINGS, AttributeMappings::DEFAULT_DESTINATIONS, AttributeMappings::HTTP_CLIENT_MAPPINGS, AttributeMappings::HTTP_SERVER_MAPPINGS, AttributeMappings::MESSAGING_CONSUMER_MAPPINGS, AttributeMappings::MESSAGING_PRODUCER_MAPPINGS, AttributeMappings::REDIS_MAPPINGS, AttributeMappings::RPC_CLIENT_MAPPINGS, AttributeMappings::RPC_SERVER_MAPPINGS

Class Method Summary collapse

Methods inherited from BaseTranslator

translate

Class Method Details

.add_producer_segment_params(result, attributes) ⇒ Object



103
104
105
106
107
108
109
110
# File 'lib/new_relic/agent/opentelemetry/translators/messaging_translator.rb', line 103

def add_producer_segment_params(result, attributes)
  params = {
    routing_key: ROUTING_KEY_OTEL_KEYS.map { |k| attributes[k] }.compact.first,
    correlation_id: attributes[CORRELATION_ID_OTEL_KEY]
  }.compact

  result[:for_segment_api][:parameters] = params unless params.empty?
end

.add_specialized_attributes(result: {}, name: nil, attributes: nil, instrumentation_scope: nil, kind: nil) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/new_relic/agent/opentelemetry/translators/messaging_translator.rb', line 78

def add_specialized_attributes(result: {}, name: nil, attributes: nil, instrumentation_scope: nil, kind: nil)
  result[:for_segment_api][:action] = ACTION_MAP[kind]
  result[:for_segment_api][:destination_type] = determine_destination_type(attributes, kind)
  if (system = attributes['messaging.system'])
    result[:for_segment_api][:library] = LIBRARY_MAP[system] || system
  end

  result[:for_segment_api][:name] = build_transaction_name(result[:for_segment_api])

  add_producer_segment_params(result, attributes) if kind == :producer

  result
end

.build_transaction_name(segment_api_params) ⇒ Object



92
93
94
95
96
97
98
99
100
101
# File 'lib/new_relic/agent/opentelemetry/translators/messaging_translator.rb', line 92

def build_transaction_name(segment_api_params)
  return nil unless segment_api_params[:library] && segment_api_params[:destination_name]

  NewRelic::Agent::Messaging.transaction_name(
    segment_api_params[:library],
    segment_api_params[:destination_type],
    segment_api_params[:destination_name],
    segment_api_params[:action]
  )
end

.determine_destination_type(attributes, kind) ⇒ Object



112
113
114
115
116
117
118
119
# File 'lib/new_relic/agent/opentelemetry/translators/messaging_translator.rb', line 112

def determine_destination_type(attributes, kind)
  type = explicit_destination_kind(attributes) ||
    DESTINATION_TYPES_MAP[kind][attributes['messaging.system']] ||
    :unknown
  return type unless attributes['messaging.destination.temporary'] == true

  TEMP_MAP[type] || type
end

.explicit_destination_kind(attributes) ⇒ Object



121
122
123
# File 'lib/new_relic/agent/opentelemetry/translators/messaging_translator.rb', line 121

def explicit_destination_kind(attributes)
  DESTINATION_KIND_MAP[attributes['messaging.destination_kind']]
end

.mappings_hash(kind) ⇒ Object



74
75
76
# File 'lib/new_relic/agent/opentelemetry/translators/messaging_translator.rb', line 74

def mappings_hash(kind)
  kind == :consumer ? AttributeMappings::MESSAGING_CONSUMER_MAPPINGS : AttributeMappings::MESSAGING_PRODUCER_MAPPINGS
end