Skip to content
This repository was archived by the owner on Oct 13, 2021. It is now read-only.

Commit 6e4d64c

Browse files
authored
[pymongo] Add support for PyMongo 3.9 (#1023)
* Test most recent versions of mongoengine and pymongo * limit the scope of what we test * [pymongo] Add support for PyMongo 3.9 * fix trailing comma issue * fix version spec * last missing trailing comma
1 parent 8983055 commit 6e4d64c

File tree

2 files changed

+56
-21
lines changed

2 files changed

+56
-21
lines changed

ddtrace/contrib/pymongo/client.py

+50-19
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class TracedServer(ObjectProxy):
9090
def __init__(self, server):
9191
super(TracedServer, self).__init__(server)
9292

93-
def send_message_with_response(self, operation, *args, **kwargs):
93+
def _datadog_trace_operation(self, operation):
9494
cmd = None
9595
# Only try to parse something we think is a query.
9696
if self._is_query(operation):
@@ -100,40 +100,71 @@ def send_message_with_response(self, operation, *args, **kwargs):
100100
log.exception('error parsing query')
101101

102102
pin = ddtrace.Pin.get_from(self)
103-
104103
# if we couldn't parse or shouldn't trace the message, just go.
105104
if not cmd or not pin or not pin.enabled():
106-
return self.__wrapped__.send_message_with_response(
105+
return None
106+
107+
span = pin.tracer.trace('pymongo.cmd', span_type=mongox.TYPE, service=pin.service)
108+
span.set_tag(mongox.DB, cmd.db)
109+
span.set_tag(mongox.COLLECTION, cmd.coll)
110+
span.set_tags(cmd.tags)
111+
112+
# set `mongodb.query` tag and resource for span
113+
_set_query_metadata(span, cmd)
114+
115+
# set analytics sample rate
116+
sample_rate = config.pymongo.get_analytics_sample_rate()
117+
if sample_rate is not None:
118+
span.set_tag(ANALYTICS_SAMPLE_RATE_KEY, sample_rate)
119+
return span
120+
121+
# Pymongo >= 3.9
122+
def run_operation_with_response(self, sock_info, operation, *args, **kwargs):
123+
span = self._datadog_trace_operation(operation)
124+
if not span:
125+
return self.__wrapped__.run_operation_with_response(
126+
sock_info,
107127
operation,
108128
*args,
109-
**kwargs)
110-
111-
with pin.tracer.trace(
112-
'pymongo.cmd',
113-
span_type=mongox.TYPE,
114-
service=pin.service) as span:
129+
**kwargs
130+
)
115131

116-
span.set_tag(mongox.DB, cmd.db)
117-
span.set_tag(mongox.COLLECTION, cmd.coll)
118-
span.set_tags(cmd.tags)
132+
try:
133+
result = self.__wrapped__.run_operation_with_response(
134+
sock_info,
135+
operation,
136+
*args,
137+
**kwargs
138+
)
119139

120-
# set `mongodb.query` tag and resource for span
121-
_set_query_metadata(span, cmd)
140+
if result and result.address:
141+
_set_address_tags(span, result.address)
142+
return result
143+
finally:
144+
span.finish()
122145

123-
# set analytics sample rate
124-
span.set_tag(
125-
ANALYTICS_SAMPLE_RATE_KEY,
126-
config.pymongo.get_analytics_sample_rate()
146+
# Pymongo < 3.9
147+
def send_message_with_response(self, operation, *args, **kwargs):
148+
span = self._datadog_trace_operation(operation)
149+
if not span:
150+
return self.__wrapped__.send_message_with_response(
151+
operation,
152+
*args,
153+
**kwargs
127154
)
128155

156+
try:
129157
result = self.__wrapped__.send_message_with_response(
130158
operation,
131159
*args,
132-
**kwargs)
160+
**kwargs
161+
)
133162

134163
if result and result.address:
135164
_set_address_tags(span, result.address)
136165
return result
166+
finally:
167+
span.finish()
137168

138169
@contextlib.contextmanager
139170
def get_socket(self, *args, **kwargs):

tox.ini

+6-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ envlist =
8181
jinja2_contrib-{py27,py34,py35,py36,py37}-jinja{27,28,29,210}
8282
mako_contrib-{py27,py34,py35,py36,py37}-mako{010,100}
8383
molten_contrib-py{36,37}-molten{070,072}
84-
mongoengine_contrib-{py27,py34,py35,py36,py37}-mongoengine{015}
84+
mongoengine_contrib-{py27,py34,py35,py36,py37}-mongoengine{015,016,017,018,latest}-pymongo{latest}
8585
mysql_contrib-{py27,py34,py35,py36,py37}-mysqlconnector
8686
mysqldb_contrib-{py27}-mysqldb{12}
8787
mysqldb_contrib-{py27,py34,py35,py36,py37}-mysqlclient{13}
@@ -90,7 +90,7 @@ envlist =
9090
pylibmc_contrib-{py27,py34,py35,py36,py37}-pylibmc{140,150}
9191
pylons_contrib-{py27}-pylons{096,097,010,10}
9292
pymemcache_contrib{,_autopatch}-{py27,py34,py35,py36,py37}-pymemcache{130,140}
93-
pymongo_contrib-{py27,py34,py35,py36,py37}-pymongo{30,31,32,33,34,36,37,38}-mongoengine{015,016,017}
93+
pymongo_contrib-{py27,py34,py35,py36,py37}-pymongo{30,31,32,33,34,35,36,37,38,39,latest}-mongoengine{latest}
9494
pymysql_contrib-{py27,py34,py35,py36,py37}-pymysql{07,08,09}
9595
pyramid_contrib{,_autopatch}-{py27,py34,py35,py36,py37}-pyramid{17,18,19}-webtest
9696
redis_contrib-{py27,py34,py35,py36,py37}-redis{26,27,28,29,210,300}
@@ -274,6 +274,8 @@ deps =
274274
mongoengine015: mongoengine>=0.15<0.16
275275
mongoengine016: mongoengine>=0.16<0.17
276276
mongoengine017: mongoengine>=0.17<0.18
277+
mongoengine018: mongoengine>=0.18<0.19
278+
mongoenginelatest: mongoengine>=0.18
277279
mysqlconnector: mysql-connector-python
278280
mysqldb12: mysql-python>=1.2,<1.3
279281
mysqlclient13: mysqlclient>=1.3,<1.4
@@ -298,6 +300,8 @@ deps =
298300
pymongo36: pymongo>=3.6,<3.7
299301
pymongo37: pymongo>=3.7,<3.8
300302
pymongo38: pymongo>=3.8,<3.9
303+
pymongo39: pymongo>=3.9,<3.10
304+
pymongolatest: pymongo>=3.9
301305
pymysql07: pymysql>=0.7,<0.8
302306
pymysql08: pymysql>=0.8,<0.9
303307
pymysql09: pymysql>=0.9,<0.10

0 commit comments

Comments
 (0)