Skip to content

Commit ff6a73b

Browse files
author
Emanuele Palazzetti
committed
flask-cache: make the tracer more fault tolerant
1 parent 0738a3b commit ff6a73b

File tree

3 files changed

+173
-35
lines changed

3 files changed

+173
-35
lines changed

ddtrace/contrib/flask_cache/tracers.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,14 @@ def __trace(self, cmd):
5757
service=self._datadog_service
5858
)
5959
# set span tags
60-
s.set_tag(CACHE_BACKEND, self.config["CACHE_TYPE"])
60+
s.set_tag(CACHE_BACKEND, self.config.get("CACHE_TYPE"))
6161
s.set_tags(self._datadog_meta)
6262
# add connection meta if there is one
6363
if getattr(self.cache, "_client", None):
64-
s.set_tags(_extract_conn_tags(self.cache._client))
64+
try:
65+
s.set_tags(_extract_conn_tags(self.cache._client))
66+
except Exception:
67+
log.exception("error parsing connection tags")
6568

6669
return s
6770

@@ -81,7 +84,8 @@ def set(self, *args, **kwargs):
8184
"""
8285
with self.__trace("flask_cache.cmd") as span:
8386
span.resource = _resource_from_cache_prefix("SET", self.config)
84-
span.set_tag(COMMAND_KEY, args[0])
87+
if len(args) > 0:
88+
span.set_tag(COMMAND_KEY, args[0])
8589
return super(TracedCache, self).set(*args, **kwargs)
8690

8791
def add(self, *args, **kwargs):
@@ -90,7 +94,8 @@ def add(self, *args, **kwargs):
9094
"""
9195
with self.__trace("flask_cache.cmd") as span:
9296
span.resource = _resource_from_cache_prefix("ADD", self.config)
93-
span.set_tag(COMMAND_KEY, args[0])
97+
if len(args) > 0:
98+
span.set_tag(COMMAND_KEY, args[0])
9499
return super(TracedCache, self).add(*args, **kwargs)
95100

96101
def delete(self, *args, **kwargs):
@@ -99,7 +104,8 @@ def delete(self, *args, **kwargs):
99104
"""
100105
with self.__trace("flask_cache.cmd") as span:
101106
span.resource = _resource_from_cache_prefix("DELETE", self.config)
102-
span.set_tag(COMMAND_KEY, args[0])
107+
if len(args) > 0:
108+
span.set_tag(COMMAND_KEY, args[0])
103109
return super(TracedCache, self).delete(*args, **kwargs)
104110

105111
def delete_many(self, *args, **kwargs):
@@ -134,7 +140,8 @@ def set_many(self, *args, **kwargs):
134140
"""
135141
with self.__trace("flask_cache.cmd") as span:
136142
span.resource = _resource_from_cache_prefix("SET_MANY", self.config)
137-
span.set_tag(COMMAND_KEY, list(args[0].keys()))
143+
if len(args) > 0:
144+
span.set_tag(COMMAND_KEY, list(args[0].keys()))
138145
return super(TracedCache, self).set_many(*args, **kwargs)
139146

140147
return TracedCache

tests/contrib/flask_cache/test.py

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# -*- coding: utf-8 -*-
22
import unittest
33

4-
from nose.tools import eq_, ok_, assert_raises
4+
from nose.tools import eq_, ok_
55

66
from ddtrace.tracer import Tracer
77
from ddtrace.contrib.flask_cache import get_traced_cache
@@ -42,34 +42,6 @@ def test_simple_cache_get(self):
4242

4343
eq_(span.meta, expected_meta)
4444

45-
def test_simple_cache_get_without_arguments(self):
46-
# initialize the dummy writer
47-
writer = DummyWriter()
48-
tracer = Tracer()
49-
tracer.writer = writer
50-
51-
# create the TracedCache instance for a Flask app
52-
Cache = get_traced_cache(tracer, service=self.SERVICE)
53-
app = Flask(__name__)
54-
cache = Cache(app, config={"CACHE_TYPE": "simple"})
55-
56-
# wrong usage of a get()
57-
with assert_raises(TypeError) as ex:
58-
cache.get()
59-
60-
# ensure that the error is not caused by our tracer
61-
ok_("get()" in ex.exception.args[0])
62-
ok_("argument" in ex.exception.args[0])
63-
spans = writer.pop()
64-
# an error trace must be sent
65-
eq_(len(spans), 1)
66-
span = spans[0]
67-
eq_(span.service, self.SERVICE)
68-
eq_(span.resource, "get")
69-
eq_(span.name, "flask_cache.cmd")
70-
eq_(span.span_type, "cache")
71-
eq_(span.error, 1)
72-
7345
def test_simple_cache_set(self):
7446
# initialize the dummy writer
7547
writer = DummyWriter()
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# -*- coding: utf-8 -*-
2+
import unittest
3+
4+
from nose.tools import eq_, ok_, assert_raises
5+
6+
# project
7+
from ddtrace.ext import net
8+
from ddtrace.tracer import Tracer
9+
from ddtrace.contrib.flask_cache import get_traced_cache
10+
11+
# 3rd party
12+
from flask import Flask
13+
14+
# testing
15+
from ...test_tracer import DummyWriter
16+
17+
18+
class FlaskCacheWrapperTest(unittest.TestCase):
19+
SERVICE = "test-flask-cache"
20+
21+
def test_cache_get_without_arguments(self):
22+
# initialize the dummy writer
23+
writer = DummyWriter()
24+
tracer = Tracer()
25+
tracer.writer = writer
26+
27+
# create the TracedCache instance for a Flask app
28+
Cache = get_traced_cache(tracer, service=self.SERVICE)
29+
app = Flask(__name__)
30+
cache = Cache(app, config={"CACHE_TYPE": "simple"})
31+
32+
# make a wrong call
33+
with assert_raises(TypeError) as ex:
34+
cache.get()
35+
36+
# ensure that the error is not caused by our tracer
37+
ok_("get()" in ex.exception.args[0])
38+
ok_("argument" in ex.exception.args[0])
39+
spans = writer.pop()
40+
# an error trace must be sent
41+
eq_(len(spans), 1)
42+
span = spans[0]
43+
eq_(span.service, self.SERVICE)
44+
eq_(span.resource, "get")
45+
eq_(span.name, "flask_cache.cmd")
46+
eq_(span.span_type, "cache")
47+
eq_(span.error, 1)
48+
49+
def test_cache_set_without_arguments(self):
50+
# initialize the dummy writer
51+
writer = DummyWriter()
52+
tracer = Tracer()
53+
tracer.writer = writer
54+
55+
# create the TracedCache instance for a Flask app
56+
Cache = get_traced_cache(tracer, service=self.SERVICE)
57+
app = Flask(__name__)
58+
cache = Cache(app, config={"CACHE_TYPE": "simple"})
59+
60+
# make a wrong call
61+
with assert_raises(TypeError) as ex:
62+
cache.set()
63+
64+
# ensure that the error is not caused by our tracer
65+
ok_("set()" in ex.exception.args[0])
66+
ok_("argument" in ex.exception.args[0])
67+
spans = writer.pop()
68+
# an error trace must be sent
69+
eq_(len(spans), 1)
70+
span = spans[0]
71+
eq_(span.service, self.SERVICE)
72+
eq_(span.resource, "set")
73+
eq_(span.name, "flask_cache.cmd")
74+
eq_(span.span_type, "cache")
75+
eq_(span.error, 1)
76+
77+
def test_cache_add_without_arguments(self):
78+
# initialize the dummy writer
79+
writer = DummyWriter()
80+
tracer = Tracer()
81+
tracer.writer = writer
82+
83+
# create the TracedCache instance for a Flask app
84+
Cache = get_traced_cache(tracer, service=self.SERVICE)
85+
app = Flask(__name__)
86+
cache = Cache(app, config={"CACHE_TYPE": "simple"})
87+
88+
# make a wrong call
89+
with assert_raises(TypeError) as ex:
90+
cache.add()
91+
92+
# ensure that the error is not caused by our tracer
93+
ok_("add()" in ex.exception.args[0])
94+
ok_("argument" in ex.exception.args[0])
95+
spans = writer.pop()
96+
# an error trace must be sent
97+
eq_(len(spans), 1)
98+
span = spans[0]
99+
eq_(span.service, self.SERVICE)
100+
eq_(span.resource, "add")
101+
eq_(span.name, "flask_cache.cmd")
102+
eq_(span.span_type, "cache")
103+
eq_(span.error, 1)
104+
105+
def test_cache_delete_without_arguments(self):
106+
# initialize the dummy writer
107+
writer = DummyWriter()
108+
tracer = Tracer()
109+
tracer.writer = writer
110+
111+
# create the TracedCache instance for a Flask app
112+
Cache = get_traced_cache(tracer, service=self.SERVICE)
113+
app = Flask(__name__)
114+
cache = Cache(app, config={"CACHE_TYPE": "simple"})
115+
116+
# make a wrong call
117+
with assert_raises(TypeError) as ex:
118+
cache.delete()
119+
120+
# ensure that the error is not caused by our tracer
121+
ok_("delete()" in ex.exception.args[0])
122+
ok_("argument" in ex.exception.args[0])
123+
spans = writer.pop()
124+
# an error trace must be sent
125+
eq_(len(spans), 1)
126+
span = spans[0]
127+
eq_(span.service, self.SERVICE)
128+
eq_(span.resource, "delete")
129+
eq_(span.name, "flask_cache.cmd")
130+
eq_(span.span_type, "cache")
131+
eq_(span.error, 1)
132+
133+
def test_cache_set_many_without_arguments(self):
134+
# initialize the dummy writer
135+
writer = DummyWriter()
136+
tracer = Tracer()
137+
tracer.writer = writer
138+
139+
# create the TracedCache instance for a Flask app
140+
Cache = get_traced_cache(tracer, service=self.SERVICE)
141+
app = Flask(__name__)
142+
cache = Cache(app, config={"CACHE_TYPE": "simple"})
143+
144+
# make a wrong call
145+
with assert_raises(TypeError) as ex:
146+
cache.set_many()
147+
148+
# ensure that the error is not caused by our tracer
149+
ok_("set_many()" in ex.exception.args[0])
150+
ok_("argument" in ex.exception.args[0])
151+
spans = writer.pop()
152+
# an error trace must be sent
153+
eq_(len(spans), 1)
154+
span = spans[0]
155+
eq_(span.service, self.SERVICE)
156+
eq_(span.resource, "set_many")
157+
eq_(span.name, "flask_cache.cmd")
158+
eq_(span.span_type, "cache")
159+
eq_(span.error, 1)

0 commit comments

Comments
 (0)