Skip to content

Commit 1182783

Browse files
authored
Enable client async and mixed tracing (#329)
* added retrieving of any active tracer (tracer, async_tracer or tornado) for each client implementation * isolate the asynqp testing for avoiding infecting other random tests * update the version
1 parent 64f62f0 commit 1182783

27 files changed

+199
-144
lines changed

.circleci/config.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,26 @@ jobs:
235235
. venv/bin/activate
236236
pytest -v tests/clients/test_cassandra-driver.py
237237
238+
py37asynqp:
239+
docker:
240+
- image: circleci/python:3.7.9
241+
- image: rabbitmq:3.5.4
242+
working_directory: ~/repo
243+
steps:
244+
- checkout
245+
- pip-install-deps:
246+
requirements: "tests/requirements-asynqp.txt"
247+
- run:
248+
name: run tests
249+
environment:
250+
INSTANA_TEST: "true"
251+
ASYNQP_TEST: "true"
252+
command: |
253+
. venv/bin/activate
254+
# We uninstall uvloop as it interferes with asyncio changing the event loop policy
255+
pip uninstall -y uvloop
256+
pytest -v tests/clients/test_asynqp.py
257+
238258
gevent38:
239259
docker:
240260
- image: circleci/python:3.8.5
@@ -262,4 +282,5 @@ workflows:
262282
- python39
263283
- py27cassandra
264284
- py36cassandra
285+
- py37asynqp
265286
- gevent38

instana/autoprofile/runtime.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import sys
55
import signal
6+
import os
67

78

89
class runtime_info(object):

instana/instrumentation/boto3_inst.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99

1010
from ..log import logger
1111
from ..singletons import tracer
12-
12+
from ..util.traceutils import get_active_tracer
1313

1414
try:
1515
import boto3
1616
from boto3.s3 import inject
1717

18+
1819
def lambda_inject_context(payload, scope):
1920
"""
2021
When boto3 lambda client 'Invoke' is called, we want to inject the tracing context.
@@ -36,13 +37,13 @@ def lambda_inject_context(payload, scope):
3637
@wrapt.patch_function_wrapper('botocore.client', 'BaseClient._make_api_call')
3738
def make_api_call_with_instana(wrapped, instance, arg_list, kwargs):
3839
# pylint: disable=protected-access
39-
parent_span = tracer.active_span
40+
active_tracer = get_active_tracer()
4041

4142
# If we're not tracing, just return
42-
if parent_span is None:
43+
if active_tracer is None:
4344
return wrapped(*arg_list, **kwargs)
4445

45-
with tracer.start_active_span("boto3", child_of=parent_span) as scope:
46+
with active_tracer.start_active_span("boto3", child_of=active_tracer.active_span) as scope:
4647
try:
4748
operation = arg_list[0]
4849
payload = arg_list[1]
@@ -62,7 +63,6 @@ def make_api_call_with_instana(wrapped, instance, arg_list, kwargs):
6263
if 'lambda' in instance._endpoint.host and operation == 'Invoke':
6364
lambda_inject_context(payload, scope)
6465

65-
6666
except Exception as exc:
6767
logger.debug("make_api_call_with_instana: collect error", exc_info=True)
6868

@@ -81,19 +81,20 @@ def make_api_call_with_instana(wrapped, instance, arg_list, kwargs):
8181
scope.span.mark_as_errored({'error': exc})
8282
raise
8383

84+
8485
def s3_inject_method_with_instana(wrapped, instance, arg_list, kwargs):
8586
fas = inspect.getfullargspec(wrapped)
8687
fas_args = fas.args
8788
fas_args.remove('self')
8889

8990
# pylint: disable=protected-access
90-
parent_span = tracer.active_span
91+
active_tracer = get_active_tracer()
9192

9293
# If we're not tracing, just return
93-
if parent_span is None:
94+
if active_tracer is None:
9495
return wrapped(*arg_list, **kwargs)
9596

96-
with tracer.start_active_span("boto3", child_of=parent_span) as scope:
97+
with active_tracer.start_active_span("boto3", child_of=active_tracer.active_span) as scope:
9798
try:
9899
operation = wrapped.__name__
99100
scope.span.set_tag('op', operation)
@@ -119,6 +120,7 @@ def s3_inject_method_with_instana(wrapped, instance, arg_list, kwargs):
119120
scope.span.mark_as_errored({'error': exc})
120121
raise
121122

123+
122124
for method in ['upload_file', 'upload_fileobj', 'download_file', 'download_fileobj']:
123125
wrapt.wrap_function_wrapper('boto3.s3.inject', method, s3_inject_method_with_instana)
124126

instana/instrumentation/cassandra_inst.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@
77
https://github.com/datastax/python-driver
88
"""
99
from __future__ import absolute_import
10-
11-
from distutils.version import LooseVersion
1210
import wrapt
13-
1411
from ..log import logger
15-
from ..singletons import tracer
12+
from ..util.traceutils import get_active_tracer
1613

1714
try:
1815
import cassandra
@@ -29,6 +26,7 @@
2926
9: "LOCAL_SERIAL",
3027
10: "LOCAL_ONE"})
3128

29+
3230
def collect_response(span, fn):
3331
tried_hosts = list()
3432
for host in fn.attempted_hosts:
@@ -46,15 +44,18 @@ def cb_request_finish(results, span, fn):
4644
collect_response(span, fn)
4745
span.finish()
4846

47+
4948
def cb_request_error(results, span, fn):
5049
collect_response(span, fn)
5150
span.mark_as_errored({"cassandra.error": results.message})
5251
span.finish()
5352

53+
5454
def request_init_with_instana(fn):
55-
parent_span = tracer.active_span
55+
active_tracer = get_active_tracer()
5656

57-
if parent_span is not None:
57+
if active_tracer is not None:
58+
parent_span = active_tracer.active_span
5859
ctags = dict()
5960
if isinstance(fn.query, cassandra.query.SimpleStatement):
6061
ctags["cassandra.query"] = fn.query.query_string
@@ -64,21 +65,23 @@ def request_init_with_instana(fn):
6465
ctags["cassandra.keyspace"] = fn.session.keyspace
6566
ctags["cassandra.cluster"] = fn.session.cluster.metadata.cluster_name
6667

67-
span = tracer.start_span(
68+
span = active_tracer.start_span(
6869
operation_name="cassandra",
6970
child_of=parent_span,
7071
tags=ctags)
7172

7273
fn.add_callback(cb_request_finish, span, fn)
7374
fn.add_errback(cb_request_error, span, fn)
7475

76+
7577
@wrapt.patch_function_wrapper('cassandra.cluster', 'Session.__init__')
7678
def init_with_instana(wrapped, instance, args, kwargs):
77-
session = wrapped(*args, **kwargs)
79+
session = wrapped(*args, **kwargs)
7880
instance.add_request_init_listener(request_init_with_instana)
7981
return session
8082

83+
8184
logger.debug("Instrumenting cassandra")
8285

8386
except ImportError:
84-
pass
87+
pass

instana/instrumentation/celery/hooks.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import opentracing
77
from ...log import logger
88
from ...singletons import tracer
9+
from ...util.traceutils import get_active_tracer
910

1011
try:
1112
import celery
@@ -111,22 +112,22 @@ def task_retry(*args, **kwargs):
111112
@signals.before_task_publish.connect
112113
def before_task_publish(*args, **kwargs):
113114
try:
114-
parent_span = tracer.active_span
115-
if parent_span is not None:
115+
active_tracer = get_active_tracer()
116+
if active_tracer is not None:
116117
body = kwargs['body']
117118
headers = kwargs['headers']
118119
task_name = kwargs['sender']
119120
task = registry.tasks.get(task_name)
120121
task_id = get_task_id(headers, body)
121122

122-
scope = tracer.start_active_span("celery-client", child_of=parent_span)
123+
scope = active_tracer.start_active_span("celery-client", child_of=active_tracer.active_span)
123124
scope.span.set_tag("task", task_name)
124125
scope.span.set_tag("task_id", task_id)
125126
add_broker_tags(scope.span, task.app.conf['broker_url'])
126127

127128
# Context propagation
128129
context_headers = {}
129-
tracer.inject(scope.span.context, opentracing.Format.HTTP_HEADERS, context_headers)
130+
active_tracer.inject(scope.span.context, opentracing.Format.HTTP_HEADERS, context_headers)
130131

131132
# Fix for broken header propagation
132133
# https://github.com/celery/celery/issues/4875

instana/instrumentation/couchbase_inst.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import wrapt
1212

1313
from ..log import logger
14-
from ..singletons import tracer
14+
from ..util.traceutils import get_active_tracer
1515

1616
try:
1717
import couchbase
@@ -47,13 +47,13 @@ def capture_kvs(scope, instance, query_arg, op):
4747

4848
def make_wrapper(op):
4949
def wrapper(wrapped, instance, args, kwargs):
50-
parent_span = tracer.active_span
50+
active_tracer = get_active_tracer()
5151

5252
# If we're not tracing, just return
53-
if parent_span is None:
53+
if active_tracer is None:
5454
return wrapped(*args, **kwargs)
5555

56-
with tracer.start_active_span("couchbase", child_of=parent_span) as scope:
56+
with active_tracer.start_active_span("couchbase", child_of=active_tracer.active_span) as scope:
5757
capture_kvs(scope, instance, None, op)
5858
try:
5959
return wrapped(*args, **kwargs)
@@ -64,13 +64,13 @@ def wrapper(wrapped, instance, args, kwargs):
6464
return wrapper
6565

6666
def query_with_instana(wrapped, instance, args, kwargs):
67-
parent_span = tracer.active_span
67+
active_tracer = get_active_tracer()
6868

6969
# If we're not tracing, just return
70-
if parent_span is None:
70+
if active_tracer is None:
7171
return wrapped(*args, **kwargs)
7272

73-
with tracer.start_active_span("couchbase", child_of=parent_span) as scope:
73+
with active_tracer.start_active_span("couchbase", child_of=active_tracer.active_span) as scope:
7474
capture_kvs(scope, instance, args[0], 'n1ql_query')
7575
try:
7676
return wrapped(*args, **kwargs)

instana/instrumentation/logging.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import collections
1010

1111
from ..log import logger
12-
from ..singletons import tracer
12+
from ..util.traceutils import get_active_tracer
1313

1414

1515
@wrapt.patch_function_wrapper('logging', 'Logger._log')
@@ -18,10 +18,10 @@ def log_with_instana(wrapped, instance, argv, kwargs):
1818
# argv[1] = message
1919
# argv[2] = args for message
2020
try:
21-
parent_span = tracer.active_span
21+
active_tracer = get_active_tracer()
2222

2323
# Only needed if we're tracing and serious log
24-
if parent_span and argv[0] >= logging.WARN:
24+
if active_tracer and argv[0] >= logging.WARN:
2525

2626
msg = str(argv[1])
2727
args = argv[2]
@@ -38,7 +38,7 @@ def log_with_instana(wrapped, instance, argv, kwargs):
3838
parameters = '{} {}'.format(t , v)
3939

4040
# create logging span
41-
with tracer.start_active_span('log', child_of=parent_span) as scope:
41+
with active_tracer.start_active_span('log', child_of=active_tracer.active_span) as scope:
4242
scope.span.log_kv({ 'message': msg })
4343
if parameters is not None:
4444
scope.span.log_kv({ 'parameters': parameters })

instana/instrumentation/pep0249.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import wrapt
77

88
from ..log import logger
9-
from ..singletons import tracer
9+
from ..util.traceutils import get_active_tracer
1010
from ..util.sql import sql_sanitizer
1111

1212

@@ -39,13 +39,13 @@ def _collect_kvs(self, span, sql):
3939
return span
4040

4141
def execute(self, sql, params=None):
42-
parent_span = tracer.active_span
42+
active_tracer = get_active_tracer()
4343

4444
# If not tracing or we're being called from sqlalchemy, just pass through
45-
if (parent_span is None) or (parent_span.operation_name == "sqlalchemy"):
45+
if (active_tracer is None) or (active_tracer.active_span.operation_name == "sqlalchemy"):
4646
return self.__wrapped__.execute(sql, params)
4747

48-
with tracer.start_active_span(self._module_name, child_of=parent_span) as scope:
48+
with active_tracer.start_active_span(self._module_name, child_of=active_tracer.active_span) as scope:
4949
try:
5050
self._collect_kvs(scope.span, sql)
5151

@@ -58,13 +58,13 @@ def execute(self, sql, params=None):
5858
return result
5959

6060
def executemany(self, sql, seq_of_parameters):
61-
parent_span = tracer.active_span
61+
active_tracer = get_active_tracer()
6262

6363
# If not tracing or we're being called from sqlalchemy, just pass through
64-
if (parent_span is None) or (parent_span.operation_name == "sqlalchemy"):
64+
if (active_tracer is None) or (active_tracer.active_span.operation_name == "sqlalchemy"):
6565
return self.__wrapped__.executemany(sql, seq_of_parameters)
6666

67-
with tracer.start_active_span(self._module_name, child_of=parent_span) as scope:
67+
with active_tracer.start_active_span(self._module_name, child_of=active_tracer.active_span) as scope:
6868
try:
6969
self._collect_kvs(scope.span, sql)
7070

@@ -77,13 +77,13 @@ def executemany(self, sql, seq_of_parameters):
7777
return result
7878

7979
def callproc(self, proc_name, params):
80-
parent_span = tracer.active_span
80+
active_tracer = get_active_tracer()
8181

8282
# If not tracing or we're being called from sqlalchemy, just pass through
83-
if (parent_span is None) or (parent_span.operation_name == "sqlalchemy"):
83+
if (active_tracer is None) or (active_tracer.active_span.operation_name == "sqlalchemy"):
8484
return self.__wrapped__.execute(proc_name, params)
8585

86-
with tracer.start_active_span(self._module_name, child_of=parent_span) as scope:
86+
with active_tracer.start_active_span(self._module_name, child_of=active_tracer.active_span) as scope:
8787
try:
8888
self._collect_kvs(scope.span, proc_name)
8989

instana/instrumentation/pika.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
from ..log import logger
1313
from ..singletons import tracer
14+
from ..util.traceutils import get_active_tracer
1415

1516
try:
1617
import pika
@@ -41,14 +42,14 @@ def basic_publish_with_instana(wrapped, instance, args, kwargs):
4142
def _bind_args(exchange, routing_key, body, properties=None, *args, **kwargs):
4243
return (exchange, routing_key, body, properties, args, kwargs)
4344

44-
parent_span = tracer.active_span
45+
active_tracer = get_active_tracer()
4546

46-
if parent_span is None:
47+
if active_tracer is None:
4748
return wrapped(*args, **kwargs)
4849

4950
(exchange, routing_key, body, properties, args, kwargs) = (_bind_args(*args, **kwargs))
5051

51-
with tracer.start_active_span("rabbitmq", child_of=parent_span) as scope:
52+
with tracer.start_active_span("rabbitmq", child_of=active_tracer.active_span) as scope:
5253
try:
5354
_extract_publisher_tags(scope.span,
5455
conn=instance.connection,

instana/instrumentation/pymongo.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ def started(self, event):
2222
if active_tracer is None:
2323
return
2424

25-
parent_span = active_tracer.active_span
26-
27-
with active_tracer.start_active_span("mongo", child_of=parent_span) as scope:
25+
with active_tracer.start_active_span("mongo", child_of=active_tracer.active_span) as scope:
2826
self._collect_connection_tags(scope.span, event)
2927
self._collect_command_tags(scope.span, event)
3028

0 commit comments

Comments
 (0)