opentelemetry-instrumentation-aws_sdk 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6b7ce8bb3f8c316bd797fc08f9255cebe9ba3f0d642844124112c170104ee06
4
- data.tar.gz: 5edcf80454e00bab286aea2c6b65f00970ab786feeed56c452de37c08cb1c239
3
+ metadata.gz: 25ec693b3e795860dc934fdfd53cc6e8811edfeb02a1d0e6e00befdfffaa868c
4
+ data.tar.gz: d6844163d29157d36b34a6fe845d0cab60e40d020004269d5ccb78f2f8f33f75
5
5
  SHA512:
6
- metadata.gz: 9fe79f219f6e3d98c33b658fe59a364f5bf1a2e1d51cf2f173239d817f55932af6c4465a02f898ced656294eb08ee5960f4e7ad2c378ee002a870ded65d28a41
7
- data.tar.gz: d24a17ecd61802eaaecc1d07f076986c267ac1879ce1c7f57a84b0f93c26f53a905efc97406ab6037268507d84d90275fd4c89227d545c7512f80ae4004b7361
6
+ metadata.gz: e43e05fd3994b51649acf47392b14bda90384727c44791fb5e638a67dbe9ac4f67dae91b46180b0cf4354aee0fbcd4eff74118fff3b32151419eb915fa18c1c8
7
+ data.tar.gz: 69db39398bc60c76390a4a56054768e294aadaa7b5aa17ffbd257217488a134df452df795f988da03a5e3073f125b8fffd03a7952ed3e9b64590d4a6849bfb9c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Release History: opentelemetry-instrumentation-aws_sdk
2
2
 
3
+ ### v0.2.0 / 2022-01-20
4
+
5
+ * ADDED: SQS / SNS messaging attributes and context propagation
6
+
3
7
  ### v0.1.0 / 2021-12-01
4
8
 
5
9
  * Initial release.
data/README.md CHANGED
@@ -19,6 +19,7 @@ To install the instrumentation, call `use` with the name of the instrumentation.
19
19
  ```ruby
20
20
  OpenTelemetry::SDK.configure do |c|
21
21
  c.use 'OpenTelemetry::Instrumentation::AwsSdk', {
22
+ inject_messaging_context: true,
22
23
  suppress_internal_instrumentation: true
23
24
  }
24
25
  end
@@ -9,11 +9,17 @@ module OpenTelemetry
9
9
  module AwsSdk
10
10
  # Generates Spans for all interactions with AwsSdk
11
11
  class Handler < Seahorse::Client::Handler
12
- def call(context) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
12
+ SQS_SEND_MESSAGE = 'SQS.SendMessage'
13
+ SQS_SEND_MESSAGE_BATCH = 'SQS.SendMessageBatch'
14
+ SQS_RECEIVE_MESSAGE = 'SQS.ReceiveMessage'
15
+ SNS_PUBLISH = 'SNS.Publish'
16
+
17
+ def call(context) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
13
18
  return super unless context
14
19
 
15
- service_name = context.client.class.api.metadata['serviceId'] || context.client.class.to_s.split('::')[1]
20
+ service_name = service_name(context)
16
21
  operation = context.operation&.name
22
+ client_method = "#{service_name}.#{operation}"
17
23
  attributes = {
18
24
  'aws.region' => context.config.region,
19
25
  OpenTelemetry::SemanticConventions::Trace::RPC_SYSTEM => 'aws-api',
@@ -21,8 +27,11 @@ module OpenTelemetry
21
27
  OpenTelemetry::SemanticConventions::Trace::RPC_SERVICE => service_name
22
28
  }
23
29
  attributes[SemanticConventions::Trace::DB_SYSTEM] = 'dynamodb' if service_name == 'DynamoDB'
30
+ MessagingHelper.apply_sqs_attributes(attributes, context, client_method) if service_name == 'SQS'
31
+ MessagingHelper.apply_sns_attributes(attributes, context, client_method) if service_name == 'SNS'
24
32
 
25
- tracer.in_span("#{service_name}.#{operation}", attributes: attributes, kind: OpenTelemetry::Trace::SpanKind::CLIENT) do |span|
33
+ tracer.in_span(span_name(context, client_method), attributes: attributes, kind: span_kind(client_method)) do |span|
34
+ inject_context(context, client_method)
26
35
  if instrumentation_config[:suppress_internal_instrumentation]
27
36
  OpenTelemetry::Common::Utilities.untraced { super }
28
37
  else
@@ -30,7 +39,7 @@ module OpenTelemetry
30
39
  end.tap do |response|
31
40
  if (err = response.error)
32
41
  span.record_exception(err)
33
- span.status = Trace::Status.error(err)
42
+ span.status = Trace::Status.error(err.to_s)
34
43
  end
35
44
  end
36
45
  end
@@ -45,6 +54,51 @@ module OpenTelemetry
45
54
  def instrumentation_config
46
55
  AwsSdk::Instrumentation.instance.config
47
56
  end
57
+
58
+ def service_name(context) # rubocop:disable Metrics/AbcSize
59
+ # Support aws-sdk v2.0.x, which 'metadata' has a setter method only
60
+ return context.client.class.to_s.split('::')[1] if ::Seahorse::Model::Api.instance_method(:metadata).parameters.length.positive?
61
+
62
+ context.client.class.api.metadata['serviceId'] || context.client.class.to_s.split('::')[1]
63
+ end
64
+
65
+ SEND_MESSAGE_CLIENT_METHODS = [SQS_SEND_MESSAGE, SQS_SEND_MESSAGE_BATCH, SNS_PUBLISH].freeze
66
+ def inject_context(context, client_method)
67
+ return unless SEND_MESSAGE_CLIENT_METHODS.include? client_method
68
+ return unless instrumentation_config[:inject_messaging_context]
69
+
70
+ if client_method == SQS_SEND_MESSAGE_BATCH
71
+ context.params[:entries].each do |entry|
72
+ entry[:message_attributes] ||= {}
73
+ OpenTelemetry.propagation.inject(entry[:message_attributes], setter: MessageAttributeSetter)
74
+ end
75
+ else
76
+ context.params[:message_attributes] ||= {}
77
+ OpenTelemetry.propagation.inject(context.params[:message_attributes], setter: MessageAttributeSetter)
78
+ end
79
+ end
80
+
81
+ def span_kind(client_method)
82
+ case client_method
83
+ when SQS_SEND_MESSAGE, SQS_SEND_MESSAGE_BATCH, SNS_PUBLISH
84
+ OpenTelemetry::Trace::SpanKind::PRODUCER
85
+ when SQS_RECEIVE_MESSAGE
86
+ OpenTelemetry::Trace::SpanKind::CONSUMER
87
+ else
88
+ OpenTelemetry::Trace::SpanKind::CLIENT
89
+ end
90
+ end
91
+
92
+ def span_name(context, client_method)
93
+ case client_method
94
+ when SQS_SEND_MESSAGE, SQS_SEND_MESSAGE_BATCH, SNS_PUBLISH
95
+ "#{MessagingHelper.queue_name(context)} send"
96
+ when SQS_RECEIVE_MESSAGE
97
+ "#{MessagingHelper.queue_name(context)} receive"
98
+ else
99
+ client_method
100
+ end
101
+ end
48
102
  end
49
103
 
50
104
  # A Seahorse::Client::Plugin that enables instrumentation for all AWS services
@@ -24,15 +24,9 @@ module OpenTelemetry
24
24
  gem_version >= MINIMUM_VERSION
25
25
  end
26
26
 
27
+ option :inject_messaging_context, default: false, validate: :boolean
27
28
  option :suppress_internal_instrumentation, default: false, validate: :boolean
28
29
 
29
- private
30
-
31
- def require_dependencies
32
- require_relative 'handler'
33
- require_relative 'services'
34
- end
35
-
36
30
  def gem_version
37
31
  if Gem.loaded_specs['aws-sdk']
38
32
  Gem.loaded_specs['aws-sdk'].version
@@ -41,6 +35,15 @@ module OpenTelemetry
41
35
  end
42
36
  end
43
37
 
38
+ private
39
+
40
+ def require_dependencies
41
+ require_relative 'handler'
42
+ require_relative 'services'
43
+ require_relative 'message_attributes'
44
+ require_relative 'messaging_helper'
45
+ end
46
+
44
47
  def add_plugin(*targets)
45
48
  targets.each { |klass| klass.add_plugin(AwsSdk::Plugin) }
46
49
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright The OpenTelemetry Authors
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+
7
+ module OpenTelemetry
8
+ module Instrumentation
9
+ module AwsSdk
10
+ # The MessageAttributeSetter class provides methods for writing tracing information to
11
+ # SNS / SQS messages.
12
+ #
13
+ # @example
14
+ # OpenTelemetry.propagation.inject(context.params[:message_attributes], setter: MessageAttributeSetter)
15
+ class MessageAttributeSetter
16
+ def self.set(carrier, key, value)
17
+ # https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-quotas.html
18
+ if carrier.length < 10
19
+ carrier[key] = { string_value: value, data_type: 'String' }
20
+ else
21
+ OpenTelemetry.logger.warn('aws-sdk instrumentation: cannot set context propagation on SQS/SNS message due to maximum amount of MessageAttributes')
22
+ end
23
+ end
24
+ end
25
+
26
+ # The MessageAttributeGetter class provides methods for getting tracing information from SQS message.
27
+ #
28
+ # @example
29
+ # OpenTelemetry.propagation.extract(message, getter: MessageAttributeGetter)
30
+ class MessageAttributeGetter
31
+ def self.get(carrier, key)
32
+ return carrier[key][:string_value] if carrier[key][:data_type] == 'String'
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright The OpenTelemetry Authors
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+
7
+ module OpenTelemetry
8
+ module Instrumentation
9
+ module AwsSdk
10
+ # MessagingHelper class provides methods for calculating messaging span attributes
11
+ class MessagingHelper
12
+ class << self
13
+ def queue_name(context)
14
+ topic_arn = context.params[:topic_arn]
15
+ target_arn = context.params[:target_arn]
16
+
17
+ if topic_arn || target_arn
18
+ arn = topic_arn || target_arn
19
+ return arn.split(':')[-1]
20
+ end
21
+
22
+ phone_number = context.params[:phone_number]
23
+ return 'phone_number' if phone_number
24
+
25
+ queue_url = context.params[:queue_url]
26
+ return queue_url.split('/')[-1] if queue_url
27
+
28
+ 'unknown'
29
+ end
30
+
31
+ def apply_sqs_attributes(attributes, context, client_method)
32
+ attributes[SemanticConventions::Trace::MESSAGING_SYSTEM] = 'aws.sqs'
33
+ attributes[SemanticConventions::Trace::MESSAGING_DESTINATION_KIND] = 'queue'
34
+ attributes[SemanticConventions::Trace::MESSAGING_DESTINATION] = queue_name(context)
35
+ attributes[SemanticConventions::Trace::MESSAGING_URL] = context.params[:queue_url]
36
+
37
+ attributes[SemanticConventions::Trace::MESSAGING_OPERATION] = 'receive' if client_method == 'SQS.ReceiveMessage'
38
+ end
39
+
40
+ def apply_sns_attributes(attributes, context, client_method)
41
+ attributes[SemanticConventions::Trace::MESSAGING_SYSTEM] = 'aws.sns'
42
+
43
+ return unless client_method == 'SNS.Publish'
44
+
45
+ attributes[SemanticConventions::Trace::MESSAGING_DESTINATION_KIND] = 'topic'
46
+ attributes[SemanticConventions::Trace::MESSAGING_DESTINATION] = queue_name(context)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -7,7 +7,7 @@
7
7
  module OpenTelemetry
8
8
  module Instrumentation
9
9
  module AwsSdk
10
- VERSION = '0.1.0'
10
+ VERSION = '0.2.0'
11
11
  end
12
12
  end
13
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-instrumentation-aws_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-01 00:00:00.000000000 Z
11
+ date: 2022-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opentelemetry-api
@@ -236,16 +236,18 @@ files:
236
236
  - lib/opentelemetry/instrumentation/aws_sdk.rb
237
237
  - lib/opentelemetry/instrumentation/aws_sdk/handler.rb
238
238
  - lib/opentelemetry/instrumentation/aws_sdk/instrumentation.rb
239
+ - lib/opentelemetry/instrumentation/aws_sdk/message_attributes.rb
240
+ - lib/opentelemetry/instrumentation/aws_sdk/messaging_helper.rb
239
241
  - lib/opentelemetry/instrumentation/aws_sdk/services.rb
240
242
  - lib/opentelemetry/instrumentation/aws_sdk/version.rb
241
243
  homepage: https://github.com/open-telemetry/opentelemetry-ruby
242
244
  licenses:
243
245
  - Apache-2.0
244
246
  metadata:
245
- changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-instrumentation-aws_sdk/v0.1.0/file.CHANGELOG.html
247
+ changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-instrumentation-aws_sdk/v0.2.0/file.CHANGELOG.html
246
248
  source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/instrumentation/aws_sdk
247
249
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby/issues
248
- documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-instrumentation-aws_sdk/v0.1.0
250
+ documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-instrumentation-aws_sdk/v0.2.0
249
251
  post_install_message:
250
252
  rdoc_options: []
251
253
  require_paths: