Skip to content

Commit

Permalink
Merge branch 'main' into enable-commenter-instrument-connection
Browse files Browse the repository at this point in the history
  • Loading branch information
tammy-baylis-swi authored Dec 11, 2024
2 parents 197e5ea + d2a51b9 commit b3ae9c8
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 17 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([#2816](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2816))
- `opentelemetry-instrumentation-sqlalchemy`: Fix a remaining memory leak in EngineTracer
([#3053](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3053))
- `opentelemetry-instrumentation-sqlite3`: Update documentation on explicit cursor support of tracing
([#3088](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3088))

### Breaking changes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
# Enable instrumentation
BotocoreInstrumentor().instrument()
AwsLambdaInstrumentor().instrument()
# Lambda function
def lambda_handler(event, context):
Expand All @@ -39,6 +38,8 @@ def lambda_handler(event, context):
return "200 OK"
AwsLambdaInstrumentor().instrument()
API
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,19 @@ def test_traced_client(self):
request_id = "fdcdcab1-ae5c-489e-9c33-4637c5dda355"
self.assert_span("EC2", "DescribeInstances", request_id=request_id)

@mock_aws
def test_no_op_tracer_provider_ec2(self):
BotocoreInstrumentor().uninstrument()
BotocoreInstrumentor().instrument(
tracer_provider=trace_api.NoOpTracerProvider()
)

ec2 = self._make_client("ec2")
ec2.describe_instances()

spans_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans_list), 0)

@mock_aws
def test_not_recording(self):
mock_tracer = Mock()
Expand Down Expand Up @@ -148,6 +161,19 @@ def test_s3_client(self):
s3.list_buckets()
self.assert_span("S3", "ListBuckets")

@mock_aws
def test_no_op_tracer_provider_s3(self):
BotocoreInstrumentor().uninstrument()
BotocoreInstrumentor().instrument(
tracer_provider=trace_api.NoOpTracerProvider()
)

s3 = self._make_client("s3")
s3.list_buckets()

spans_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans_list), 0)

@mock_aws
def test_s3_put(self):
s3 = self._make_client("s3")
Expand Down Expand Up @@ -176,6 +202,19 @@ def test_sqs_client(self):
"SQS", "ListQueues", request_id=_REQUEST_ID_REGEX_MATCH
)

@mock_aws
def test_no_op_tracer_provider_sqs(self):
BotocoreInstrumentor().uninstrument()
BotocoreInstrumentor().instrument(
tracer_provider=trace_api.NoOpTracerProvider()
)

sqs = self._make_client("sqs")
sqs.list_queues()

spans_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans_list), 0)

@mock_aws
def test_sqs_send_message(self):
sqs = self._make_client("sqs")
Expand Down Expand Up @@ -204,6 +243,19 @@ def test_kinesis_client(self):
kinesis.list_streams()
self.assert_span("Kinesis", "ListStreams")

@mock_aws
def test_no_op_tracer_provider_kinesis(self):
BotocoreInstrumentor().uninstrument()
BotocoreInstrumentor().instrument(
tracer_provider=trace_api.NoOpTracerProvider()
)

kinesis = self._make_client("kinesis")
kinesis.list_streams()

spans_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans_list), 0)

@mock_aws
def test_unpatch(self):
kinesis = self._make_client("kinesis")
Expand All @@ -213,6 +265,19 @@ def test_unpatch(self):
kinesis.list_streams()
self.assertEqual(0, len(self.memory_exporter.get_finished_spans()))

@mock_aws
def test_no_op_tracer_provider_kms(self):
BotocoreInstrumentor().uninstrument()
BotocoreInstrumentor().instrument(
tracer_provider=trace_api.NoOpTracerProvider()
)

kms = self._make_client("kms")
kms.list_keys(Limit=21)

spans_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans_list), 0)

@mock_aws
def test_uninstrument_does_not_inject_headers(self):
headers = {}
Expand Down Expand Up @@ -268,6 +333,19 @@ def test_sts_client(self):
# check for exact attribute set to make sure not to leak any sts secrets
self.assertEqual(expected, dict(span.attributes))

@mock_aws
def test_no_op_tracer_provider_sts(self):
BotocoreInstrumentor().uninstrument()
BotocoreInstrumentor().instrument(
tracer_provider=trace_api.NoOpTracerProvider()
)

sts = self._make_client("sts")
sts.get_caller_identity()

spans_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans_list), 0)

@mock_aws
def test_propagator_injects_into_request(self):
headers = {}
Expand Down Expand Up @@ -308,6 +386,19 @@ def check_headers(**kwargs):
finally:
set_global_textmap(previous_propagator)

@mock_aws
def test_no_op_tracer_provider_xray(self):
BotocoreInstrumentor().uninstrument()
BotocoreInstrumentor().instrument(
tracer_provider=trace_api.NoOpTracerProvider()
)

xray_client = self._make_client("xray")
xray_client.put_trace_segments(TraceSegmentDocuments=["str1"])

spans_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(spans_list), 0)

@mock_aws
def test_override_xray_propagator_injects_into_request(self):
headers = {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

"""
SQLite instrumentation supporting `sqlite3`_, it can be enabled by
using ``SQLite3Instrumentor``.
using ``SQLite3Instrumentor``. At this time, cursor objects must
be explicitly initialized as shown below to support tracing.
.. _sqlite3: https://docs.python.org/3/library/sqlite3.html
Expand All @@ -29,8 +30,9 @@
SQLite3Instrumentor().instrument()
cnx = sqlite3.connect('example.db')
cnx = sqlite3.connect(':memory:')
cursor = cnx.cursor()
cursor.execute("CREATE TABLE test (testField INTEGER)")
cursor.execute("INSERT INTO test (testField) VALUES (123)")
cursor.close()
cnx.close()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

from logging import getLogger
from typing import Collection, Optional, Union
from typing import Collection

from packaging.requirements import InvalidRequirement, Requirement

Expand All @@ -27,10 +29,10 @@


class DependencyConflict:
required: str = None
found: Optional[str] = None
required: str | None = None
found: str | None = None

def __init__(self, required, found=None):
def __init__(self, required: str | None, found: str | None = None):
self.required = required
self.found = found

Expand All @@ -40,7 +42,7 @@ def __str__(self):

def get_dist_dependency_conflicts(
dist: Distribution,
) -> Optional[DependencyConflict]:
) -> DependencyConflict | None:
instrumentation_deps = []
extra = "extra"
instruments = "instruments"
Expand All @@ -57,8 +59,8 @@ def get_dist_dependency_conflicts(


def get_dependency_conflicts(
deps: Collection[Union[str, Requirement]],
) -> Optional[DependencyConflict]:
deps: Collection[str | Requirement],
) -> DependencyConflict | None:
for dep in deps:
if isinstance(dep, Requirement):
req = dep
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
OpenTelemetry Base Instrumentor
"""

from __future__ import annotations

from abc import ABC, abstractmethod
from logging import getLogger
from typing import Collection, Optional
from typing import Any, Collection

from opentelemetry.instrumentation._semconv import (
_OpenTelemetrySemanticConventionStability,
Expand All @@ -33,7 +35,7 @@


class BaseInstrumentor(ABC):
"""An ABC for instrumentors
"""An ABC for instrumentors.
Child classes of this ABC should instrument specific third
party libraries or frameworks either by using the
Expand Down Expand Up @@ -74,18 +76,18 @@ def instrumentation_dependencies(self) -> Collection[str]:
is present in the environment.
"""

def _instrument(self, **kwargs):
def _instrument(self, **kwargs: Any):
"""Instrument the library"""

@abstractmethod
def _uninstrument(self, **kwargs):
def _uninstrument(self, **kwargs: Any):
"""Uninstrument the library"""

def _check_dependency_conflicts(self) -> Optional[DependencyConflict]:
def _check_dependency_conflicts(self) -> DependencyConflict | None:
dependencies = self.instrumentation_dependencies()
return get_dependency_conflicts(dependencies)

def instrument(self, **kwargs):
def instrument(self, **kwargs: Any):
"""Instrument the library
This method will be called without any optional arguments by the
Expand Down Expand Up @@ -117,7 +119,7 @@ def instrument(self, **kwargs):
self._is_instrumented_by_opentelemetry = True
return result

def uninstrument(self, **kwargs):
def uninstrument(self, **kwargs: Any):
"""Uninstrument the library
See ``BaseInstrumentor.instrument`` for more information regarding the
Expand Down

0 comments on commit b3ae9c8

Please sign in to comment.