opentelemetry-instrumentation-aws_sdk 0.6.0 → 0.7.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: 05256cef329eccec85d4d6732b402aa9c1be08fa39da455cee3ed43d4b0ed9c7
4
- data.tar.gz: d4f05d032386bdbabfb064e051757a02fc27b75947594bb89211b311abb54446
3
+ metadata.gz: fc28b8e181dc59950237cb56fbde713e2083003bab88acd345bd90dba7b5eb1a
4
+ data.tar.gz: a479a21f7d6c14d691df13d7683bf5a680045185520205018d70a9736b306a2a
5
5
  SHA512:
6
- metadata.gz: 7dada29094deea482504658785d9b13ce16d2e8d4198d0c08b64c378618cda70d30744ece8a0b59a12df3a39f18a23ca9f93c1b3186ea51e53e4a6c03e887127
7
- data.tar.gz: 379d073b4f1d46dce866fdd15a85677cc7f436b82c608a40731f4a716222fda9b3774fecf0264679046f79b1cf71179398a7c555c7815f8f35e5ce461784eb73
6
+ metadata.gz: 86d3e8d2c0a94cd739f5abdeae3c762573d6e175b0fc4ffd682fc1811ce1da7fc2d4fd73ce0131573531b9f3643d9ef5b3bf775869aa9445012d43295af2c02c
7
+ data.tar.gz: 1b1d40e77d958f1869163cf01f1d6ddf6bb8713170747cf6d754fc225d6a9715efe6454a3b5f4fb7e9d5d0025d22ca745c0dccf46385718509f97a604fd3c33f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Release History: opentelemetry-instrumentation-aws_sdk
2
2
 
3
+ ### v0.7.0 / 2024-10-08
4
+
5
+ * ADDED: Integration with V3 telemetry provider
6
+
3
7
  ### v0.6.0 / 2024-09-19
4
8
 
5
9
  * ADDED: All AWS services emit traces
data/README.md CHANGED
@@ -32,6 +32,30 @@ OpenTelemetry::SDK.configure do |c|
32
32
  c.use_all
33
33
  end
34
34
  ```
35
+ ### Configuration options
36
+ This instrumentation offers the following configuration options:
37
+ * `:inject_messaging_context` (default: `false`): When set to `true`, adds context key/value
38
+ to Message Attributes for SQS/SNS messages.
39
+ * `suppress_internal_instrumentation` (default: `false`): When set to `true`, any spans with
40
+ span kind of `internal` are suppressed from traces.
41
+
42
+ ## Integration with SDK V3's Telemetry support
43
+ AWS SDK for Ruby V3 added support for Observability which includes a new configuration,
44
+ `telemetry_provider` and an OpenTelemetry-based telemetry provider. Only applies to
45
+ AWS service gems released after 2024-09-03.
46
+
47
+ Using later versions of these gems will give more details on the internal spans.
48
+ See below for example usage:
49
+ ```ruby
50
+ # configures the OpenTelemetry SDK with instrumentation defaults
51
+ OpenTelemetry::SDK.configure do |c|
52
+ c.use 'OpenTelemetry::Instrumentation::AwsSdk'
53
+ end
54
+
55
+ # create open-telemetry provider and pass to client config
56
+ otel_provider = Aws::Telemetry::OTelProvider.new
57
+ client = Aws::S3::Client.new(telemetry_provider: otel_provider)
58
+ ```
35
59
 
36
60
  ## Example
37
61
 
@@ -7,26 +7,23 @@
7
7
  module OpenTelemetry
8
8
  module Instrumentation
9
9
  module AwsSdk
10
- # Generates Spans for all interactions with AwsSdk
10
+ # This handler supports specifically supports V2 and V3
11
+ # prior to Observability support released on 2024-09-03.
11
12
  class Handler < Seahorse::Client::Handler
12
13
  def call(context)
13
14
  return super unless context
14
15
 
15
- service_id = service_name(context)
16
- operation = context.operation&.name
17
- client_method = "#{service_id}.#{operation}"
16
+ service_id = HandlerHelper.service_id(context, legacy: true)
17
+ client_method = HandlerHelper.client_method(service_id, context)
18
18
 
19
19
  tracer.in_span(
20
- span_name(context, client_method, service_id),
21
- attributes: attributes(context, client_method, service_id, operation),
22
- kind: span_kind(client_method, service_id)
20
+ HandlerHelper.span_name(context, client_method, service_id, legacy: true),
21
+ attributes: HandlerHelper.span_attributes(context, client_method, service_id, legacy: true),
22
+ kind: HandlerHelper.span_kind(client_method, service_id)
23
23
  ) do |span|
24
- if instrumentation_config[:inject_messaging_context] &&
25
- %w[SQS SNS].include?(service_id)
26
- MessagingHelper.inject_context(context, client_method)
27
- end
24
+ MessagingHelper.inject_context_if_supported(context, client_method, service_id)
28
25
 
29
- if instrumentation_config[:suppress_internal_instrumentation]
26
+ if HandlerHelper.instrumentation_config[:suppress_internal_instrumentation]
30
27
  OpenTelemetry::Common::Utilities.untraced { super }
31
28
  else
32
29
  super
@@ -49,47 +46,6 @@ module OpenTelemetry
49
46
  def tracer
50
47
  AwsSdk::Instrumentation.instance.tracer
51
48
  end
52
-
53
- def instrumentation_config
54
- AwsSdk::Instrumentation.instance.config
55
- end
56
-
57
- def service_name(context)
58
- # Support aws-sdk v2.0.x, which 'metadata' has a setter method only
59
- return context.client.class.to_s.split('::')[1] if ::Seahorse::Model::Api.instance_method(:metadata).parameters.length.positive?
60
-
61
- context.client.class.api.metadata['serviceId'] || context.client.class.to_s.split('::')[1]
62
- end
63
-
64
- def span_kind(client_method, service_id)
65
- case service_id
66
- when 'SQS', 'SNS'
67
- MessagingHelper.span_kind(client_method)
68
- else
69
- OpenTelemetry::Trace::SpanKind::CLIENT
70
- end
71
- end
72
-
73
- def span_name(context, client_method, service_id)
74
- case service_id
75
- when 'SQS', 'SNS'
76
- MessagingHelper.legacy_span_name(context, client_method)
77
- else
78
- client_method
79
- end
80
- end
81
-
82
- def attributes(context, client_method, service_id, operation)
83
- {
84
- 'aws.region' => context.config.region,
85
- OpenTelemetry::SemanticConventions::Trace::RPC_SYSTEM => 'aws-api',
86
- OpenTelemetry::SemanticConventions::Trace::RPC_METHOD => operation,
87
- OpenTelemetry::SemanticConventions::Trace::RPC_SERVICE => service_id
88
- }.tap do |attrs|
89
- attrs[SemanticConventions::Trace::DB_SYSTEM] = 'dynamodb' if service_id == 'DynamoDB'
90
- MessagingHelper.apply_span_attributes(context, attrs, client_method, service_id) if %w[SQS SNS].include?(service_id)
91
- end
92
- end
93
49
  end
94
50
 
95
51
  # A Seahorse::Client::Plugin that enables instrumentation for all AWS services
@@ -0,0 +1,81 @@
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
+ # Utility module that contains shared methods between AwsSdk and Telemetry handlers
11
+ module HandlerHelper
12
+ class << self
13
+ def instrumentation_config
14
+ AwsSdk::Instrumentation.instance.config
15
+ end
16
+
17
+ def client_method(service_id, context)
18
+ "#{service_id}.#{context.operation.name}".delete(' ')
19
+ end
20
+
21
+ def span_attributes(context, client_method, service_id, legacy: false)
22
+ {
23
+ 'aws.region' => context.config.region,
24
+ OpenTelemetry::SemanticConventions::Trace::CODE_FUNCTION => context.operation_name.to_s,
25
+ OpenTelemetry::SemanticConventions::Trace::CODE_NAMESPACE => 'Aws::Plugins::Telemetry',
26
+ OpenTelemetry::SemanticConventions::Trace::RPC_METHOD => context.operation.name,
27
+ OpenTelemetry::SemanticConventions::Trace::RPC_SERVICE => service_id,
28
+ OpenTelemetry::SemanticConventions::Trace::RPC_SYSTEM => 'aws-api'
29
+ }.tap do |attrs|
30
+ attrs[OpenTelemetry::SemanticConventions::Trace::CODE_NAMESPACE] = 'Aws::Plugins::AwsSdk' if legacy
31
+ attrs[SemanticConventions::Trace::DB_SYSTEM] = 'dynamodb' if service_id == 'DynamoDB'
32
+
33
+ MessagingHelper.apply_span_attributes(context, attrs, client_method, service_id) if MessagingHelper::SUPPORTED_SERVICES.include?(service_id)
34
+ end
35
+ end
36
+
37
+ def span_kind(client_method, service_id)
38
+ case service_id
39
+ when *MessagingHelper::SUPPORTED_SERVICES
40
+ MessagingHelper.span_kind(client_method)
41
+ else
42
+ OpenTelemetry::Trace::SpanKind::CLIENT
43
+ end
44
+ end
45
+
46
+ def span_name(context, client_method, service_id, legacy: false)
47
+ case service_id
48
+ when *MessagingHelper::SUPPORTED_SERVICES
49
+ if legacy
50
+ MessagingHelper.legacy_span_name(context, client_method)
51
+ else
52
+ MessagingHelper.span_name(context, client_method)
53
+ end
54
+ else
55
+ client_method
56
+ end
57
+ end
58
+
59
+ def service_id(context, legacy: false)
60
+ if legacy
61
+ legacy_service_id(context)
62
+ else
63
+ context.config.api.metadata['serviceId'] ||
64
+ context.config.api.metadata['serviceAbbreviation'] ||
65
+ context.config.api.metadata['serviceFullName']
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ def legacy_service_id(context)
72
+ # Support aws-sdk v2.0.x, which 'metadata' has a setter method only
73
+ return context.client.class.to_s.split('::')[1] if ::Seahorse::Model::Api.instance_method(:metadata).parameters.length.positive?
74
+
75
+ context.client.class.api.metadata['serviceId'] || context.client.class.to_s.split('::')[1]
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -7,12 +7,38 @@
7
7
  module OpenTelemetry
8
8
  module Instrumentation
9
9
  module AwsSdk
10
- # Instrumentation class that detects and installs the AwsSdk instrumentation
10
+ # The `OpenTelemetry::Instrumentation::AwsSdk::Instrumentation` class contains
11
+ # logic to detect and install the AwsSdk instrumentation.
12
+ #
13
+ # ## Configuration keys and options
14
+ #
15
+ # ### `:inject_messaging_context`
16
+ #
17
+ # Allows adding of context key/value to Message Attributes for SQS/SNS messages.
18
+ #
19
+ # - `false` **(default)** - Context key/value will not be added.
20
+ # - `true` - Context key/value will be added.
21
+ #
22
+ # ### `:suppress_internal_instrumentation`
23
+ #
24
+ # Disables tracing of spans of `internal` span kind.
25
+ #
26
+ # - `false` **(default)** - Internal spans are traced.
27
+ # - `true` - Internal spans are not traced.
28
+ #
29
+ # @example An explicit default configuration
30
+ # OpenTelemetry::SDK.configure do |c|
31
+ # c.use 'OpenTelemetry::Instrumentation::AwsSdk', {
32
+ # inject_messaging_context: false,
33
+ # suppress_internal_instrumentation: false
34
+ # }
35
+ # end
11
36
  class Instrumentation < OpenTelemetry::Instrumentation::Base
12
37
  MINIMUM_VERSION = Gem::Version.new('2.0.0')
13
38
 
14
39
  install do |_config|
15
40
  require_dependencies
41
+ patch_telemetry_plugin if telemetry_plugin?
16
42
  add_plugins(Seahorse::Client::Base, *loaded_service_clients)
17
43
  end
18
44
 
@@ -41,12 +67,34 @@ module OpenTelemetry
41
67
 
42
68
  def require_dependencies
43
69
  require_relative 'handler'
70
+ require_relative 'handler_helper'
44
71
  require_relative 'message_attributes'
45
72
  require_relative 'messaging_helper'
73
+ require_relative 'patches/telemetry'
46
74
  end
47
75
 
48
76
  def add_plugins(*targets)
49
- targets.each { |klass| klass.add_plugin(AwsSdk::Plugin) }
77
+ targets.each do |klass|
78
+ next if supports_telemetry_plugin?(klass)
79
+
80
+ klass.add_plugin(AwsSdk::Plugin)
81
+ end
82
+ end
83
+
84
+ def supports_telemetry_plugin?(klass)
85
+ telemetry_plugin? &&
86
+ klass.plugins.include?(Aws::Plugins::Telemetry)
87
+ end
88
+
89
+ def telemetry_plugin?
90
+ ::Aws::Plugins.const_defined?(:Telemetry)
91
+ end
92
+
93
+ # Patches AWS SDK V3's telemetry plugin for integration
94
+ # This patch supports configuration set by this gem and
95
+ # additional span attributes that was not provided by the plugin
96
+ def patch_telemetry_plugin
97
+ ::Aws::Plugins::Telemetry::Handler.prepend(Patches::Handler)
50
98
  end
51
99
 
52
100
  def loaded_service_clients
@@ -9,6 +9,7 @@ module OpenTelemetry
9
9
  module AwsSdk
10
10
  # An utility class to help SQS/SNS-related span attributes/context injection
11
11
  class MessagingHelper
12
+ SUPPORTED_SERVICES = %w[SQS SNS].freeze
12
13
  class << self
13
14
  SQS_SEND_MESSAGE = 'SQS.SendMessage'
14
15
  SQS_SEND_MESSAGE_BATCH = 'SQS.SendMessageBatch'
@@ -16,6 +17,10 @@ module OpenTelemetry
16
17
  SNS_PUBLISH = 'SNS.Publish'
17
18
  SEND_MESSAGE_CLIENT_METHODS = [SQS_SEND_MESSAGE, SQS_SEND_MESSAGE_BATCH, SNS_PUBLISH].freeze
18
19
 
20
+ def supported_services
21
+ SUPPORTED_SERVICES
22
+ end
23
+
19
24
  def queue_name(context)
20
25
  topic_arn = context.params[:topic_arn]
21
26
  target_arn = context.params[:target_arn]
@@ -34,6 +39,17 @@ module OpenTelemetry
34
39
  'unknown'
35
40
  end
36
41
 
42
+ def span_name(context, client_method)
43
+ case client_method
44
+ when SQS_SEND_MESSAGE, SQS_SEND_MESSAGE_BATCH, SNS_PUBLISH
45
+ "#{client_method}.#{queue_name(context)}.Publish"
46
+ when SQS_RECEIVE_MESSAGE
47
+ "#{client_method}.#{queue_name(context)}.Receive"
48
+ else
49
+ client_method
50
+ end
51
+ end
52
+
37
53
  def legacy_span_name(context, client_method)
38
54
  case client_method
39
55
  when SQS_SEND_MESSAGE, SQS_SEND_MESSAGE_BATCH, SNS_PUBLISH
@@ -65,6 +81,13 @@ module OpenTelemetry
65
81
  end
66
82
  end
67
83
 
84
+ def inject_context_if_supported(context, client_method, service_id)
85
+ if HandlerHelper.instrumentation_config[:inject_messaging_context] &&
86
+ SUPPORTED_SERVICES.include?(service_id)
87
+ inject_context(context, client_method)
88
+ end
89
+ end
90
+
68
91
  def inject_context(context, client_method)
69
92
  return unless SEND_MESSAGE_CLIENT_METHODS.include?(client_method)
70
93
 
@@ -0,0 +1,40 @@
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
+ module Patches
11
+ # Patch for Telemetry Plugin Handler in V3 SDK
12
+ module Handler
13
+ def call(context)
14
+ span_wrapper(context) { @handler.call(context) }
15
+ end
16
+
17
+ private
18
+
19
+ def span_wrapper(context, &block)
20
+ service_id = HandlerHelper.service_id(context)
21
+ client_method = HandlerHelper.client_method(service_id, context)
22
+ context.tracer.in_span(
23
+ HandlerHelper.span_name(context, client_method, service_id),
24
+ attributes: HandlerHelper.span_attributes(context, client_method, service_id),
25
+ kind: HandlerHelper.span_kind(client_method, service_id)
26
+ ) do |span|
27
+ MessagingHelper.inject_context_if_supported(context, client_method, service_id)
28
+
29
+ if HandlerHelper.instrumentation_config[:suppress_internal_instrumentation]
30
+ OpenTelemetry::Common::Utilities.untraced { super }
31
+ else
32
+ yield span
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -7,7 +7,7 @@
7
7
  module OpenTelemetry
8
8
  module Instrumentation
9
9
  module AwsSdk
10
- VERSION = '0.6.0'
10
+ VERSION = '0.7.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.6.0
4
+ version: 0.7.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: 2024-09-20 00:00:00.000000000 Z
11
+ date: 2024-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opentelemetry-api
@@ -170,14 +170,14 @@ dependencies:
170
170
  requirements:
171
171
  - - "~>"
172
172
  - !ruby/object:Gem::Version
173
- version: '1.20'
173
+ version: 1.22.0
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
- version: '1.20'
180
+ version: 1.22.0
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: simplecov
183
183
  requirement: !ruby/object:Gem::Requirement
@@ -198,14 +198,14 @@ dependencies:
198
198
  requirements:
199
199
  - - "~>"
200
200
  - !ruby/object:Gem::Version
201
- version: '3.19'
201
+ version: 3.24.0
202
202
  type: :development
203
203
  prerelease: false
204
204
  version_requirements: !ruby/object:Gem::Requirement
205
205
  requirements:
206
206
  - - "~>"
207
207
  - !ruby/object:Gem::Version
208
- version: '3.19'
208
+ version: 3.24.0
209
209
  - !ruby/object:Gem::Dependency
210
210
  name: yard
211
211
  requirement: !ruby/object:Gem::Requirement
@@ -235,18 +235,20 @@ files:
235
235
  - lib/opentelemetry/instrumentation.rb
236
236
  - lib/opentelemetry/instrumentation/aws_sdk.rb
237
237
  - lib/opentelemetry/instrumentation/aws_sdk/handler.rb
238
+ - lib/opentelemetry/instrumentation/aws_sdk/handler_helper.rb
238
239
  - lib/opentelemetry/instrumentation/aws_sdk/instrumentation.rb
239
240
  - lib/opentelemetry/instrumentation/aws_sdk/message_attributes.rb
240
241
  - lib/opentelemetry/instrumentation/aws_sdk/messaging_helper.rb
242
+ - lib/opentelemetry/instrumentation/aws_sdk/patches/telemetry.rb
241
243
  - lib/opentelemetry/instrumentation/aws_sdk/version.rb
242
244
  homepage: https://github.com/open-telemetry/opentelemetry-ruby-contrib
243
245
  licenses:
244
246
  - Apache-2.0
245
247
  metadata:
246
- changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-aws_sdk/0.6.0/file/CHANGELOG.md
248
+ changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-aws_sdk/0.7.0/file/CHANGELOG.md
247
249
  source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation/aws_sdk
248
250
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues
249
- documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-aws_sdk/0.6.0
251
+ documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-aws_sdk/0.7.0
250
252
  post_install_message:
251
253
  rdoc_options: []
252
254
  require_paths: