Skip to content

Commit 3ef959f

Browse files
committed
allow setting tags directly on span/transaction objects (#384)
this is a pre-requisite for the opentracing bridge refs #249 closes #384
1 parent d053f04 commit 3ef959f

File tree

3 files changed

+38
-21
lines changed

3 files changed

+38
-21
lines changed

elasticapm/traces.py

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,17 @@ def ensure_parent_id(self):
9696
logger.debug("Set parent id to generated %s", self.trace_parent.span_id)
9797
return self.trace_parent.span_id
9898

99+
def tag(self, **tags):
100+
"""
101+
Tag this transaction with one or multiple key/value tags. Both the values should be strings
102+
103+
transaction_obj.tag(key1="value1", key2="value2")
104+
105+
Note that keys will be dedotted, replacing dot (.), star (*) and double quote (") with an underscore (_)
106+
"""
107+
for key in tags.keys():
108+
self.tags[TAG_RE.sub("_", compat.text_type(key))] = encoding.keyword_field(compat.text_type(tags[key]))
109+
99110
def to_dict(self):
100111
self.context["tags"] = self.tags
101112
result = {
@@ -161,12 +172,20 @@ def __init__(self, transaction, name, span_type, context=None, leaf=False, tags=
161172
self.duration = None
162173
self.parent = None
163174
self.frames = None
164-
self.tags = tags
165-
if self.tags:
166-
for key in list(self.tags.keys()):
167-
self.tags[TAG_RE.sub("_", compat.text_type(key))] = encoding.keyword_field(
168-
compat.text_type(self.tags.pop(key))
169-
)
175+
self.tags = {}
176+
if tags:
177+
self.tag(**tags)
178+
179+
def tag(self, **tags):
180+
"""
181+
Tag this span with one or multiple key/value tags. Both the values should be strings
182+
183+
span_obj.tag(key1="value1", key2="value2")
184+
185+
Note that keys will be dedotted, replacing dot (.), star (*) and double quote (") with an underscore (_)
186+
"""
187+
for key in tags.keys():
188+
self.tags[TAG_RE.sub("_", compat.text_type(key))] = encoding.keyword_field(compat.text_type(tags[key]))
170189

171190
def to_dict(self):
172191
result = {
@@ -300,13 +319,10 @@ def tag(**tags):
300319
Tags current transaction. Both key and value of the tag should be strings.
301320
"""
302321
transaction = get_transaction()
303-
for name, value in tags.items():
304-
if not transaction:
305-
error_logger.warning("Ignored tag %s. No transaction currently active.", name)
306-
return
307-
# replace invalid characters for Elasticsearch field names with underscores
308-
name = TAG_RE.sub("_", compat.text_type(name))
309-
transaction.tags[compat.text_type(name)] = encoding.keyword_field(compat.text_type(value))
322+
if not transaction:
323+
error_logger.warning("Ignored tags %s. No transaction currently active.", ", ".join(tags.keys()))
324+
else:
325+
transaction.tag(**tags)
310326

311327

312328
def set_transaction_name(name, override=True):

tests/fixtures.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
assert os.path.exists(ERRORS_SCHEMA) and os.path.exists(
3636
TRANSACTIONS_SCHEMA
37-
), 'JSON Schema files not found. Run "make update-json-schema to download'
37+
), 'JSON Schema files not found. Run "make update-json-schema" to download'
3838

3939

4040
with codecs.open(ERRORS_SCHEMA, encoding="utf8") as errors_json, codecs.open(

tests/instrumentation/transactions_store_tests.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,14 @@ def test_get_transaction_clear():
186186

187187
def test_tag_transaction():
188188
requests_store = Tracer(lambda: [], lambda: [], lambda *args: None)
189-
t = requests_store.begin_transaction("test")
189+
transaction = requests_store.begin_transaction("test")
190190
elasticapm.tag(foo="bar")
191+
transaction.tag(baz="bazzinga")
191192
requests_store.end_transaction(200, "test")
192193

193-
assert t.tags == {"foo": "bar"}
194-
transaction_dict = t.to_dict()
195-
assert transaction_dict["context"]["tags"] == {"foo": "bar"}
194+
assert transaction.tags == {"foo": "bar", "baz": "bazzinga"}
195+
transaction_dict = transaction.to_dict()
196+
assert transaction_dict["context"]["tags"] == {"foo": "bar", "baz": "bazzinga"}
196197

197198

198199
def test_tag_while_no_transaction(caplog):
@@ -328,8 +329,8 @@ def test_transaction_without_name_result(elasticapm_client):
328329

329330
def test_span_tagging(elasticapm_client):
330331
elasticapm_client.begin_transaction("test")
331-
with elasticapm.capture_span("test", tags={"foo": "bar", "ba.z": "baz.zinga"}):
332-
pass
332+
with elasticapm.capture_span("test", tags={"foo": "bar", "ba.z": "baz.zinga"}) as span:
333+
span.tag(lorem="ipsum")
333334
elasticapm_client.end_transaction("test", "OK")
334335
span = elasticapm_client.events[SPAN][0]
335-
assert span["context"]["tags"] == {"foo": "bar", "ba_z": "baz.zinga"}
336+
assert span["context"]["tags"] == {"foo": "bar", "ba_z": "baz.zinga", "lorem": "ipsum"}

0 commit comments

Comments
 (0)