Skip to content

Commit b4277bf

Browse files
committed
Merge remote-tracking branch 'upstream/master' into tracer_provider_force_flush
2 parents 83bd36e + 2992950 commit b4277bf

File tree

113 files changed

+2966
-546
lines changed

Some content is hidden

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

113 files changed

+2966
-546
lines changed

.flake8

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ exclude =
1818
ext/opentelemetry-ext-jaeger/src/opentelemetry/ext/jaeger/gen/
1919
ext/opentelemetry-ext-jaeger/build/*
2020
docs/examples/opentelemetry-example-app/src/opentelemetry_example_app/grpc/gen/
21+
docs/examples/opentelemetry-example-app/build/*

.isort.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ multi_line_output=3
1515
skip=target
1616
skip_glob=**/gen/*,.venv*/*,venv*/*
1717
known_first_party=opentelemetry,opentelemetry_example_app
18-
known_third_party=psutil,pytest
18+
known_third_party=psutil,pytest,redis,redis_opentracing

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ language: python
55
cache: pip
66

77
python:
8+
- 'pypy3'
9+
- '3.8'
810
- '3.4'
911
- '3.5'
1012
- '3.6'
1113
- '3.7'
12-
- '3.8'
13-
- 'pypy3'
1414

1515
#matrix:
1616
# allow_failures:

dev-requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pylint~=2.3
1+
pylint==2.4.4
22
flake8~=3.7
33
isort~=4.3
44
black>=19.3b0,==19.*

docs/examples/basic_tracer/tests/test_tracer.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ def test_basic_tracer(self):
2525
(sys.executable, test_script)
2626
).decode()
2727

28-
self.assertIn('name="foo"', output)
29-
self.assertIn('name="bar"', output)
30-
self.assertIn('name="baz"', output)
28+
self.assertIn('"name": "foo"', output)
29+
self.assertIn('"name": "bar"', output)
30+
self.assertIn('"name": "baz"', output)

docs/examples/http/client.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,18 @@
2828

2929
# The preferred tracer implementation must be set, as the opentelemetry-api
3030
# defines the interface with a no-op implementation.
31+
# It must be done before instrumenting any library.
3132
trace.set_tracer_provider(TracerProvider())
32-
tracer_provider = trace.get_tracer_provider()
3333

34+
# Enable instrumentation in the requests library.
35+
http_requests.RequestsInstrumentor().instrument()
36+
37+
# Configure a console span exporter.
3438
exporter = ConsoleSpanExporter()
3539
span_processor = BatchExportSpanProcessor(exporter)
36-
tracer_provider.add_span_processor(span_processor)
40+
trace.get_tracer_provider().add_span_processor(span_processor)
3741

3842
# Integrations are the glue that binds the OpenTelemetry API and the
3943
# frameworks and libraries that are used together, automatically creating
4044
# Spans and propagating context as appropriate.
41-
http_requests.enable(tracer_provider)
4245
response = requests.get(url="http://127.0.0.1:5000/")

docs/examples/http/server.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,23 @@
3030

3131
# The preferred tracer implementation must be set, as the opentelemetry-api
3232
# defines the interface with a no-op implementation.
33+
# It must be done before instrumenting any library.
3334
trace.set_tracer_provider(TracerProvider())
34-
tracer = trace.get_tracer(__name__)
35-
36-
exporter = ConsoleSpanExporter()
37-
span_processor = BatchExportSpanProcessor(exporter)
38-
trace.get_tracer_provider().add_span_processor(span_processor)
3935

4036
# Integrations are the glue that binds the OpenTelemetry API and the
4137
# frameworks and libraries that are used together, automatically creating
4238
# Spans and propagating context as appropriate.
43-
http_requests.enable(trace.get_tracer_provider())
39+
http_requests.RequestsInstrumentor().instrument()
4440
app = flask.Flask(__name__)
4541
app.wsgi_app = OpenTelemetryMiddleware(app.wsgi_app)
4642

43+
# Configure a console span exporter.
44+
exporter = ConsoleSpanExporter()
45+
span_processor = BatchExportSpanProcessor(exporter)
46+
trace.get_tracer_provider().add_span_processor(span_processor)
47+
48+
tracer = trace.get_tracer(__name__)
49+
4750

4851
@app.route("/")
4952
def hello():

docs/examples/http/tests/test_http.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def test_http(self):
3232
output = subprocess.check_output(
3333
(sys.executable, test_script)
3434
).decode()
35-
self.assertIn('name="/"', output)
35+
self.assertIn('"name": "/"', output)
3636

3737
@classmethod
3838
def teardown_class(cls):

docs/examples/opentelemetry-example-app/src/opentelemetry_example_app/flask_example.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,20 @@
2828
SimpleExportSpanProcessor,
2929
)
3030

31+
# The preferred tracer implementation must be set, as the opentelemetry-api
32+
# defines the interface with a no-op implementation.
33+
# It must be done before instrumenting any library
3134
trace.set_tracer_provider(TracerProvider())
35+
36+
opentelemetry.ext.http_requests.RequestsInstrumentor().instrument()
37+
FlaskInstrumentor().instrument()
38+
3239
trace.get_tracer_provider().add_span_processor(
3340
SimpleExportSpanProcessor(ConsoleSpanExporter())
3441
)
3542

36-
FlaskInstrumentor().instrument()
43+
3744
app = flask.Flask(__name__)
38-
opentelemetry.ext.http_requests.enable(trace.get_tracer_provider())
3945

4046

4147
@app.route("/")

docs/examples/opentelemetry-example-app/src/opentelemetry_example_app/grpc/hello_world_client.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
trace.get_tracer_provider().add_span_processor(
6565
SimpleExportSpanProcessor(ConsoleSpanExporter())
6666
)
67-
tracer = trace.get_tracer(__name__)
6867

6968

7069
def run():
@@ -73,7 +72,7 @@ def run():
7372
# of the code.
7473
with grpc.insecure_channel("localhost:50051") as channel:
7574

76-
channel = intercept_channel(channel, client_interceptor(tracer))
75+
channel = intercept_channel(channel, client_interceptor())
7776

7877
stub = helloworld_pb2_grpc.GreeterStub(channel)
7978

docs/examples/opentelemetry-example-app/src/opentelemetry_example_app/grpc/hello_world_server.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
trace.get_tracer_provider().add_span_processor(
6565
SimpleExportSpanProcessor(ConsoleSpanExporter())
6666
)
67-
tracer = trace.get_tracer(__name__)
6867

6968

7069
class Greeter(helloworld_pb2_grpc.GreeterServicer):
@@ -75,7 +74,7 @@ def SayHello(self, request, context):
7574
def serve():
7675

7776
server = grpc.server(futures.ThreadPoolExecutor())
78-
server = intercept_server(server, server_interceptor(tracer))
77+
server = intercept_server(server, server_interceptor())
7978

8079
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
8180
server.add_insecure_port("[::]:50051")

docs/examples/opentelemetry-example-app/src/opentelemetry_example_app/grpc/route_guide_client.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
trace.get_tracer_provider().add_span_processor(
6868
SimpleExportSpanProcessor(ConsoleSpanExporter())
6969
)
70-
tracer = trace.get_tracer(__name__)
7170

7271

7372
def make_route_note(message, latitude, longitude):
@@ -154,7 +153,7 @@ def run():
154153
# used in circumstances in which the with statement does not fit the needs
155154
# of the code.
156155
with grpc.insecure_channel("localhost:50051") as channel:
157-
channel = intercept_channel(channel, client_interceptor(tracer))
156+
channel = intercept_channel(channel, client_interceptor())
158157

159158
stub = route_guide_pb2_grpc.RouteGuideStub(channel)
160159

docs/examples/opentelemetry-example-app/src/opentelemetry_example_app/grpc/route_guide_server.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@
6969
trace.get_tracer_provider().add_span_processor(
7070
SimpleExportSpanProcessor(ConsoleSpanExporter())
7171
)
72-
tracer = trace.get_tracer(__name__)
7372

7473

7574
def get_feature(feature_db, point):
@@ -164,7 +163,7 @@ def RouteChat(self, request_iterator, context):
164163

165164
def serve():
166165
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
167-
server = intercept_server(server, server_interceptor(tracer))
166+
server = intercept_server(server, server_interceptor())
168167

169168
route_guide_pb2_grpc.add_RouteGuideServicer_to_server(
170169
RouteGuideServicer(), server

docs/ext/pymysql/pymysql.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
OpenTelemetry PyMySQL Integration
2+
=================================
3+
4+
.. automodule:: opentelemetry.ext.pymysql
5+
:members:
6+
:undoc-members:
7+
:show-inheritance:

docs/ext/redis/redis.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
OpenTelemetry Redis Instrumentation
2+
===================================
3+
4+
.. automodule:: opentelemetry.ext.redis
5+
:members:
6+
:undoc-members:
7+
:show-inheritance:

docs/ext/sqlalchemy/sqlalchemy.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
OpenTelemetry SQLAlchemy Instrumentation
2+
========================================
3+
4+
.. automodule:: opentelemetry.ext.sqlalchemy
5+
:members:
6+
:undoc-members:
7+
:show-inheritance:

docs/getting-started.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ And let's write a small Flask application that sends an HTTP request, activating
202202
)
203203
204204
app = flask.Flask(__name__)
205-
opentelemetry.ext.http_requests.enable(trace.get_tracer_provider())
205+
opentelemetry.ext.http_requests.RequestsInstrumentor().instrument()
206206
207207
@app.route("/")
208208
def hello():

eachdist.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ sortfirst=
66
opentelemetry-sdk
77
opentelemetry-auto-instrumentation
88
ext/opentelemetry-ext-wsgi
9+
ext/opentelemetry-ext-dbapi
910
ext/*
1011

1112
[lintroots]

ext/opentelemetry-ext-dbapi/setup.cfg

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ long_description = file: README.rst
1919
long_description_content_type = text/x-rst
2020
author = OpenTelemetry Authors
2121
author_email = [email protected]
22-
url = https://github.com/open-telemetry/opentelemetry-python/ext/opentelemetry-ext-dbapi
22+
url = https://github.com/open-telemetry/opentelemetry-python/tree/master/ext/opentelemetry-ext-dbapi
2323
platforms = any
2424
license = Apache-2.0
2525
classifiers =
@@ -43,5 +43,9 @@ install_requires =
4343
opentelemetry-api == 0.7.dev0
4444
wrapt >= 1.0.0, < 2.0.0
4545

46+
[options.extras_require]
47+
test =
48+
opentelemetry-test == 0.7.dev0
49+
4650
[options.packages.find]
4751
where = src

ext/opentelemetry-ext-dbapi/src/opentelemetry/ext/dbapi/__init__.py

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,16 @@
2424
import mysql.connector
2525
import pyodbc
2626
27+
from opentelemetry import trace
2728
from opentelemetry.ext.dbapi import trace_integration
2829
from opentelemetry.trace import TracerProvider
2930
3031
trace.set_tracer_provider(TracerProvider())
31-
tracer = trace.get_tracer(__name__)
32+
3233
# Ex: mysql.connector
33-
trace_integration(tracer, mysql.connector, "connect", "mysql", "sql")
34+
trace_integration(mysql.connector, "connect", "mysql", "sql")
3435
# Ex: pyodbc
35-
trace_integration(tracer, pyodbc, "Connection", "odbc", "sql")
36+
trace_integration(pyodbc, "Connection", "odbc", "sql")
3637
3738
API
3839
---
@@ -44,13 +45,44 @@
4445

4546
import wrapt
4647

47-
from opentelemetry.trace import SpanKind, Tracer
48+
from opentelemetry.ext.dbapi.version import __version__
49+
from opentelemetry.trace import SpanKind, Tracer, TracerProvider, get_tracer
4850
from opentelemetry.trace.status import Status, StatusCanonicalCode
4951

5052
logger = logging.getLogger(__name__)
5153

5254

5355
def trace_integration(
56+
connect_module: typing.Callable[..., any],
57+
connect_method_name: str,
58+
database_component: str,
59+
database_type: str = "",
60+
connection_attributes: typing.Dict = None,
61+
tracer_provider: typing.Optional[TracerProvider] = None,
62+
):
63+
"""Integrate with DB API library.
64+
https://www.python.org/dev/peps/pep-0249/
65+
66+
Args:
67+
connect_module: Module name where connect method is available.
68+
connect_method_name: The connect method name.
69+
database_component: Database driver name or database name "JDBI", "jdbc", "odbc", "postgreSQL".
70+
database_type: The Database type. For any SQL database, "sql".
71+
connection_attributes: Attribute names for database, port, host and user in Connection object.
72+
tracer_provider: The :class:`TracerProvider` to use. If ommited the current configured one is used.
73+
"""
74+
tracer = get_tracer(__name__, __version__, tracer_provider)
75+
wrap_connect(
76+
tracer,
77+
connect_module,
78+
connect_method_name,
79+
database_component,
80+
database_type,
81+
connection_attributes,
82+
)
83+
84+
85+
def wrap_connect(
5486
tracer: Tracer,
5587
connect_module: typing.Callable[..., any],
5688
connect_method_name: str,
@@ -71,7 +103,7 @@ def trace_integration(
71103
"""
72104

73105
# pylint: disable=unused-argument
74-
def wrap_connect(
106+
def wrap_connect_(
75107
wrapped: typing.Callable[..., any],
76108
instance: typing.Any,
77109
args: typing.Tuple[any, any],
@@ -87,12 +119,20 @@ def wrap_connect(
87119

88120
try:
89121
wrapt.wrap_function_wrapper(
90-
connect_module, connect_method_name, wrap_connect
122+
connect_module, connect_method_name, wrap_connect_
91123
)
92124
except Exception as ex: # pylint: disable=broad-except
93125
logger.warning("Failed to integrate with DB API. %s", str(ex))
94126

95127

128+
def unwrap_connect(
129+
connect_module: typing.Callable[..., any], connect_method_name: str,
130+
):
131+
conn = getattr(connect_module, connect_method_name, None)
132+
if isinstance(conn, wrapt.ObjectProxy):
133+
setattr(connect_module, connect_method_name, conn.__wrapped__)
134+
135+
96136
class DatabaseApiIntegration:
97137
def __init__(
98138
self,
@@ -146,10 +186,13 @@ def get_connection_attributes(self, connection):
146186
self.name = self.database_component
147187
self.database = self.connection_props.get("database", "")
148188
if self.database:
189+
# PyMySQL encodes names with utf-8
190+
if hasattr(self.database, "decode"):
191+
self.database = self.database.decode(errors="ignore")
149192
self.name += "." + self.database
150193
user = self.connection_props.get("user")
151194
if user is not None:
152-
self.span_attributes["db.user"] = user
195+
self.span_attributes["db.user"] = str(user)
153196
host = self.connection_props.get("host")
154197
if host is not None:
155198
self.span_attributes["net.peer.name"] = host

0 commit comments

Comments
 (0)