Skip to content

Commit b0d3ac1

Browse files
authored
Merge branch 'main' into issue-1747
2 parents 49b65c5 + 2edcc21 commit b0d3ac1

File tree

21 files changed

+706
-63
lines changed

21 files changed

+706
-63
lines changed

.github/CODEOWNERS

+7-21
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,12 @@
1-
# Code owners file.
2-
# This file controls who is tagged for review for any given pull request.
3-
#
4-
# What is a "CODEOWNER"?
5-
#
6-
# A CODEOWNER lends their expertise to a specific package hosted by an OpenTelemetry repository.
7-
#
8-
# A CODEOWNER MUST:
9-
# - introduce themselves on the CNCF OTel Python channel: https://cloud-native.slack.com/archives/C01PD4HUVBL
10-
# - have enough knowledge of the corresponding instrumented library
11-
# - respond to issues
12-
# - fix failing unit tests or any other blockers to the CI/CD workflow
13-
# - update usage of `opentelemetry-python-core` APIs upon the introduction of breaking changes
14-
# - be a member of the OpenTelemetry community so that the `component-owners.yml` action to automatically assign CODEOWNERS to PRs works correctly.
15-
#
1+
# This file is only used as a way to assign any change to the approvers team
2+
# except for a change in any of the instrumentations. The actual codeowners
3+
# of the instrumentations are in .github/component_owners.yml.
164

17-
18-
# For anything not explicitly taken by someone else:
5+
# Assigns any change to the approvers team...
196
* @open-telemetry/opentelemetry-python-contrib-approvers
207

8+
# ...except for changes in any instrumentation.
9+
/instrumentation
10+
2111
# Learn about CODEOWNERS file format:
2212
# https://help.github.com/en/articles/about-code-owners
23-
#
24-
# Learn about membership in OpenTelemetry community:
25-
# https://github.com/open-telemetry/community/blob/main/community-membership.md
26-
#

.github/component_owners.yml

+14
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,23 @@ components:
4343

4444
instrumentation/opentelemetry-instrumentation-urllib:
4545
- shalevr
46+
- ocelotl
4647

4748
instrumentation/opentelemetry-instrumentation-urllib3:
4849
- shalevr
50+
- ocelotl
4951

5052
instrumentation/opentelemetry-instrumentation-sqlalchemy:
5153
- shalevr
54+
55+
instrumentation/opentelemetry-instrumentation-flask:
56+
- ocelotl
57+
58+
instrumentation/opentelemetry-instrumentation-jinja2:
59+
- ocelotl
60+
61+
instrumentation/opentelemetry-instrumentation-logging:
62+
- ocelotl
63+
64+
instrumentation/opentelemetry-instrumentation-requests:
65+
- ocelotl

.github/workflows/test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
fail-fast: false # ensures the entire test matrix is run, even if one permutation fails
2525
matrix:
2626
python-version: [ py37, py38, py39, py310, py311, pypy3 ]
27-
package: ["instrumentation", "distro", "exporter", "sdkextension", "propagator"]
27+
package: ["instrumentation", "distro", "exporter", "sdkextension", "propagator", "resource"]
2828
os: [ ubuntu-20.04 ]
2929
steps:
3030
- name: Checkout Contrib Repo @ SHA - ${{ github.sha }}

CHANGELOG.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
### Added
11+
- `opentelemetry-instrumentation-kafka-python` Add instrumentation to `consume` method
12+
([#1786](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1786))
13+
1014
## Version 1.18.0/0.39b0 (2023-05-10)
1115

1216
- `opentelemetry-instrumentation-system-metrics` Add `process.` prefix to `runtime.memory`, `runtime.cpu.time`, and `runtime.gc_count`. Change `runtime.memory` from count to UpDownCounter. ([#1735](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1735))
@@ -29,8 +33,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2933
([#1407](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1407))
3034
- `opentelemetry-instrumentation-logging` Add `otelTraceSampled` to instrumetation-logging
3135
([#1773](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1773))
32-
- `opentelemetry-instrumentation-kafka-python` Add instrumentation to `consume` method
33-
([#1786](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1786))
36+
37+
### Changed
38+
39+
- `opentelemetry-instrumentation-botocore` now uses the AWS X-Ray propagator by
40+
default
41+
([#1741](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1741))
3442

3543
### Fixed
3644

@@ -128,6 +136,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
128136

129137
### Added
130138

139+
- `opentelemetry-resource-detector-container` Add support resource detection of container properties.
140+
([#1584](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1584))
131141
- `opentelemetry-instrumentation-pymysql` Add tests for commit() and rollback().
132142
([#1424](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1424))
133143
- `opentelemetry-instrumentation-fastapi` Add support for regular expression matching and sanitization of HTTP headers.

CONTRIBUTING.md

+11
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,17 @@ Open a pull request against the main `opentelemetry-python-contrib` repo.
124124
as `work-in-progress`, or mark it as [`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/).
125125
* Make sure CLA is signed and CI is clear.
126126

127+
### How to Get PRs Reviewed
128+
129+
The maintainers and approvers of this repo are not experts in every instrumentation there is here.
130+
In fact each one of us knows enough about them to only review a few. Unfortunately it can be hard
131+
to find enough experts in every instrumentation to quickly review every instrumentation PR. The
132+
instrumentation experts are listed in `.github/component_owners.yml` with their corresponding files
133+
or directories that they own. The owners listed there will be notified when PRs that modify their
134+
files are opened.
135+
136+
If you are not getting reviews, please contact the respective owners directly.
137+
127138
### How to Get PRs Merged
128139

129140
A PR is considered to be **ready to merge** when:

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,13 @@ Meeting notes are available as a public [Google doc](https://docs.google.com/doc
9595
Approvers ([@open-telemetry/python-approvers](https://github.com/orgs/open-telemetry/teams/python-approvers)):
9696

9797
- [Aaron Abbott](https://github.com/aabmass), Google
98+
- [Jeremy Voss](https://github.com/jeremydvoss), Microsoft
9899
- [Sanket Mehta](https://github.com/sanketmehta28), Cisco
99100
- [Shalev Roda](https://github.com/shalevr), Cisco
100101

101102
Emeritus Approvers:
102103

103-
- [Hector Hernandez](https://github.com/hectorhdzg), Microsoft
104+
- [Héctor Hernández](https://github.com/hectorhdzg), Microsoft
104105
- [Yusuke Tsutsumi](https://github.com/toumorokoshi), Google
105106
- [Nathaniel Ruiz Nowell](https://github.com/NathanielRN), AWS
106107
- [Ashutosh Goel](https://github.com/ashu658), Cisco
@@ -111,12 +112,12 @@ Maintainers ([@open-telemetry/python-maintainers](https://github.com/orgs/open-t
111112

112113
- [Diego Hurtado](https://github.com/ocelotl), Lightstep
113114
- [Leighton Chen](https://github.com/lzchen), Microsoft
114-
- [Srikanth Chekuri](https://github.com/srikanthccv), signoz.io
115115

116116
Emeritus Maintainers:
117117

118118
- [Alex Boten](https://github.com/codeboten), Lightstep
119119
- [Owais Lone](https://github.com/owais), Splunk
120+
- [Srikanth Chekuri](https://github.com/srikanthccv), signoz.io
120121

121122
*Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer).*
122123

docs/conf.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@
5454
if isdir(join(sdk_ext, f))
5555
]
5656

57-
sys.path[:0] = exp_dirs + instr_dirs + sdk_ext_dirs + prop_dirs
57+
resource = "../resource"
58+
resource_dirs = [
59+
os.path.abspath("/".join(["../resource", f, "src"]))
60+
for f in listdir(resource)
61+
if isdir(join(resource, f))
62+
]
63+
sys.path[:0] = exp_dirs + instr_dirs + sdk_ext_dirs + prop_dirs + resource_dirs
5864

5965
# -- Project information -----------------------------------------------------
6066

docs/index.rst

+10-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Extensions
3333

3434
Visit `OpenTelemetry Registry <https://opentelemetry.io/registry/?s=python>`_ to
3535
find a lot of related projects like exporters, instrumentation libraries, tracer
36-
implementations, etc.
36+
implementations, resource, etc.
3737

3838
Installing Cutting Edge Packages
3939
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -51,6 +51,7 @@ install <https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs>
5151
pip install -e ./instrumentation/opentelemetry-instrumentation-flask
5252
pip install -e ./instrumentation/opentelemetry-instrumentation-botocore
5353
pip install -e ./sdk-extension/opentelemetry-sdk-extension-aws
54+
pip install -e ./resource/opentelemetry-resource-detector-container
5455
5556
5657
.. toctree::
@@ -85,6 +86,14 @@ install <https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs>
8586

8687
sdk-extension/**
8788

89+
.. toctree::
90+
:maxdepth: 2
91+
:caption: OpenTelemetry Resource Detectors
92+
:name: Resource Detectors
93+
:glob:
94+
95+
resource/**
96+
8897
Indices and tables
8998
------------------
9099

docs/resource/container/container.rst

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
OpenTelemetry Python - Resource Detector for Containers
2+
=======================================================
3+
4+
.. automodule:: opentelemetry.resource.detector.container
5+
:members:
6+
:undoc-members:
7+
:show-inheritance:

instrumentation/opentelemetry-instrumentation-botocore/pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ dependencies = [
2828
"opentelemetry-api ~= 1.12",
2929
"opentelemetry-instrumentation == 0.40b0.dev",
3030
"opentelemetry-semantic-conventions == 0.40b0.dev",
31+
"opentelemetry-propagator-aws-xray == 1.0.1",
3132
]
3233

3334
[project.optional-dependencies]

instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/__init__.py

+20-10
Original file line numberDiff line numberDiff line change
@@ -101,22 +101,14 @@ def response_hook(span, service_name, operation_name, result):
101101
_SUPPRESS_INSTRUMENTATION_KEY,
102102
unwrap,
103103
)
104-
from opentelemetry.propagate import inject
104+
from opentelemetry.propagators.aws.aws_xray_propagator import AwsXRayPropagator
105105
from opentelemetry.semconv.trace import SpanAttributes
106106
from opentelemetry.trace import get_tracer
107107
from opentelemetry.trace.span import Span
108108

109109
logger = logging.getLogger(__name__)
110110

111111

112-
# pylint: disable=unused-argument
113-
def _patched_endpoint_prepare_request(wrapped, instance, args, kwargs):
114-
request = args[0]
115-
headers = request.headers
116-
inject(headers)
117-
return wrapped(*args, **kwargs)
118-
119-
120112
class BotocoreInstrumentor(BaseInstrumentor):
121113
"""An instrumentor for Botocore.
122114
@@ -127,6 +119,7 @@ def __init__(self):
127119
super().__init__()
128120
self.request_hook = None
129121
self.response_hook = None
122+
self.propagator = AwsXRayPropagator()
130123

131124
def instrumentation_dependencies(self) -> Collection[str]:
132125
return _instruments
@@ -140,6 +133,10 @@ def _instrument(self, **kwargs):
140133
self.request_hook = kwargs.get("request_hook")
141134
self.response_hook = kwargs.get("response_hook")
142135

136+
propagator = kwargs.get("propagator")
137+
if propagator is not None:
138+
self.propagator = propagator
139+
143140
wrap_function_wrapper(
144141
"botocore.client",
145142
"BaseClient._make_api_call",
@@ -149,13 +146,26 @@ def _instrument(self, **kwargs):
149146
wrap_function_wrapper(
150147
"botocore.endpoint",
151148
"Endpoint.prepare_request",
152-
_patched_endpoint_prepare_request,
149+
self._patched_endpoint_prepare_request,
153150
)
154151

155152
def _uninstrument(self, **kwargs):
156153
unwrap(BaseClient, "_make_api_call")
157154
unwrap(Endpoint, "prepare_request")
158155

156+
# pylint: disable=unused-argument
157+
def _patched_endpoint_prepare_request(
158+
self, wrapped, instance, args, kwargs
159+
):
160+
request = args[0]
161+
headers = request.headers
162+
163+
# Only the x-ray header is propagated by AWS services. Using any
164+
# other propagator will lose the trace context.
165+
self.propagator.inject(headers)
166+
167+
return wrapped(*args, **kwargs)
168+
159169
# pylint: disable=too-many-branches
160170
def _patched_api_call(self, original_func, instance, args, kwargs):
161171
if context_api.get_value(_SUPPRESS_INSTRUMENTATION_KEY):

instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py

+42-24
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,11 @@
3636
from opentelemetry.instrumentation.botocore import BotocoreInstrumentor
3737
from opentelemetry.instrumentation.utils import _SUPPRESS_INSTRUMENTATION_KEY
3838
from opentelemetry.propagate import get_global_textmap, set_global_textmap
39+
from opentelemetry.propagators.aws.aws_xray_propagator import TRACE_HEADER_KEY
3940
from opentelemetry.semconv.trace import SpanAttributes
4041
from opentelemetry.test.mock_textmap import MockTextMapPropagator
4142
from opentelemetry.test.test_base import TestBase
43+
from opentelemetry.trace.span import format_span_id, format_trace_id
4244

4345
_REQUEST_ID_REGEX_MATCH = r"[A-Z0-9]{52}"
4446

@@ -225,27 +227,21 @@ def test_unpatch(self):
225227
@mock_ec2
226228
def test_uninstrument_does_not_inject_headers(self):
227229
headers = {}
228-
previous_propagator = get_global_textmap()
229-
try:
230-
set_global_textmap(MockTextMapPropagator())
231230

232-
def intercept_headers(**kwargs):
233-
headers.update(kwargs["request"].headers)
231+
def intercept_headers(**kwargs):
232+
headers.update(kwargs["request"].headers)
234233

235-
ec2 = self._make_client("ec2")
234+
ec2 = self._make_client("ec2")
236235

237-
BotocoreInstrumentor().uninstrument()
236+
BotocoreInstrumentor().uninstrument()
238237

239-
ec2.meta.events.register_first(
240-
"before-send.ec2.DescribeInstances", intercept_headers
241-
)
242-
with self.tracer_provider.get_tracer("test").start_span("parent"):
243-
ec2.describe_instances()
238+
ec2.meta.events.register_first(
239+
"before-send.ec2.DescribeInstances", intercept_headers
240+
)
241+
with self.tracer_provider.get_tracer("test").start_span("parent"):
242+
ec2.describe_instances()
244243

245-
self.assertNotIn(MockTextMapPropagator.TRACE_ID_KEY, headers)
246-
self.assertNotIn(MockTextMapPropagator.SPAN_ID_KEY, headers)
247-
finally:
248-
set_global_textmap(previous_propagator)
244+
self.assertNotIn(TRACE_HEADER_KEY, headers)
249245

250246
@mock_sqs
251247
def test_double_patch(self):
@@ -306,20 +302,42 @@ def check_headers(**kwargs):
306302
"EC2", "DescribeInstances", request_id=request_id
307303
)
308304

309-
self.assertIn(MockTextMapPropagator.TRACE_ID_KEY, headers)
310-
self.assertEqual(
311-
str(span.get_span_context().trace_id),
312-
headers[MockTextMapPropagator.TRACE_ID_KEY],
305+
# only x-ray propagation is used in HTTP requests
306+
self.assertIn(TRACE_HEADER_KEY, headers)
307+
xray_context = headers[TRACE_HEADER_KEY]
308+
formated_trace_id = format_trace_id(
309+
span.get_span_context().trace_id
313310
)
314-
self.assertIn(MockTextMapPropagator.SPAN_ID_KEY, headers)
315-
self.assertEqual(
316-
str(span.get_span_context().span_id),
317-
headers[MockTextMapPropagator.SPAN_ID_KEY],
311+
formated_trace_id = (
312+
formated_trace_id[:8] + "-" + formated_trace_id[8:]
318313
)
319314

315+
self.assertEqual(
316+
xray_context.lower(),
317+
f"root=1-{formated_trace_id};parent={format_span_id(span.get_span_context().span_id)};sampled=1".lower(),
318+
)
320319
finally:
321320
set_global_textmap(previous_propagator)
322321

322+
@mock_ec2
323+
def test_override_xray_propagator_injects_into_request(self):
324+
headers = {}
325+
326+
def check_headers(**kwargs):
327+
nonlocal headers
328+
headers = kwargs["request"].headers
329+
330+
BotocoreInstrumentor().instrument()
331+
332+
ec2 = self._make_client("ec2")
333+
ec2.meta.events.register_first(
334+
"before-send.ec2.DescribeInstances", check_headers
335+
)
336+
ec2.describe_instances()
337+
338+
self.assertNotIn(MockTextMapPropagator.TRACE_ID_KEY, headers)
339+
self.assertNotIn(MockTextMapPropagator.SPAN_ID_KEY, headers)
340+
323341
@mock_xray
324342
def test_suppress_instrumentation_xray_client(self):
325343
xray_client = self._make_client("xray")

0 commit comments

Comments
 (0)