opentelemetry-instrumentation-botocore 0.57b0__tar.gz → 0.58b0__tar.gz

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.
Files changed (93) hide show
  1. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/PKG-INFO +3 -3
  2. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/pyproject.toml +2 -2
  3. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/extensions/__init__.py +1 -0
  4. opentelemetry_instrumentation_botocore-0.58b0/src/opentelemetry/instrumentation/botocore/extensions/sfns.py +58 -0
  5. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/extensions/sns.py +20 -0
  6. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/version.py +1 -1
  7. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/test_botocore_dynamodb.py +4 -4
  8. opentelemetry_instrumentation_botocore-0.58b0/tests/test_botocore_sfns.py +117 -0
  9. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/test_botocore_sns.py +24 -0
  10. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/.gitignore +0 -0
  11. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/LICENSE +0 -0
  12. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/README.rst +0 -0
  13. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/__init__.py +0 -0
  14. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/environment_variables.py +0 -0
  15. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/extensions/_messaging.py +0 -0
  16. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/extensions/bedrock.py +0 -0
  17. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/extensions/bedrock_utils.py +0 -0
  18. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/extensions/dynamodb.py +0 -0
  19. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/extensions/lmbd.py +0 -0
  20. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/extensions/sqs.py +0 -0
  21. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/extensions/types.py +0 -0
  22. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/package.py +0 -0
  23. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/src/opentelemetry/instrumentation/botocore/utils.py +0 -0
  24. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/README.md +0 -0
  25. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/__init__.py +0 -0
  26. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/bedrock_utils.py +0 -0
  27. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_no_content.yaml +0 -0
  28. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_no_content_different_events.yaml +0 -0
  29. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_stream_close_before_consumption.yaml +0 -0
  30. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_stream_handles_event_stream_error.yaml +0 -0
  31. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_stream_no_content.yaml +0 -0
  32. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_stream_no_content_different_events.yaml +0 -0
  33. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_stream_no_content_tool_call.yaml +0 -0
  34. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_stream_tool_call_parsing_errors.yaml +0 -0
  35. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_stream_with_content.yaml +0 -0
  36. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_stream_with_content_different_events.yaml +0 -0
  37. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_stream_with_content_tool_call.yaml +0 -0
  38. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_stream_with_invalid_model.yaml +0 -0
  39. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_tool_call_no_content.yaml +0 -0
  40. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_tool_call_with_content.yaml +0 -0
  41. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_with_content.yaml +0 -0
  42. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_with_content_different_events.yaml +0 -0
  43. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_converse_with_invalid_model.yaml +0 -0
  44. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_no_content[amazon.nova].yaml +0 -0
  45. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_no_content[amazon.titan].yaml +0 -0
  46. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_no_content[anthropic.claude].yaml +0 -0
  47. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_no_content[cohere.command-r].yaml +0 -0
  48. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_no_content[cohere.command].yaml +0 -0
  49. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_no_content[meta.llama].yaml +0 -0
  50. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_no_content[mistral.mistral].yaml +0 -0
  51. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_no_content_different_events[amazon.nova].yaml +0 -0
  52. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_no_content_different_events[anthropic.claude].yaml +0 -0
  53. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_no_content_tool_call[amazon.nova].yaml +0 -0
  54. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_no_content_tool_call[anthropic.claude].yaml +0 -0
  55. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_content[amazon.nova].yaml +0 -0
  56. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_content[amazon.titan].yaml +0 -0
  57. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_content[anthropic.claude].yaml +0 -0
  58. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_content[cohere.command-r].yaml +0 -0
  59. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_content[cohere.command].yaml +0 -0
  60. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_content[meta.llama].yaml +0 -0
  61. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_content[mistral.mistral].yaml +0 -0
  62. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_content_assistant_content_as_string.yaml +0 -0
  63. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_content_different_events[amazon.nova].yaml +0 -0
  64. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_content_different_events[anthropic.claude].yaml +0 -0
  65. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_content_tool_call[amazon.nova].yaml +0 -0
  66. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_content_tool_call[anthropic.claude].yaml +0 -0
  67. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_content_user_content_as_string.yaml +0 -0
  68. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_invalid_model.yaml +0 -0
  69. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_close_before_consumption[amazon.nova].yaml +0 -0
  70. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_close_before_consumption[amazon.titan].yaml +0 -0
  71. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_close_before_consumption[anthropic.claude].yaml +0 -0
  72. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_handles_stream_error.yaml +0 -0
  73. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_invalid_model.yaml +0 -0
  74. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_no_content[amazon.nova].yaml +0 -0
  75. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_no_content[amazon.titan].yaml +0 -0
  76. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_no_content[anthropic.claude].yaml +0 -0
  77. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_no_content_different_events[amazon.nova].yaml +0 -0
  78. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_no_content_different_events[anthropic.claude].yaml +0 -0
  79. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_no_content_tool_call[amazon.nova].yaml +0 -0
  80. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_no_content_tool_call[anthropic.claude].yaml +0 -0
  81. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_with_content[amazon.nova].yaml +0 -0
  82. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_with_content[amazon.titan].yaml +0 -0
  83. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_with_content[anthropic.claude].yaml +0 -0
  84. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_with_content_different_events[amazon.nova].yaml +0 -0
  85. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_with_content_different_events[anthropic.claude].yaml +0 -0
  86. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_with_content_tool_call[amazon.nova].yaml +0 -0
  87. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/cassettes/test_invoke_model_with_response_stream_with_content_tool_call[anthropic.claude].yaml +0 -0
  88. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/conftest.py +0 -0
  89. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/test_botocore_bedrock.py +0 -0
  90. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/test_botocore_instrumentation.py +0 -0
  91. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/test_botocore_lambda.py +0 -0
  92. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/test_botocore_messaging.py +0 -0
  93. {opentelemetry_instrumentation_botocore-0.57b0 → opentelemetry_instrumentation_botocore-0.58b0}/tests/test_botocore_sqs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opentelemetry-instrumentation-botocore
3
- Version: 0.57b0
3
+ Version: 0.58b0
4
4
  Summary: OpenTelemetry Botocore instrumentation
5
5
  Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-botocore
6
6
  Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python-contrib
@@ -19,9 +19,9 @@ Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Programming Language :: Python :: 3.13
20
20
  Requires-Python: >=3.9
21
21
  Requires-Dist: opentelemetry-api~=1.30
22
- Requires-Dist: opentelemetry-instrumentation==0.57b0
22
+ Requires-Dist: opentelemetry-instrumentation==0.58b0
23
23
  Requires-Dist: opentelemetry-propagator-aws-xray~=1.0
24
- Requires-Dist: opentelemetry-semantic-conventions==0.57b0
24
+ Requires-Dist: opentelemetry-semantic-conventions==0.58b0
25
25
  Provides-Extra: instruments
26
26
  Requires-Dist: botocore~=1.0; extra == 'instruments'
27
27
  Description-Content-Type: text/x-rst
@@ -26,8 +26,8 @@ classifiers = [
26
26
  ]
27
27
  dependencies = [
28
28
  "opentelemetry-api ~= 1.30",
29
- "opentelemetry-instrumentation == 0.57b0",
30
- "opentelemetry-semantic-conventions == 0.57b0",
29
+ "opentelemetry-instrumentation == 0.58b0",
30
+ "opentelemetry-semantic-conventions == 0.58b0",
31
31
  "opentelemetry-propagator-aws-xray ~= 1.0",
32
32
  ]
33
33
 
@@ -35,6 +35,7 @@ _KNOWN_EXTENSIONS = {
35
35
  "bedrock-runtime": _lazy_load(".bedrock", "_BedrockRuntimeExtension"),
36
36
  "dynamodb": _lazy_load(".dynamodb", "_DynamoDbExtension"),
37
37
  "lambda": _lazy_load(".lmbd", "_LambdaExtension"),
38
+ "stepfunctions": _lazy_load(".sfns", "_StepFunctionsExtension"),
38
39
  "sns": _lazy_load(".sns", "_SnsExtension"),
39
40
  "sqs": _lazy_load(".sqs", "_SqsExtension"),
40
41
  }
@@ -0,0 +1,58 @@
1
+ # Copyright The OpenTelemetry Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ from opentelemetry.instrumentation.botocore.extensions.types import (
15
+ _AttributeMapT,
16
+ _AwsSdkExtension,
17
+ _BotocoreInstrumentorContext,
18
+ _BotoResultT,
19
+ )
20
+ from opentelemetry.semconv._incubating.attributes.aws_attributes import (
21
+ AWS_STEP_FUNCTIONS_ACTIVITY_ARN,
22
+ AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN,
23
+ )
24
+ from opentelemetry.trace.span import Span
25
+
26
+
27
+ class _StepFunctionsExtension(_AwsSdkExtension):
28
+ @staticmethod
29
+ def _set_arn_attributes(source, target, setter_func):
30
+ """Helper to set ARN attributes if they exist in source."""
31
+ activity_arn = source.get("activityArn")
32
+ if activity_arn:
33
+ setter_func(target, AWS_STEP_FUNCTIONS_ACTIVITY_ARN, activity_arn)
34
+
35
+ state_machine_arn = source.get("stateMachineArn")
36
+ if state_machine_arn:
37
+ setter_func(
38
+ target, AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN, state_machine_arn
39
+ )
40
+
41
+ def extract_attributes(self, attributes: _AttributeMapT):
42
+ self._set_arn_attributes(
43
+ self._call_context.params,
44
+ attributes,
45
+ lambda target, key, value: target.__setitem__(key, value),
46
+ )
47
+
48
+ def on_success(
49
+ self,
50
+ span: Span,
51
+ result: _BotoResultT,
52
+ instrumentor_context: _BotocoreInstrumentorContext,
53
+ ):
54
+ self._set_arn_attributes(
55
+ result,
56
+ span,
57
+ lambda target, key, value: target.set_attribute(key, value),
58
+ )
@@ -24,6 +24,10 @@ from opentelemetry.instrumentation.botocore.extensions.types import (
24
24
  _AwsSdkCallContext,
25
25
  _AwsSdkExtension,
26
26
  _BotocoreInstrumentorContext,
27
+ _BotoResultT,
28
+ )
29
+ from opentelemetry.semconv._incubating.attributes.aws_attributes import (
30
+ AWS_SNS_TOPIC_ARN,
27
31
  )
28
32
  from opentelemetry.semconv.trace import (
29
33
  MessagingDestinationKindValues,
@@ -161,6 +165,9 @@ class _SnsExtension(_AwsSdkExtension):
161
165
 
162
166
  def extract_attributes(self, attributes: _AttributeMapT):
163
167
  attributes[SpanAttributes.MESSAGING_SYSTEM] = "aws.sns"
168
+ topic_arn = self._call_context.params.get("TopicArn")
169
+ if topic_arn:
170
+ attributes[AWS_SNS_TOPIC_ARN] = topic_arn
164
171
 
165
172
  if self._op:
166
173
  self._op.extract_attributes(self._call_context, attributes)
@@ -170,3 +177,16 @@ class _SnsExtension(_AwsSdkExtension):
170
177
  ):
171
178
  if self._op:
172
179
  self._op.before_service_call(self._call_context, span)
180
+
181
+ def on_success(
182
+ self,
183
+ span: Span,
184
+ result: _BotoResultT,
185
+ instrumentor_context: _BotocoreInstrumentorContext,
186
+ ):
187
+ if not span.is_recording():
188
+ return
189
+
190
+ topic_arn = result.get("TopicArn")
191
+ if topic_arn:
192
+ span.set_attribute(AWS_SNS_TOPIC_ARN, topic_arn)
@@ -12,4 +12,4 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- __version__ = "0.57b0"
15
+ __version__ = "0.58b0"
@@ -439,7 +439,7 @@ class TestDynamoDbExtension(TestBase):
439
439
  Limit=42,
440
440
  Select="ALL_ATTRIBUTES",
441
441
  TotalSegments=17,
442
- Segment=21,
442
+ Segment=16,
443
443
  ProjectionExpression="PE",
444
444
  ConsistentRead=True,
445
445
  ReturnConsumedCapacity="TOTAL",
@@ -448,14 +448,14 @@ class TestDynamoDbExtension(TestBase):
448
448
  span = self.assert_span("Scan")
449
449
  self.assert_table_names(span, self.default_table_name)
450
450
  self.assertEqual(
451
- 21, span.attributes[SpanAttributes.AWS_DYNAMODB_SEGMENT]
451
+ 16, span.attributes[SpanAttributes.AWS_DYNAMODB_SEGMENT]
452
452
  )
453
453
  self.assertEqual(
454
454
  17, span.attributes[SpanAttributes.AWS_DYNAMODB_TOTAL_SEGMENTS]
455
455
  )
456
- self.assertEqual(1, span.attributes[SpanAttributes.AWS_DYNAMODB_COUNT])
456
+ self.assertEqual(0, span.attributes[SpanAttributes.AWS_DYNAMODB_COUNT])
457
457
  self.assertEqual(
458
- 1, span.attributes[SpanAttributes.AWS_DYNAMODB_SCANNED_COUNT]
458
+ 0, span.attributes[SpanAttributes.AWS_DYNAMODB_SCANNED_COUNT]
459
459
  )
460
460
  self.assert_attributes_to_get(span, "id", "idl")
461
461
  self.assert_consistent_read(span, True)
@@ -0,0 +1,117 @@
1
+ import json
2
+
3
+ import botocore.session
4
+ from moto import mock_aws
5
+
6
+ from opentelemetry.instrumentation.botocore import BotocoreInstrumentor
7
+ from opentelemetry.semconv._incubating.attributes.aws_attributes import (
8
+ AWS_STEP_FUNCTIONS_ACTIVITY_ARN,
9
+ AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN,
10
+ )
11
+ from opentelemetry.test.test_base import TestBase
12
+
13
+
14
+ class TestSfnsExtension(TestBase):
15
+ def setUp(self):
16
+ super().setUp()
17
+ BotocoreInstrumentor().instrument()
18
+ session = botocore.session.get_session()
19
+ session.set_credentials(
20
+ access_key="access-key", secret_key="secret-key"
21
+ )
22
+ self.region = "us-west-2"
23
+ self.client = session.create_client(
24
+ "stepfunctions", region_name=self.region
25
+ )
26
+
27
+ def tearDown(self):
28
+ super().tearDown()
29
+ BotocoreInstrumentor().uninstrument()
30
+
31
+ SIMPLE_STATE_MACHINE_DEF = {
32
+ "Comment": "A simple Hello World example",
33
+ "StartAt": "HelloState",
34
+ "States": {
35
+ "HelloState": {
36
+ "Type": "Pass",
37
+ "Result": "Hello, Moto!",
38
+ "End": True,
39
+ }
40
+ },
41
+ }
42
+
43
+ def create_state_machine_and_get_arn(
44
+ self, name: str = "TestStateMachine"
45
+ ) -> str:
46
+ """
47
+ Create a state machine in mocked Step Functions and return its ARN.
48
+ """
49
+ definition_json = json.dumps(self.SIMPLE_STATE_MACHINE_DEF)
50
+ role_arn = "arn:aws:iam::123456789012:role/DummyRole"
51
+
52
+ response = self.client.create_state_machine(
53
+ name=name,
54
+ definition=definition_json,
55
+ roleArn=role_arn,
56
+ )
57
+ return response["stateMachineArn"]
58
+
59
+ def create_activity_and_get_arn(self, name: str = "TestActivity") -> str:
60
+ """
61
+ Create an activity in mocked Step Functions and return its ARN.
62
+ """
63
+ response = self.client.create_activity(
64
+ name=name,
65
+ )
66
+ return response["activityArn"]
67
+
68
+ @mock_aws
69
+ def test_sfns_create_state_machine(self):
70
+ state_machine_arn = self.create_state_machine_and_get_arn()
71
+ spans = self.memory_exporter.get_finished_spans()
72
+ assert spans
73
+ self.assertEqual(len(spans), 1)
74
+ span = spans[0]
75
+ self.assertEqual(
76
+ span.attributes[AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN],
77
+ state_machine_arn,
78
+ )
79
+
80
+ @mock_aws
81
+ def test_sfns_describe_state_machine(self):
82
+ state_machine_arn = self.create_state_machine_and_get_arn()
83
+ self.client.describe_state_machine(stateMachineArn=state_machine_arn)
84
+
85
+ spans = self.memory_exporter.get_finished_spans()
86
+ assert spans
87
+ self.assertEqual(len(spans), 2)
88
+ span = spans[1]
89
+ self.assertEqual(
90
+ span.attributes[AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN],
91
+ state_machine_arn,
92
+ )
93
+
94
+ @mock_aws
95
+ def test_sfns_create_activity(self):
96
+ activity_arn = self.create_activity_and_get_arn()
97
+ spans = self.memory_exporter.get_finished_spans()
98
+ assert spans
99
+ self.assertEqual(len(spans), 1)
100
+ span = spans[0]
101
+ self.assertEqual(
102
+ span.attributes[AWS_STEP_FUNCTIONS_ACTIVITY_ARN],
103
+ activity_arn,
104
+ )
105
+
106
+ @mock_aws
107
+ def test_sfns_describe_activity(self):
108
+ activity_arn = self.create_activity_and_get_arn()
109
+ self.client.describe_activity(activityArn=activity_arn)
110
+ spans = self.memory_exporter.get_finished_spans()
111
+ assert spans
112
+ self.assertEqual(len(spans), 2)
113
+ span = spans[1]
114
+ self.assertEqual(
115
+ span.attributes[AWS_STEP_FUNCTIONS_ACTIVITY_ARN],
116
+ activity_arn,
117
+ )
@@ -21,6 +21,9 @@ from botocore.awsrequest import AWSResponse
21
21
  from moto import mock_aws
22
22
 
23
23
  from opentelemetry.instrumentation.botocore import BotocoreInstrumentor
24
+ from opentelemetry.semconv._incubating.attributes.aws_attributes import (
25
+ AWS_SNS_TOPIC_ARN,
26
+ )
24
27
  from opentelemetry.semconv.trace import (
25
28
  MessagingDestinationKindValues,
26
29
  SpanAttributes,
@@ -151,6 +154,10 @@ class TestSnsExtension(TestBase):
151
154
  )
152
155
 
153
156
  span = self.assert_span(f"{self.topic_name} send")
157
+ self.assertEqual(
158
+ topic_arn,
159
+ span.attributes[AWS_SNS_TOPIC_ARN],
160
+ )
154
161
  self.assert_injected_span(message_attrs, span)
155
162
 
156
163
  def test_publish_batch_to_topic(self):
@@ -188,6 +195,10 @@ class TestSnsExtension(TestBase):
188
195
  MessagingDestinationKindValues.TOPIC.value,
189
196
  span.attributes[SpanAttributes.MESSAGING_DESTINATION_KIND],
190
197
  )
198
+ self.assertEqual(
199
+ topic_arn,
200
+ span.attributes[AWS_SNS_TOPIC_ARN],
201
+ )
191
202
  self.assertEqual(
192
203
  topic_arn,
193
204
  span.attributes[SpanAttributes.MESSAGING_DESTINATION],
@@ -199,3 +210,16 @@ class TestSnsExtension(TestBase):
199
210
 
200
211
  self.assert_injected_span(message1_attrs, span)
201
212
  self.assert_injected_span(message2_attrs, span)
213
+
214
+ @mock_aws
215
+ def test_create_topic_span(self):
216
+ _ = self.client.create_topic(Name=self.topic_name)
217
+ spans = self.memory_exporter.get_finished_spans()
218
+ self.assertEqual(1, len(spans))
219
+ span = spans[0]
220
+ self.assertEqual(SpanKind.CLIENT, span.kind)
221
+ self.assertEqual("SNS.CreateTopic", span.name)
222
+ self.assertEqual(
223
+ self.topic_arn,
224
+ span.attributes[AWS_SNS_TOPIC_ARN],
225
+ )