|
4 | 4 | from datetime import datetime
|
5 | 5 | from itertools import islice
|
6 | 6 | import socket
|
| 7 | +import json |
7 | 8 |
|
8 | 9 | from sentry_sdk._compat import string_types, text_type, iteritems
|
9 | 10 | from sentry_sdk.utils import (
|
10 | 11 | capture_internal_exceptions,
|
11 | 12 | current_stacktrace,
|
12 | 13 | disable_capture_event,
|
13 | 14 | format_timestamp,
|
| 15 | + from_base64, |
14 | 16 | get_type_name,
|
15 | 17 | get_default_release,
|
16 | 18 | handle_in_app,
|
@@ -338,16 +340,36 @@ def capture_event(
|
338 | 340 |
|
339 | 341 | attachments = hint.get("attachments")
|
340 | 342 | is_transaction = event_opt.get("type") == "transaction"
|
| 343 | + raw_tracestate = ( |
| 344 | + event_opt.get("contexts", {}).get("trace", {}).pop("tracestate", None) |
| 345 | + ) |
341 | 346 |
|
342 | 347 | if is_transaction or attachments:
|
343 | 348 | # Transactions or events with attachments should go to the
|
344 | 349 | # /envelope/ endpoint.
|
345 |
| - envelope = Envelope( |
346 |
| - headers={ |
347 |
| - "event_id": event_opt["event_id"], |
348 |
| - "sent_at": format_timestamp(datetime.utcnow()), |
349 |
| - } |
350 |
| - ) |
| 350 | + headers = { |
| 351 | + "event_id": event_opt["event_id"], |
| 352 | + "sent_at": format_timestamp(datetime.utcnow()), |
| 353 | + } |
| 354 | + |
| 355 | + if raw_tracestate: |
| 356 | + # Base64-encoded strings always come out with a length which is a multiple |
| 357 | + # of 4. In order to achieve this, the end is padded with one or more `=` |
| 358 | + # signs. Because the tracestate standard calls for using `=` signs between |
| 359 | + # vendor name and value (`sentry=xxx,dogsaregreat=yyy`), to avoid confusion |
| 360 | + # we strip the `=` when the data is initially encoded. Python's decoding |
| 361 | + # function requires they be put back. |
| 362 | + |
| 363 | + # The final mod 4 is necessary because 4 is represented as 4 |
| 364 | + # rather than 0. |
| 365 | + missing_equals = (4 - (len(raw_tracestate) % 4)) % 4 |
| 366 | + base64_tracestate = raw_tracestate + "=" * missing_equals |
| 367 | + |
| 368 | + tracestate_json = from_base64(base64_tracestate) |
| 369 | + |
| 370 | + headers["trace"] = json.loads(tracestate_json) |
| 371 | + |
| 372 | + envelope = Envelope(headers=headers) |
351 | 373 |
|
352 | 374 | if is_transaction:
|
353 | 375 | envelope.add_transaction(event_opt)
|
|
0 commit comments