From 1bf9f928d3371dce8fe157c17b70d4eddc3f4826 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Wed, 30 Sep 2020 10:36:57 -0400 Subject: [PATCH] Use is_recording flag in flask, django, tornado, boto, botocore instrumentations (#1164) --- .../instrumentation/botocore/__init__.py | 38 +++++++++++-------- .../tests/test_botocore_instrumentation.py | 33 ++++++++++++++++ 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py index d716c90d6..b574b86cf 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py @@ -97,7 +97,7 @@ class BotocoreInstrumentor(BaseInstrumentor): ) as span: operation = None - if args: + if args and span.is_recording(): operation = args[0] span.resource = Resource( attributes={ @@ -119,25 +119,28 @@ class BotocoreInstrumentor(BaseInstrumentor): {"params", "path", "verb"}, ) - region_name = deep_getattr(instance, "meta.region_name") + if span.is_recording(): + region_name = deep_getattr(instance, "meta.region_name") - meta = { - "aws.agent": "botocore", - "aws.operation": operation, - "aws.region": region_name, - } - for key, value in meta.items(): - span.set_attribute(key, value) + meta = { + "aws.agent": "botocore", + "aws.operation": operation, + "aws.region": region_name, + } + for key, value in meta.items(): + span.set_attribute(key, value) result = original_func(*args, **kwargs) - span.set_attribute( - "http.status_code", - result["ResponseMetadata"]["HTTPStatusCode"], - ) - span.set_attribute( - "retry_attempts", result["ResponseMetadata"]["RetryAttempts"], - ) + if span.is_recording(): + span.set_attribute( + "http.status_code", + result["ResponseMetadata"]["HTTPStatusCode"], + ) + span.set_attribute( + "retry_attempts", + result["ResponseMetadata"]["RetryAttempts"], + ) return result @@ -177,6 +180,9 @@ def add_span_arg_tags(span, endpoint_name, args, args_names, args_traced): else {prefix: dict_} ) + if not span.is_recording(): + return + if endpoint_name not in {"kms", "sts"}: tags = dict( (name, value) diff --git a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py index ea655c883..9bf691f65 100644 --- a/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py +++ b/instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py @@ -1,3 +1,19 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from unittest.mock import Mock, patch + import botocore.session from botocore.exceptions import ParamValidationError from moto import ( # pylint: disable=import-error @@ -61,6 +77,23 @@ class TestBotocoreInstrumentor(TestBase): ) self.assertEqual(span.name, "ec2.command") + @mock_ec2 + def test_not_recording(self): + mock_tracer = Mock() + mock_span = Mock() + mock_span.is_recording.return_value = False + mock_tracer.start_span.return_value = mock_span + mock_tracer.use_span.return_value.__enter__ = mock_span + mock_tracer.use_span.return_value.__exit__ = mock_span + with patch("opentelemetry.trace.get_tracer") as tracer: + tracer.return_value = mock_tracer + ec2 = self.session.create_client("ec2", region_name="us-west-2") + ec2.describe_instances() + self.assertFalse(mock_span.is_recording()) + self.assertTrue(mock_span.is_recording.called) + self.assertFalse(mock_span.set_attribute.called) + self.assertFalse(mock_span.set_status.called) + @mock_ec2 def test_traced_client_analytics(self): ec2 = self.session.create_client("ec2", region_name="us-west-2")