Skip to content

Commit 909ecaa

Browse files
markstoryuntitaker
andauthored
fix(tracing) Omit the top level status tag (getsentry#644)
In the product side we don't really want people to search by this tag as it is far more expensive than the `transaction.status` property which is indexed separately. By not emitting this tag and only including it in the trace context we won't end up with poor performing tags for users to click on. To workaround get_trace_context() being called multiple times I needed an additional non-tags place to store the status. I've had to shim the status back into tags as non-transaction spans expect to have status as a tag. Co-authored-by: Markus Unterwaditzer <markus@unterwaditzer.net>
1 parent 8d475f9 commit 909ecaa

File tree

2 files changed

+15
-7
lines changed

2 files changed

+15
-7
lines changed

sentry_sdk/tracing.py

+11-6
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class Span(object):
103103
"description",
104104
"start_timestamp",
105105
"_start_timestamp_monotonic",
106+
"status",
106107
"timestamp",
107108
"_tags",
108109
"_data",
@@ -122,6 +123,7 @@ def __init__(
122123
op=None, # type: Optional[str]
123124
description=None, # type: Optional[str]
124125
hub=None, # type: Optional[sentry_sdk.Hub]
126+
status=None, # type: Optional[str]
125127
):
126128
# type: (...) -> None
127129
self.trace_id = trace_id or uuid.uuid4().hex
@@ -132,6 +134,7 @@ def __init__(
132134
self.transaction = transaction
133135
self.op = op
134136
self.description = description
137+
self.status = status
135138
self.hub = hub
136139
self._tags = {} # type: Dict[str, str]
137140
self._data = {} # type: Dict[str, Any]
@@ -183,7 +186,7 @@ def __enter__(self):
183186
def __exit__(self, ty, value, tb):
184187
# type: (Optional[Any], Optional[Any], Optional[Any]) -> None
185188
if value is not None:
186-
self._tags.setdefault("status", "internal_error")
189+
self.set_status("internal_error")
187190

188191
hub, scope, old_span = self._context_manager_state
189192
del self._context_manager_state
@@ -272,7 +275,7 @@ def set_data(self, key, value):
272275

273276
def set_status(self, value):
274277
# type: (str) -> None
275-
self.set_tag("status", value)
278+
self.status = value
276279

277280
def set_http_status(self, http_status):
278281
# type: (int) -> None
@@ -309,7 +312,7 @@ def set_http_status(self, http_status):
309312

310313
def is_success(self):
311314
# type: () -> bool
312-
return self._tags.get("status") == "ok"
315+
return self.status == "ok"
313316

314317
def finish(self, hub=None):
315318
# type: (Optional[sentry_sdk.Hub]) -> Optional[str]
@@ -387,6 +390,9 @@ def to_json(self, client):
387390
if transaction:
388391
rv["transaction"] = transaction
389392

393+
if self.status:
394+
self._tags["status"] = self.status
395+
390396
tags = self._tags
391397
if tags:
392398
rv["tags"] = tags
@@ -406,9 +412,8 @@ def get_trace_context(self):
406412
"op": self.op,
407413
"description": self.description,
408414
}
409-
410-
if "status" in self._tags:
411-
rv["status"] = self._tags["status"]
415+
if self.status:
416+
rv["status"] = self.status
412417

413418
return rv
414419

tests/test_tracing.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ def test_basic(sentry_init, capture_events, sample_rate):
1212
sentry_init(traces_sample_rate=sample_rate)
1313
events = capture_events()
1414

15-
with Hub.current.start_span(transaction="hi"):
15+
with Hub.current.start_span(transaction="hi") as span:
16+
span.set_status("ok")
1617
with pytest.raises(ZeroDivisionError):
1718
with Hub.current.start_span(op="foo", description="foodesc"):
1819
1 / 0
@@ -32,6 +33,8 @@ def test_basic(sentry_init, capture_events, sample_rate):
3233
assert span2["op"] == "bar"
3334
assert span2["description"] == "bardesc"
3435
assert parent_span["transaction"] == "hi"
36+
assert "status" not in event["tags"]
37+
assert event["contexts"]["trace"]["status"] == "ok"
3538
else:
3639
assert not events
3740

0 commit comments

Comments
 (0)