Skip to content

Commit e1dbc65

Browse files
Fix issue with tagging non-string Flask view args (#2760) (#2761)
* Fix issue with tagging non-string Flask view args fixes #2756 * fix test method name * fix json decoding when we have bytes Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 54a42fe) Co-authored-by: Brett Langdon <[email protected]>
1 parent 95ca9a3 commit e1dbc65

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

ddtrace/contrib/flask/patch.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,9 @@ def _traced_request(pin, wrapped, instance, args, kwargs):
481481

482482
if not span.get_tag(FLASK_VIEW_ARGS) and request.view_args and config.flask.get("collect_view_args"):
483483
for k, v in request.view_args.items():
484-
span._set_str_tag(u".".join((FLASK_VIEW_ARGS, k)), v)
484+
# DEV: Do not use `_set_str_tag` here since view args can be string/int/float/path/uuid/etc
485+
# https://flask.palletsprojects.com/en/1.1.x/api/#url-route-registrations
486+
span.set_tag(u".".join((FLASK_VIEW_ARGS, k)), v)
485487
except Exception:
486488
log.debug('failed to set tags for "flask.request" span', exc_info=True)
487489

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
fixes:
3+
- |
4+
Fixes error with tagging non-string Flask view args.

tests/contrib/flask/test_request.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# -*- coding: utf-8 -*-
2+
import json
3+
24
import flask
35
from flask import abort
6+
from flask import jsonify
47
from flask import make_response
58

69
from ddtrace.constants import ANALYTICS_SAMPLE_RATE_KEY
@@ -82,6 +85,50 @@ def index():
8285
self.assertEqual(handler_span.resource, "/")
8386
self.assertEqual(req_span.error, 0)
8487

88+
def test_route_params_request(self):
89+
"""
90+
When making a request to an endpoint with non-string url params
91+
We create the expected spans
92+
"""
93+
94+
@self.app.route("/route_params/<first>/<int:second>/<float:third>/<path:fourth>")
95+
def route_params(first, second, third, fourth):
96+
return jsonify(
97+
{
98+
"first": first,
99+
"second": second,
100+
"third": third,
101+
"fourth": fourth,
102+
}
103+
)
104+
105+
res = self.client.get("/route_params/test/100/5.5/some/sub/path")
106+
self.assertEqual(res.status_code, 200)
107+
if isinstance(res.data, bytes):
108+
data = json.loads(res.data.decode())
109+
else:
110+
data = json.loads(res.data)
111+
112+
assert data == {
113+
"first": "test",
114+
"second": 100,
115+
"third": 5.5,
116+
"fourth": "some/sub/path",
117+
}
118+
119+
spans = self.get_spans()
120+
self.assertEqual(len(spans), 8)
121+
122+
root = spans[0]
123+
assert root.name == "flask.request"
124+
assert root.get_tag(http.URL) == "http://localhost/route_params/test/100/5.5/some/sub/path"
125+
assert root.get_tag("flask.endpoint") == "route_params"
126+
assert root.get_tag("flask.url_rule") == "/route_params/<first>/<int:second>/<float:third>/<path:fourth>"
127+
assert root.get_tag("flask.view_args.first") == "test"
128+
assert root.get_metric("flask.view_args.second") == 100.0
129+
assert root.get_metric("flask.view_args.third") == 5.5
130+
assert root.get_tag("flask.view_args.fourth") == "some/sub/path"
131+
85132
def test_request_query_string_trace(self):
86133
"""Make sure when making a request that we create the expected spans and capture the query string."""
87134

0 commit comments

Comments
 (0)