Skip to content

Commit

Permalink
Merge branch 'main' into HLS-3903
Browse files Browse the repository at this point in the history
  • Loading branch information
nozik committed Jun 1, 2023
2 parents 75b62a9 + a679754 commit 1515b47
Show file tree
Hide file tree
Showing 21 changed files with 700 additions and 60 deletions.
28 changes: 7 additions & 21 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,26 +1,12 @@
# Code owners file.
# This file controls who is tagged for review for any given pull request.
#
# What is a "CODEOWNER"?
#
# A CODEOWNER lends their expertise to a specific package hosted by an OpenTelemetry repository.
#
# A CODEOWNER MUST:
# - introduce themselves on the CNCF OTel Python channel: https://cloud-native.slack.com/archives/C01PD4HUVBL
# - have enough knowledge of the corresponding instrumented library
# - respond to issues
# - fix failing unit tests or any other blockers to the CI/CD workflow
# - update usage of `opentelemetry-python-core` APIs upon the introduction of breaking changes
# - be a member of the OpenTelemetry community so that the `component-owners.yml` action to automatically assign CODEOWNERS to PRs works correctly.
#
# This file is only used as a way to assign any change to the approvers team
# except for a change in any of the instrumentations. The actual codeowners
# of the instrumentations are in .github/component_owners.yml.


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

# ...except for changes in any instrumentation.
/instrumentation

# Learn about CODEOWNERS file format:
# https://help.github.com/en/articles/about-code-owners
#
# Learn about membership in OpenTelemetry community:
# https://github.com/open-telemetry/community/blob/main/community-membership.md
#
14 changes: 14 additions & 0 deletions .github/component_owners.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,23 @@ components:

instrumentation/opentelemetry-instrumentation-urllib:
- shalevr
- ocelotl

instrumentation/opentelemetry-instrumentation-urllib3:
- shalevr
- ocelotl

instrumentation/opentelemetry-instrumentation-sqlalchemy:
- shalevr

instrumentation/opentelemetry-instrumentation-flask:
- ocelotl

instrumentation/opentelemetry-instrumentation-jinja2:
- ocelotl

instrumentation/opentelemetry-instrumentation-logging:
- ocelotl

instrumentation/opentelemetry-instrumentation-requests:
- ocelotl
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
fail-fast: false # ensures the entire test matrix is run, even if one permutation fails
matrix:
python-version: [ py37, py38, py39, py310, py311, pypy3 ]
package: ["instrumentation", "distro", "exporter", "sdkextension", "propagator"]
package: ["instrumentation", "distro", "exporter", "sdkextension", "propagator", "resource"]
os: [ ubuntu-20.04 ]
steps:
- name: Checkout Contrib Repo @ SHA - ${{ github.sha }}
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `opentelemetry-instrumentation-logging` Add `otelTraceSampled` to instrumetation-logging
([#1773](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1773))

### Changed

- `opentelemetry-instrumentation-botocore` now uses the AWS X-Ray propagator by
default
([#1741](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1741))

### Fixed

Expand Down Expand Up @@ -129,6 +134,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- `opentelemetry-resource-detector-container` Add support resource detection of container properties.
([#1584](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1584))
- `opentelemetry-instrumentation-pymysql` Add tests for commit() and rollback().
([#1424](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1424))
- `opentelemetry-instrumentation-fastapi` Add support for regular expression matching and sanitization of HTTP headers.
Expand Down
11 changes: 11 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,17 @@ Open a pull request against the main `opentelemetry-python-contrib` repo.
as `work-in-progress`, or mark it as [`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/).
* Make sure CLA is signed and CI is clear.

### How to Get PRs Reviewed

The maintainers and approvers of this repo are not experts in every instrumentation there is here.
In fact each one of us knows enough about them to only review a few. Unfortunately it can be hard
to find enough experts in every instrumentation to quickly review every instrumentation PR. The
instrumentation experts are listed in `.github/component_owners.yml` with their corresponding files
or directories that they own. The owners listed there will be notified when PRs that modify their
files are opened.

If you are not getting reviews, please contact the respective owners directly.

### How to Get PRs Merged

A PR is considered to be **ready to merge** when:
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,13 @@ Meeting notes are available as a public [Google doc](https://docs.google.com/doc
Approvers ([@open-telemetry/python-approvers](https://github.com/orgs/open-telemetry/teams/python-approvers)):

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

Emeritus Approvers:

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

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

Emeritus Maintainers:

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

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

Expand Down
8 changes: 7 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@
if isdir(join(sdk_ext, f))
]

sys.path[:0] = exp_dirs + instr_dirs + sdk_ext_dirs + prop_dirs
resource = "../resource"
resource_dirs = [
os.path.abspath("/".join(["../resource", f, "src"]))
for f in listdir(resource)
if isdir(join(resource, f))
]
sys.path[:0] = exp_dirs + instr_dirs + sdk_ext_dirs + prop_dirs + resource_dirs

# -- Project information -----------------------------------------------------

Expand Down
11 changes: 10 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Extensions

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

Installing Cutting Edge Packages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -51,6 +51,7 @@ install <https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs>
pip install -e ./instrumentation/opentelemetry-instrumentation-flask
pip install -e ./instrumentation/opentelemetry-instrumentation-botocore
pip install -e ./sdk-extension/opentelemetry-sdk-extension-aws
pip install -e ./resource/opentelemetry-resource-detector-container
.. toctree::
Expand Down Expand Up @@ -85,6 +86,14 @@ install <https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs>

sdk-extension/**

.. toctree::
:maxdepth: 2
:caption: OpenTelemetry Resource Detectors
:name: Resource Detectors
:glob:

resource/**

Indices and tables
------------------

Expand Down
7 changes: 7 additions & 0 deletions docs/resource/container/container.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
OpenTelemetry Python - Resource Detector for Containers
=======================================================

.. automodule:: opentelemetry.resource.detector.container
:members:
:undoc-members:
:show-inheritance:
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ dependencies = [
"opentelemetry-api ~= 1.12",
"opentelemetry-instrumentation == 0.40b0.dev",
"opentelemetry-semantic-conventions == 0.40b0.dev",
"opentelemetry-propagator-aws-xray == 1.0.1",
]

[project.optional-dependencies]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,22 +101,14 @@ def response_hook(span, service_name, operation_name, result):
_SUPPRESS_INSTRUMENTATION_KEY,
unwrap,
)
from opentelemetry.propagate import inject
from opentelemetry.propagators.aws.aws_xray_propagator import AwsXRayPropagator
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.trace import get_tracer
from opentelemetry.trace.span import Span

logger = logging.getLogger(__name__)


# pylint: disable=unused-argument
def _patched_endpoint_prepare_request(wrapped, instance, args, kwargs):
request = args[0]
headers = request.headers
inject(headers)
return wrapped(*args, **kwargs)


class BotocoreInstrumentor(BaseInstrumentor):
"""An instrumentor for Botocore.
Expand All @@ -127,6 +119,7 @@ def __init__(self):
super().__init__()
self.request_hook = None
self.response_hook = None
self.propagator = AwsXRayPropagator()

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

propagator = kwargs.get("propagator")
if propagator is not None:
self.propagator = propagator

wrap_function_wrapper(
"botocore.client",
"BaseClient._make_api_call",
Expand All @@ -149,13 +146,26 @@ def _instrument(self, **kwargs):
wrap_function_wrapper(
"botocore.endpoint",
"Endpoint.prepare_request",
_patched_endpoint_prepare_request,
self._patched_endpoint_prepare_request,
)

def _uninstrument(self, **kwargs):
unwrap(BaseClient, "_make_api_call")
unwrap(Endpoint, "prepare_request")

# pylint: disable=unused-argument
def _patched_endpoint_prepare_request(
self, wrapped, instance, args, kwargs
):
request = args[0]
headers = request.headers

# Only the x-ray header is propagated by AWS services. Using any
# other propagator will lose the trace context.
self.propagator.inject(headers)

return wrapped(*args, **kwargs)

# pylint: disable=too-many-branches
def _patched_api_call(self, original_func, instance, args, kwargs):
if context_api.get_value(_SUPPRESS_INSTRUMENTATION_KEY):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@
from opentelemetry.instrumentation.botocore import BotocoreInstrumentor
from opentelemetry.instrumentation.utils import _SUPPRESS_INSTRUMENTATION_KEY
from opentelemetry.propagate import get_global_textmap, set_global_textmap
from opentelemetry.propagators.aws.aws_xray_propagator import TRACE_HEADER_KEY
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.test.mock_textmap import MockTextMapPropagator
from opentelemetry.test.test_base import TestBase
from opentelemetry.trace.span import format_span_id, format_trace_id

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

Expand Down Expand Up @@ -225,27 +227,21 @@ def test_unpatch(self):
@mock_ec2
def test_uninstrument_does_not_inject_headers(self):
headers = {}
previous_propagator = get_global_textmap()
try:
set_global_textmap(MockTextMapPropagator())

def intercept_headers(**kwargs):
headers.update(kwargs["request"].headers)
def intercept_headers(**kwargs):
headers.update(kwargs["request"].headers)

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

BotocoreInstrumentor().uninstrument()
BotocoreInstrumentor().uninstrument()

ec2.meta.events.register_first(
"before-send.ec2.DescribeInstances", intercept_headers
)
with self.tracer_provider.get_tracer("test").start_span("parent"):
ec2.describe_instances()
ec2.meta.events.register_first(
"before-send.ec2.DescribeInstances", intercept_headers
)
with self.tracer_provider.get_tracer("test").start_span("parent"):
ec2.describe_instances()

self.assertNotIn(MockTextMapPropagator.TRACE_ID_KEY, headers)
self.assertNotIn(MockTextMapPropagator.SPAN_ID_KEY, headers)
finally:
set_global_textmap(previous_propagator)
self.assertNotIn(TRACE_HEADER_KEY, headers)

@mock_sqs
def test_double_patch(self):
Expand Down Expand Up @@ -306,20 +302,42 @@ def check_headers(**kwargs):
"EC2", "DescribeInstances", request_id=request_id
)

self.assertIn(MockTextMapPropagator.TRACE_ID_KEY, headers)
self.assertEqual(
str(span.get_span_context().trace_id),
headers[MockTextMapPropagator.TRACE_ID_KEY],
# only x-ray propagation is used in HTTP requests
self.assertIn(TRACE_HEADER_KEY, headers)
xray_context = headers[TRACE_HEADER_KEY]
formated_trace_id = format_trace_id(
span.get_span_context().trace_id
)
self.assertIn(MockTextMapPropagator.SPAN_ID_KEY, headers)
self.assertEqual(
str(span.get_span_context().span_id),
headers[MockTextMapPropagator.SPAN_ID_KEY],
formated_trace_id = (
formated_trace_id[:8] + "-" + formated_trace_id[8:]
)

self.assertEqual(
xray_context.lower(),
f"root=1-{formated_trace_id};parent={format_span_id(span.get_span_context().span_id)};sampled=1".lower(),
)
finally:
set_global_textmap(previous_propagator)

@mock_ec2
def test_override_xray_propagator_injects_into_request(self):
headers = {}

def check_headers(**kwargs):
nonlocal headers
headers = kwargs["request"].headers

BotocoreInstrumentor().instrument()

ec2 = self._make_client("ec2")
ec2.meta.events.register_first(
"before-send.ec2.DescribeInstances", check_headers
)
ec2.describe_instances()

self.assertNotIn(MockTextMapPropagator.TRACE_ID_KEY, headers)
self.assertNotIn(MockTextMapPropagator.SPAN_ID_KEY, headers)

@mock_xray
def test_suppress_instrumentation_xray_client(self):
xray_client = self._make_client("xray")
Expand Down
Loading

0 comments on commit 1515b47

Please sign in to comment.