Skip to content

Commit 34d37d9

Browse files
author
alrex
authored
Merge branch 'master' into http
2 parents e761066 + a384130 commit 34d37d9

File tree

56 files changed

+2651
-95
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2651
-95
lines changed

Diff for: .github/pull_request_template.md

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Please describe the tests that you ran to verify your changes. Provide instructi
2121

2222
# Checklist:
2323

24+
See [contributing.md](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/master/CONTRIBUTING.md) for styleguide, changelog guidelines, and more.
25+
2426
- [ ] Followed the style guidelines of this project
2527
- [ ] Changelogs have been updated
2628
- [ ] Unit tests have been added

Diff for: .github/workflows/test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
fail-fast: false # ensures the entire test matrix is run, even if one permutation fails
2323
matrix:
2424
python-version: [ py35, py36, py37, py38, pypy3 ]
25-
package: ["instrumentation", "exporter"]
25+
package: ["instrumentation", "exporter", "sdkextension"]
2626
os: [ ubuntu-latest ]
2727
include:
2828
# py35-instrumentation segfaults on 18.04 so we instead run on 20.04

Diff for: CONTRIBUTING.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,13 @@ A PR is considered to be **ready to merge** when:
104104
reasonable time to review.
105105
* Trivial change (typo, cosmetic, doc, etc.) doesn't have to wait for one day.
106106
* Urgent fix can take exception as long as it has been actively communicated.
107+
* A changelog entry is added to the corresponding changelog for the code base, if there is any impact on behavior. e.g. doc entries are not required, but small bug entries are.
107108

108109
Any Approver / Maintainer can merge the PR once it is **ready to merge**.
109110

110111
## Design Choices
111112

112-
As with other OpenTelemetry clients, opentelemetry-python follows the
113+
As with other OpenTelemetry clients, opentelemetry-python follows the
113114
[opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification).
114115

115116
It's especially valuable to read through the [library guidelines](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/library-guidelines.md).
@@ -122,7 +123,7 @@ use cases are clear, but the method to satisfy those uses cases are not.
122123
As such, contributions should provide functionality and behavior that
123124
conforms to the specification, but the interface and structure is flexible.
124125

125-
It is preferable to have contributions follow the idioms of the language
126+
It is preferable to have contributions follow the idioms of the language
126127
rather than conform to specific API names or argument patterns in the spec.
127128

128129
For a deeper discussion, see: https://github.com/open-telemetry/opentelemetry-specification/issues/165

Diff for: dev-requirements.txt

+4
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,7 @@ sphinx-rtd-theme~=0.4
88
sphinx-autodoc-typehints~=1.10.2
99
pytest!=5.2.3
1010
pytest-cov>=2.8
11+
readme-renderer~=24.0
12+
grpcio-tools==1.29.0
13+
mypy-protobuf>=1.23
14+
protobuf>=3.13.0

Diff for: instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/wrappers.py

-3
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@
2323
2424
from opentelemetry import trace
2525
from opentelemetry.instrumentation.aiopg import trace_integration
26-
from opentelemetry.trace import TracerProvider
27-
28-
trace.set_tracer_provider(TracerProvider())
2926
3027
trace_integration(aiopg.connection, "_connect", "postgresql", "sql")
3128

Diff for: instrumentation/opentelemetry-instrumentation-aiopg/tests/test_aiopg_integration.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,11 @@ def test_span_succeeded(self):
199199
"user": "user",
200200
}
201201
db_integration = AiopgIntegration(
202-
self.tracer, "testcomponent", "testtype", connection_attributes
202+
self.tracer,
203+
"testcomponent",
204+
"testtype",
205+
connection_attributes,
206+
capture_parameters=True,
203207
)
204208
mock_connection = async_call(
205209
db_integration.wrapped_connection(

Diff for: instrumentation/opentelemetry-instrumentation-boto/src/opentelemetry/instrumentation/boto/__init__.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,12 @@
2626
2727
.. code:: python
2828
29-
from opentelemetry import trace
3029
from opentelemetry.instrumentation.boto import BotoInstrumentor
31-
from opentelemetry.sdk.trace import TracerProvider
3230
import boto
3331
34-
trace.set_tracer_provider(TracerProvider())
3532
3633
# Instrument Boto
37-
BotoInstrumentor().instrument(tracer_provider=trace.get_tracer_provider())
34+
BotoInstrumentor().instrument()
3835
3936
# This will create a span with Boto-specific attributes
4037
ec2 = boto.ec2.connect_to_region("us-west-2")

Diff for: instrumentation/opentelemetry-instrumentation-botocore/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Changelog
22

33
## Unreleased
4+
- Add propagator injection for botocore calls
5+
([#181](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/181))
6+
- Make botocore instrumentation check if instrumentation has been suppressed
7+
([#182](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/182))
48

59
## Version 0.13b0
610

Diff for: instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py

+19-6
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,12 @@
2727
2828
.. code:: python
2929
30-
from opentelemetry import trace
3130
from opentelemetry.instrumentation.botocore import BotocoreInstrumentor
32-
from opentelemetry.sdk.trace import TracerProvider
3331
import botocore
3432
35-
trace.set_tracer_provider(TracerProvider())
3633
3734
# Instrument Botocore
38-
BotocoreInstrumentor().instrument(
39-
tracer_provider=trace.get_tracer_provider()
40-
)
35+
BotocoreInstrumentor().instrument()
4136
4237
# This will create a span with Botocore-specific attributes
4338
session = botocore.session.get_session()
@@ -56,6 +51,8 @@
5651
from botocore.client import BaseClient
5752
from wrapt import ObjectProxy, wrap_function_wrapper
5853

54+
from opentelemetry import context as context_api
55+
from opentelemetry import propagators
5956
from opentelemetry.instrumentation.botocore.version import __version__
6057
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
6158
from opentelemetry.sdk.trace import Resource
@@ -64,6 +61,14 @@
6461
logger = logging.getLogger(__name__)
6562

6663

64+
# pylint: disable=unused-argument
65+
def _patched_endpoint_prepare_request(wrapped, instance, args, kwargs):
66+
request = args[0]
67+
headers = request.headers
68+
propagators.inject(type(headers).__setitem__, headers)
69+
return wrapped(*args, **kwargs)
70+
71+
6772
class BotocoreInstrumentor(BaseInstrumentor):
6873
"""A instrumentor for Botocore
6974
@@ -85,10 +90,18 @@ def _instrument(self, **kwargs):
8590
self._patched_api_call,
8691
)
8792

93+
wrap_function_wrapper(
94+
"botocore.endpoint",
95+
"Endpoint.prepare_request",
96+
_patched_endpoint_prepare_request,
97+
)
98+
8899
def _uninstrument(self, **kwargs):
89100
unwrap(BaseClient, "_make_api_call")
90101

91102
def _patched_api_call(self, original_func, instance, args, kwargs):
103+
if context_api.get_value("suppress_instrumentation"):
104+
return original_func(*args, **kwargs)
92105

93106
endpoint_name = deep_getattr(instance, "_endpoint._endpoint_prefix")
94107

Diff for: instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py

+70
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,14 @@
2323
mock_lambda,
2424
mock_s3,
2525
mock_sqs,
26+
mock_xray,
2627
)
2728

29+
from opentelemetry import propagators
30+
from opentelemetry.context import attach, detach, set_value
2831
from opentelemetry.instrumentation.botocore import BotocoreInstrumentor
2932
from opentelemetry.sdk.resources import Resource
33+
from opentelemetry.test.mock_textmap import MockTextMapPropagator
3034
from opentelemetry.test.test_base import TestBase
3135

3236

@@ -275,3 +279,69 @@ def test_kms_client(self):
275279

276280
# checking for protection on sts against security leak
277281
self.assertTrue("params" not in span.attributes.keys())
282+
283+
@mock_ec2
284+
def test_propagator_injects_into_request(self):
285+
headers = {}
286+
previous_propagator = propagators.get_global_textmap()
287+
288+
def check_headers(**kwargs):
289+
nonlocal headers
290+
headers = kwargs["request"].headers
291+
292+
try:
293+
propagators.set_global_textmap(MockTextMapPropagator())
294+
295+
ec2 = self.session.create_client("ec2", region_name="us-west-2")
296+
ec2.meta.events.register_first(
297+
"before-send.ec2.DescribeInstances", check_headers
298+
)
299+
ec2.describe_instances()
300+
301+
spans = self.memory_exporter.get_finished_spans()
302+
assert spans
303+
span = spans[0]
304+
self.assertEqual(len(spans), 1)
305+
self.assertEqual(span.attributes["aws.agent"], "botocore")
306+
self.assertEqual(span.attributes["aws.region"], "us-west-2")
307+
self.assertEqual(
308+
span.attributes["aws.operation"], "DescribeInstances"
309+
)
310+
assert_span_http_status_code(span, 200)
311+
self.assertEqual(
312+
span.resource,
313+
Resource(
314+
attributes={
315+
"endpoint": "ec2",
316+
"operation": "describeinstances",
317+
}
318+
),
319+
)
320+
self.assertEqual(span.name, "ec2.command")
321+
322+
self.assertIn(MockTextMapPropagator.TRACE_ID_KEY, headers)
323+
self.assertEqual(
324+
str(span.get_span_context().trace_id),
325+
headers[MockTextMapPropagator.TRACE_ID_KEY],
326+
)
327+
self.assertIn(MockTextMapPropagator.SPAN_ID_KEY, headers)
328+
self.assertEqual(
329+
str(span.get_span_context().span_id),
330+
headers[MockTextMapPropagator.SPAN_ID_KEY],
331+
)
332+
333+
finally:
334+
propagators.set_global_textmap(previous_propagator)
335+
336+
@mock_xray
337+
def test_suppress_instrumentation_xray_client(self):
338+
xray_client = self.session.create_client(
339+
"xray", region_name="us-east-1"
340+
)
341+
token = attach(set_value("suppress_instrumentation", True))
342+
xray_client.put_trace_segments(TraceSegmentDocuments=["str1"])
343+
xray_client.put_trace_segments(TraceSegmentDocuments=["str2"])
344+
detach(token)
345+
346+
spans = self.memory_exporter.get_finished_spans()
347+
self.assertEqual(0, len(spans))

Diff for: instrumentation/opentelemetry-instrumentation-celery/src/opentelemetry/instrumentation/celery/__init__.py

-6
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,13 @@
3030
3131
.. code:: python
3232
33-
from opentelemetry import trace
34-
from opentelemetry.sdk.trace import TracerProvider
35-
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor
3633
from opentelemetry.instrumentation.celery import CeleryInstrumentor
3734
3835
from celery import Celery
3936
from celery.signals import worker_process_init
4037
4138
@worker_process_init.connect(weak=False)
4239
def init_celery_tracing(*args, **kwargs):
43-
trace.set_tracer_provider(TracerProvider())
44-
span_processor = BatchExportSpanProcessor(ConsoleSpanExporter())
45-
trace.get_tracer_provider().add_span_processor(span_processor)
4640
CeleryInstrumentor().instrument()
4741
4842
app = Celery("tasks", broker="amqp://localhost")

Diff for: instrumentation/opentelemetry-instrumentation-dbapi/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## Unreleased
44

5+
Stop capturing query parameters by default
6+
([#156](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/156))
7+
58
## Version 0.13b0
69

710
Released 2020-09-17

Diff for: instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py

+13-5
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,8 @@
2525
import mysql.connector
2626
import pyodbc
2727
28-
from opentelemetry import trace
2928
from opentelemetry.instrumentation.dbapi import trace_integration
30-
from opentelemetry.trace import TracerProvider
3129
32-
trace.set_tracer_provider(TracerProvider())
3330
3431
# Ex: mysql.connector
3532
trace_integration(mysql.connector, "connect", "mysql", "sql")
@@ -62,6 +59,7 @@ def trace_integration(
6259
database_type: str = "",
6360
connection_attributes: typing.Dict = None,
6461
tracer_provider: typing.Optional[TracerProvider] = None,
62+
capture_parameters: bool = False,
6563
):
6664
"""Integrate with DB API library.
6765
https://www.python.org/dev/peps/pep-0249/
@@ -76,6 +74,7 @@ def trace_integration(
7674
user in Connection object.
7775
tracer_provider: The :class:`opentelemetry.trace.TracerProvider` to
7876
use. If ommited the current configured one is used.
77+
capture_parameters: Configure if db.statement.parameters should be captured.
7978
"""
8079
wrap_connect(
8180
__name__,
@@ -86,6 +85,7 @@ def trace_integration(
8685
connection_attributes,
8786
version=__version__,
8887
tracer_provider=tracer_provider,
88+
capture_parameters=capture_parameters,
8989
)
9090

9191

@@ -98,6 +98,7 @@ def wrap_connect(
9898
connection_attributes: typing.Dict = None,
9999
version: str = "",
100100
tracer_provider: typing.Optional[TracerProvider] = None,
101+
capture_parameters: bool = False,
101102
):
102103
"""Integrate with DB API library.
103104
https://www.python.org/dev/peps/pep-0249/
@@ -111,6 +112,8 @@ def wrap_connect(
111112
database_type: The Database type. For any SQL database, "sql".
112113
connection_attributes: Attribute names for database, port, host and
113114
user in Connection object.
115+
capture_parameters: Configure if db.statement.parameters should be captured.
116+
114117
"""
115118

116119
# pylint: disable=unused-argument
@@ -127,6 +130,7 @@ def wrap_connect_(
127130
connection_attributes=connection_attributes,
128131
version=version,
129132
tracer_provider=tracer_provider,
133+
capture_parameters=capture_parameters,
130134
)
131135
return db_integration.wrapped_connection(wrapped, args, kwargs)
132136

@@ -159,6 +163,7 @@ def instrument_connection(
159163
connection_attributes: typing.Dict = None,
160164
version: str = "",
161165
tracer_provider: typing.Optional[TracerProvider] = None,
166+
capture_parameters=False,
162167
):
163168
"""Enable instrumentation in a database connection.
164169
@@ -170,7 +175,7 @@ def instrument_connection(
170175
database_type: The Database type. For any SQL database, "sql".
171176
connection_attributes: Attribute names for database, port, host and
172177
user in a connection object.
173-
178+
capture_parameters: Configure if db.statement.parameters should be captured.
174179
Returns:
175180
An instrumented connection.
176181
"""
@@ -181,6 +186,7 @@ def instrument_connection(
181186
connection_attributes=connection_attributes,
182187
version=version,
183188
tracer_provider=tracer_provider,
189+
capture_parameters=capture_parameters,
184190
)
185191
db_integration.get_connection_attributes(connection)
186192
return get_traced_connection_proxy(connection, db_integration)
@@ -211,6 +217,7 @@ def __init__(
211217
connection_attributes=None,
212218
version: str = "",
213219
tracer_provider: typing.Optional[TracerProvider] = None,
220+
capture_parameters: bool = False,
214221
):
215222
self.connection_attributes = connection_attributes
216223
if self.connection_attributes is None:
@@ -223,6 +230,7 @@ def __init__(
223230
self._name = name
224231
self._version = version
225232
self._tracer_provider = tracer_provider
233+
self.capture_parameters = capture_parameters
226234
self.database_component = database_component
227235
self.database_type = database_type
228236
self.connection_props = {}
@@ -327,7 +335,7 @@ def _populate_span(
327335
) in self._db_api_integration.span_attributes.items():
328336
span.set_attribute(attribute_key, attribute_value)
329337

330-
if len(args) > 1:
338+
if self._db_api_integration.capture_parameters and len(args) > 1:
331339
span.set_attribute("db.statement.parameters", str(args[1]))
332340

333341
def traced_execution(

0 commit comments

Comments
 (0)