opentelemetry-instrumentation-aws_sdk 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: