Skip to content

Commit a29b421

Browse files
authored
fix(logs): Set span_id instead of sentry.trace.parent_span_id attribute (#5241)
The ID of the currently active span should be set as `span_id`, top-level, on the log. The attribute `sentry.trace.parent_span_id` is the old way of sending it. The change should be safe as relay supports both.
1 parent a9d89f2 commit a29b421

File tree

9 files changed

+21
-19
lines changed

9 files changed

+21
-19
lines changed

sentry_sdk/_log_batcher.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ def format_attribute(val: "int | float | str | bool") -> "Any":
134134
res = {
135135
"timestamp": int(log["time_unix_nano"]) / 1.0e9,
136136
"trace_id": log.get("trace_id", "00000000-0000-0000-0000-000000000000"),
137+
"span_id": log.get("span_id"),
137138
"level": str(log["severity_text"]),
138139
"body": str(log["body"]),
139140
"attributes": {

sentry_sdk/_types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ class SDKInfo(TypedDict):
224224
"attributes": dict[str, str | bool | float | int],
225225
"time_unix_nano": int,
226226
"trace_id": Optional[str],
227+
"span_id": Optional[str],
227228
},
228229
)
229230

sentry_sdk/client.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -927,11 +927,8 @@ def _capture_log(self, log: "Optional[Log]") -> None:
927927
if trace_id is not None and log.get("trace_id") is None:
928928
log["trace_id"] = trace_id
929929

930-
if (
931-
span_id is not None
932-
and "sentry.trace.parent_span_id" not in log["attributes"]
933-
):
934-
log["attributes"]["sentry.trace.parent_span_id"] = span_id
930+
if span_id is not None and log.get("span_id") is None:
931+
log["span_id"] = span_id
935932

936933
# The user, if present, is always set on the isolation scope.
937934
if self.should_send_default_pii() and isolation_scope._user is not None:

sentry_sdk/integrations/logging.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,5 +404,6 @@ def _capture_log_from_record(
404404
"attributes": attrs,
405405
"time_unix_nano": int(record.created * 1e9),
406406
"trace_id": None,
407+
"span_id": None,
407408
},
408409
)

sentry_sdk/integrations/loguru.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,5 +204,6 @@ def loguru_sentry_logs_handler(message: "Message") -> None:
204204
"attributes": attrs,
205205
"time_unix_nano": int(record["time"].timestamp() * 1e9),
206206
"trace_id": None,
207+
"span_id": None,
207208
}
208209
)

sentry_sdk/logger.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def _capture_log(
6666
"body": body,
6767
"time_unix_nano": time.time_ns(),
6868
"trace_id": None,
69+
"span_id": None,
6970
},
7071
)
7172

tests/integrations/logging/test_logging.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,9 @@ def test_logger_with_all_attributes(sentry_init, capture_envelopes):
438438

439439
logs = envelopes_to_logs(envelopes)
440440

441+
assert "span_id" in logs[0]
442+
assert isinstance(logs[0]["span_id"], str)
443+
441444
attributes = logs[0]["attributes"]
442445

443446
assert "process.pid" in attributes
@@ -478,10 +481,6 @@ def test_logger_with_all_attributes(sentry_init, capture_envelopes):
478481

479482
assert attributes.pop("sentry.sdk.name").startswith("sentry.python")
480483

481-
assert "sentry.trace.parent_span_id" in attributes
482-
assert isinstance(attributes["sentry.trace.parent_span_id"], str)
483-
del attributes["sentry.trace.parent_span_id"]
484-
485484
# Assert on the remaining non-dynamic attributes.
486485
assert attributes == {
487486
"foo": "bar",

tests/integrations/loguru/test_loguru.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,9 @@ def test_logger_with_all_attributes(
418418

419419
logs = envelopes_to_logs(envelopes)
420420

421+
assert "span_id" in logs[0]
422+
assert isinstance(logs[0]["span_id"], str)
423+
421424
attributes = logs[0]["attributes"]
422425

423426
assert "process.pid" in attributes
@@ -458,10 +461,6 @@ def test_logger_with_all_attributes(
458461

459462
assert attributes.pop("sentry.sdk.name").startswith("sentry.python")
460463

461-
assert "sentry.trace.parent_span_id" in attributes
462-
assert isinstance(attributes["sentry.trace.parent_span_id"], str)
463-
del attributes["sentry.trace.parent_span_id"]
464-
465464
# Assert on the remaining non-dynamic attributes.
466465
assert attributes == {
467466
"logger.name": "tests.integrations.loguru.test_loguru",

tests/test_logs.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ def envelopes_to_logs(envelopes: List[Envelope]) -> List[Log]:
5555
"attributes": otel_attributes_to_dict(log_json["attributes"]),
5656
"time_unix_nano": int(float(log_json["timestamp"]) * 1e9),
5757
"trace_id": log_json["trace_id"],
58+
"span_id": log_json["span_id"],
5859
} # type: Log
60+
5961
res.append(log)
6062
return res
6163

@@ -142,6 +144,7 @@ def _before_log(record, hint):
142144
"attributes",
143145
"time_unix_nano",
144146
"trace_id",
147+
"span_id",
145148
}
146149

147150
if record["severity_text"] in ["fatal", "error"]:
@@ -319,7 +322,9 @@ def test_logs_tied_to_transactions(sentry_init, capture_envelopes):
319322

320323
get_client().flush()
321324
logs = envelopes_to_logs(envelopes)
322-
assert logs[0]["attributes"]["sentry.trace.parent_span_id"] == trx.span_id
325+
326+
assert "span_id" in logs[0]
327+
assert logs[0]["span_id"] == trx.span_id
323328

324329

325330
@minimum_python_37
@@ -336,7 +341,7 @@ def test_logs_tied_to_spans(sentry_init, capture_envelopes):
336341

337342
get_client().flush()
338343
logs = envelopes_to_logs(envelopes)
339-
assert logs[0]["attributes"]["sentry.trace.parent_span_id"] == span.span_id
344+
assert logs[0]["span_id"] == span.span_id
340345

341346

342347
def test_auto_flush_logs_after_100(sentry_init, capture_envelopes):
@@ -511,6 +516,7 @@ def record_lost_event(reason, data_category=None, item=None, *, quantity=1):
511516
"level": "info",
512517
"timestamp": mock.ANY,
513518
"trace_id": mock.ANY,
519+
"span_id": mock.ANY,
514520
"attributes": {
515521
"sentry.environment": {
516522
"type": "string",
@@ -536,10 +542,6 @@ def record_lost_event(reason, data_category=None, item=None, *, quantity=1):
536542
"type": "string",
537543
"value": "info",
538544
},
539-
"sentry.trace.parent_span_id": {
540-
"type": "string",
541-
"value": mock.ANY,
542-
},
543545
"server.address": {
544546
"type": "string",
545547
"value": "test-server",

0 commit comments

Comments
 (0)