Skip to content

Commit da02e96

Browse files
committed
Merge branch 'main' into metrics-instrumentation-celery
2 parents 4f1a7b5 + 4a859e3 commit da02e96

File tree

36 files changed

+980
-464
lines changed

36 files changed

+980
-464
lines changed

.github/component_owners.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,6 @@ components:
4646

4747
instrumentation/opentelemetry-instrumentation-urllib3:
4848
- shalevr
49+
50+
instrumentation/opentelemetry-instrumentation-sqlalchemy:
51+
- shalevr

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ jobs:
125125
--title "Version ${STABLE_VERSION}/${UNSTABLE_VERSION}" \
126126
--notes-file /tmp/release-notes.txt \
127127
--discussion-category announcements \
128-
v$STABLE_VERSION
128+
v$UNSTABLE_VERSION
129129
130130
- uses: actions/checkout@v3
131131
with:

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
- 'release/*'
77
pull_request:
88
env:
9-
CORE_REPO_SHA: d0bb12b34b0c487198c935001636b6163485a50f
9+
CORE_REPO_SHA: 2d1f0b9f5fce62549d1338882f37b91b95881c75
1010

1111
jobs:
1212
build:

CHANGELOG.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
- Add metric instrumentation for celery
1111
([#1679](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1679))
12+
-
13+
- Add metrics instrumentation for sqlalchemy
14+
([#1645](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1645))
15+
16+
- Fix exception in Urllib3 when dealing with filelike body.
17+
([#1399](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1399))
18+
19+
### Added
20+
21+
- Add connection attributes to sqlalchemy connect span
22+
([#1608](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1608))
23+
- Add support for enabling Redis sanitization from environment variable
24+
([#1690](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1690))
25+
26+
### Fixed
27+
28+
- Fix Flask instrumentation to only close the span if it was created by the same thread.
29+
([#1654](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1654))
30+
- `opentelemetry-instrumentation-system-metrics` Fix initialization of the instrumentation class when configuration is provided
31+
([#1438](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1439))
32+
>>>>>>> main
1233
1334
## Version 1.16.0/0.37b0 (2023-02-17)
1435

1536
### Added
1637

1738
- Support `aio_pika` 9.x (([#1670](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1670])
1839
- `opentelemetry-instrumentation-redis` Add `sanitize_query` config option to allow query sanitization. ([#1572](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1572))
19-
- `opentelemetry-instrumentation-elasticsearch` Add optional db.statement query sanitization.
40+
- `opentelemetry-instrumentation-elasticsearch` Add optional db.statement query sanitization.
2041
([#1598](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1598))
2142
- `opentelemetry-instrumentation-celery` Record exceptions as events on the span.
2243
([#1573](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1573))

RELEASING.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Preparing a new major or minor release
44

5-
* Run the [Prepare release branch workflow](https://github.com/open-telemetry/opentelemetry-python/actions/workflows/prepare-release-branch.yml).
5+
* Run the [Prepare release branch workflow](https://github.com/open-telemetry/opentelemetry-python-contrib/actions/workflows/prepare-release-branch.yml).
66
* Press the "Run workflow" button, and leave the default branch `main` selected.
77
* If making a pre-release of stable components (e.g. release candidate),
88
enter the pre-release version number, e.g. `1.9.0rc2`.
@@ -13,21 +13,21 @@
1313
## Preparing a new patch release
1414

1515
* Backport pull request(s) to the release branch.
16-
* Run the [Backport workflow](https://github.com/open-telemetry/opentelemetry-python/actions/workflows/backport.yml).
16+
* Run the [Backport workflow](https://github.com/open-telemetry/opentelemetry-python-contrib/actions/workflows/backport.yml).
1717
* Press the "Run workflow" button, then select the release branch from the dropdown list,
1818
e.g. `release/v1.9.x`, then enter the pull request number that you want to backport,
1919
then click the "Run workflow" button below that.
2020
* Review and merge the backport pull request that it generates.
2121
* Merge a pull request to the release branch updating the `CHANGELOG.md`.
2222
* The heading for the unreleased entries should be `## Unreleased`.
23-
* Run the [Prepare patch release workflow](https://github.com/open-telemetry/opentelemetry-python/actions/workflows/prepare-patch-release.yml).
23+
* Run the [Prepare patch release workflow](https://github.com/open-telemetry/opentelemetry-python-contrib/actions/workflows/prepare-patch-release.yml).
2424
* Press the "Run workflow" button, then select the release branch from the dropdown list,
2525
e.g. `release/v1.9.x`, and click the "Run workflow" button below that.
2626
* Review and merge the pull request that it creates for updating the version.
2727

2828
## Making the release
2929

30-
* Run the [Release workflow](https://github.com/open-telemetry/opentelemetry-python/actions/workflows/release.yml).
30+
* Run the [Release workflow](https://github.com/open-telemetry/opentelemetry-python-contrib/actions/workflows/release.yml).
3131
* Press the "Run workflow" button, then select the release branch from the dropdown list,
3232
e.g. `release/v1.9.x`, and click the "Run workflow" button below that.
3333
* This workflow will publish the artifacts and publish a GitHub release with release notes based on the change log.
@@ -69,9 +69,9 @@
6969
## After the release
7070

7171
* Check PyPI
72-
* This should be handled automatically on release by the [publish action](https://github.com/open-telemetry/opentelemetry-python/blob/main/.github/workflows/publish.yml).
73-
* Check the [action logs](https://github.com/open-telemetry/opentelemetry-python/actions?query=workflow%3APublish) to make sure packages have been uploaded to PyPI
74-
* Check the release history (e.g. https://pypi.org/project/opentelemetry-api/#history) on PyPI
72+
* This should be handled automatically on release by the [publish action](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/.github/workflows/release.yml).
73+
* Check the [action logs](https://github.com/open-telemetry/opentelemetry-python-contrib/actions/workflows/release.yml) to make sure packages have been uploaded to PyPI
74+
* Check the release history (e.g. https://pypi.org/project/opentelemetry-instrumentation/#history) on PyPI
7575
* If for some reason the action failed, see [Publish failed](#publish-failed) below
7676
* Move stable tag
7777
* Run the following (TODO automate):

docs-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ aiopg>=0.13.0,<1.3.0
2424
asyncpg>=0.12.0
2525
boto~=2.0
2626
botocore~=1.0
27+
boto3~=1.0
2728
celery>=4.0
2829
confluent-kafka>= 1.8.2,< 2.0.0
2930
elasticsearch>=2.0,<9.0

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def getlistcfg(strval):
126126
]
127127

128128

129-
ignore_categories = ["py-class", "py-func", "py-exc", "any"]
129+
ignore_categories = ["py-class", "py-func", "py-exc", "py-obj", "any"]
130130

131131
for category in ignore_categories:
132132
if category in mcfg:
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.. include:: ../../../instrumentation/opentelemetry-instrumentation-boto3sqs/README.rst
2+
3+
.. automodule:: opentelemetry.instrumentation.boto3sqs
4+
:members:
5+
:undoc-members:
6+
:show-inheritance:

docs/nitpick-exceptions.ini

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ py-class=
1313
opentelemetry.sdk.trace.id_generator.IdGenerator
1414
opentelemetry.instrumentation.confluent_kafka.ProxiedProducer
1515
opentelemetry.instrumentation.confluent_kafka.ProxiedConsumer
16+
opentelemetry.instrumentation.instrumentor.BaseInstrumentor
1617
; - AwsXRayIdGenerator
1718
TextMapPropagator
1819
CarrierT
@@ -54,7 +55,16 @@ any=
5455
; - instrumentation.*
5556
Setter
5657
httpx
57-
;
58+
instrument
59+
__iter__
60+
list.__iter__
61+
__getitem__
62+
list.__getitem__
63+
SQS.ReceiveMessage
64+
65+
py-obj=
66+
opentelemetry.propagators.textmap.CarrierT
67+
5868
py-func=
5969
poll
6070
flush

exporter/opentelemetry-exporter-prometheus-remote-write/example/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ WORKDIR /code
66
COPY . .
77

88
RUN pip install -e .
9-
RUN pip install -r ./examples/requirements.txt
9+
RUN pip install -r ./example/requirements.txt
1010

11-
CMD ["python", "./examples/sampleapp.py"]
11+
CMD ["python", "./example/sampleapp.py"]

exporter/opentelemetry-exporter-prometheus-remote-write/example/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ data
1414
*Users do not need to install Python as the app will be run in the Docker Container*
1515

1616
## Instructions
17-
1. Run `docker-compose up -d` in the the `examples/` directory
17+
1. Run `docker-compose up -d` in the the `example/` directory
1818

1919
The `-d` flag causes all services to run in detached mode and frees up your
2020
terminal session. This also causes no logs to show up. Users can attach themselves to the service's logs manually using `docker logs ${CONTAINER_ID} --follow`
@@ -39,4 +39,4 @@ terminal session. This also causes no logs to show up. Users can attach themselv
3939
* Click the refresh button and data should show up on the graph
4040

4141
6. Shutdown the services when finished
42-
* Run `docker-compose down` in the examples directory
42+
* Run `docker-compose down` in the example directory

exporter/opentelemetry-exporter-prometheus-remote-write/example/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ services:
3030
sample_app:
3131
build:
3232
context: ../
33-
dockerfile: ./examples/Dockerfile
33+
dockerfile: ./example/Dockerfile

instrumentation/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
| [opentelemetry-instrumentation-remoulade](./opentelemetry-instrumentation-remoulade) | remoulade >= 0.50 | No
3535
| [opentelemetry-instrumentation-requests](./opentelemetry-instrumentation-requests) | requests ~= 2.0 | Yes
3636
| [opentelemetry-instrumentation-sklearn](./opentelemetry-instrumentation-sklearn) | scikit-learn ~= 0.24.0 | No
37-
| [opentelemetry-instrumentation-sqlalchemy](./opentelemetry-instrumentation-sqlalchemy) | sqlalchemy | No
37+
| [opentelemetry-instrumentation-sqlalchemy](./opentelemetry-instrumentation-sqlalchemy) | sqlalchemy | Yes
3838
| [opentelemetry-instrumentation-sqlite3](./opentelemetry-instrumentation-sqlite3) | sqlite3 | No
3939
| [opentelemetry-instrumentation-starlette](./opentelemetry-instrumentation-starlette) | starlette ~= 0.13.0 | Yes
4040
| [opentelemetry-instrumentation-system-metrics](./opentelemetry-instrumentation-system-metrics) | psutil >= 5 | No

instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424
# Copy this snippet into an AWS Lambda function
2525
2626
import boto3
27-
from opentelemetry.instrumentation.botocore import AwsBotocoreInstrumentor
27+
from opentelemetry.instrumentation.botocore import BotocoreInstrumentor
2828
from opentelemetry.instrumentation.aws_lambda import AwsLambdaInstrumentor
2929
3030
# Enable instrumentation
31-
AwsBotocoreInstrumentor().instrument()
31+
BotocoreInstrumentor().instrument()
3232
AwsLambdaInstrumentor().instrument()
3333
3434
# Lambda function

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@
1616
1717
.. _boto3sqs: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs.html
1818
19-
2019
Usage
2120
-----
2221
23-
.. code:: python
22+
.. code-block:: python
2423
2524
import boto3
2625
from opentelemetry.instrumentation.boto3sqs import Boto3SQSInstrumentor
2726
28-
2927
Boto3SQSInstrumentor().instrument()
28+
29+
---
3030
"""
3131
import logging
3232
from typing import Any, Collection, Dict, Generator, List, Mapping, Optional

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,8 @@ def response_hook(span: Span, status: str, response_headers: List):
238238
API
239239
---
240240
"""
241-
242241
from logging import getLogger
242+
from threading import get_ident
243243
from time import time_ns
244244
from timeit import default_timer
245245
from typing import Collection
@@ -265,6 +265,7 @@ def response_hook(span: Span, status: str, response_headers: List):
265265
_ENVIRON_STARTTIME_KEY = "opentelemetry-flask.starttime_key"
266266
_ENVIRON_SPAN_KEY = "opentelemetry-flask.span_key"
267267
_ENVIRON_ACTIVATION_KEY = "opentelemetry-flask.activation_key"
268+
_ENVIRON_THREAD_ID_KEY = "opentelemetry-flask.thread_id_key"
268269
_ENVIRON_TOKEN = "opentelemetry-flask.token"
269270

270271
_excluded_urls_from_env = get_excluded_urls("FLASK")
@@ -398,6 +399,7 @@ def _before_request():
398399
activation = trace.use_span(span, end_on_exit=True)
399400
activation.__enter__() # pylint: disable=E1101
400401
flask_request_environ[_ENVIRON_ACTIVATION_KEY] = activation
402+
flask_request_environ[_ENVIRON_THREAD_ID_KEY] = get_ident()
401403
flask_request_environ[_ENVIRON_SPAN_KEY] = span
402404
flask_request_environ[_ENVIRON_TOKEN] = token
403405

@@ -437,10 +439,17 @@ def _teardown_request(exc):
437439
return
438440

439441
activation = flask.request.environ.get(_ENVIRON_ACTIVATION_KEY)
440-
if not activation:
442+
thread_id = flask.request.environ.get(_ENVIRON_THREAD_ID_KEY)
443+
if not activation or thread_id != get_ident():
441444
# This request didn't start a span, maybe because it was created in
442445
# a way that doesn't run `before_request`, like when it is created
443446
# with `app.test_request_context`.
447+
#
448+
# Similarly, check the thread_id against the current thread to ensure
449+
# tear down only happens on the original thread. This situation can
450+
# arise if the original thread handling the request spawn children
451+
# threads and then uses something like copy_current_request_context
452+
# to copy the request context.
444453
return
445454
if exc is None:
446455
activation.__exit__(None, None, None)

instrumentation/opentelemetry-instrumentation-flask/tests/base_test.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from concurrent.futures import ThreadPoolExecutor, as_completed
16+
from random import randint
17+
1518
import flask
1619
from werkzeug.test import Client
1720
from werkzeug.wrappers import Response
@@ -34,6 +37,25 @@ def _sqlcommenter_endpoint():
3437
)
3538
return sqlcommenter_flask_values
3639

40+
@staticmethod
41+
def _multithreaded_endpoint(count):
42+
def do_random_stuff():
43+
@flask.copy_current_request_context
44+
def inner():
45+
return randint(0, 100)
46+
47+
return inner
48+
49+
executor = ThreadPoolExecutor(count)
50+
futures = []
51+
for _ in range(count):
52+
futures.append(executor.submit(do_random_stuff()))
53+
numbers = []
54+
for future in as_completed(futures):
55+
numbers.append(future.result())
56+
57+
return " ".join([str(i) for i in numbers])
58+
3759
@staticmethod
3860
def _custom_response_headers():
3961
resp = flask.Response("test response")
@@ -61,6 +83,7 @@ def excluded2_endpoint():
6183
# pylint: disable=no-member
6284
self.app.route("/hello/<int:helloid>")(self._hello_endpoint)
6385
self.app.route("/sqlcommenter")(self._sqlcommenter_endpoint)
86+
self.app.route("/multithreaded")(self._multithreaded_endpoint)
6487
self.app.route("/excluded/<int:helloid>")(self._hello_endpoint)
6588
self.app.route("/excluded")(excluded_endpoint)
6689
self.app.route("/excluded2")(excluded2_endpoint)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Copyright The OpenTelemetry Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import flask
16+
from werkzeug.test import Client
17+
from werkzeug.wrappers import Response
18+
19+
from opentelemetry.instrumentation.flask import FlaskInstrumentor
20+
from opentelemetry.test.wsgitestutil import WsgiTestBase
21+
22+
# pylint: disable=import-error
23+
from .base_test import InstrumentationTest
24+
25+
26+
class TestMultiThreading(InstrumentationTest, WsgiTestBase):
27+
def setUp(self):
28+
super().setUp()
29+
FlaskInstrumentor().instrument()
30+
self.app = flask.Flask(__name__)
31+
self._common_initialization()
32+
33+
def tearDown(self):
34+
super().tearDown()
35+
with self.disable_logging():
36+
FlaskInstrumentor().uninstrument()
37+
38+
def test_multithreaded(self):
39+
"""Test that instrumentation tear down does not blow up
40+
when the request thread spawn children threads and the request
41+
context is copied to the children threads
42+
"""
43+
self.app = flask.Flask(__name__)
44+
self.app.route("/multithreaded/<int:count>")(
45+
self._multithreaded_endpoint
46+
)
47+
client = Client(self.app, Response)
48+
count = 5
49+
resp = client.get(f"/multithreaded/{count}")
50+
self.assertEqual(200, resp.status_code)
51+
# Should return the specified number of random integers
52+
self.assertEqual(count, len(resp.text.split(" ")))

0 commit comments

Comments
 (0)