Skip to content

Commit f425934

Browse files
authored
feat(objectstore): Improve host rewriting (#103964)
1 parent 2a1a7bf commit f425934

File tree

2 files changed

+53
-18
lines changed

2 files changed

+53
-18
lines changed

src/sentry/lang/native/symbolicator.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,9 @@
2626
from sentry.lang.native.utils import Backoff
2727
from sentry.models.project import Project
2828
from sentry.net.http import Session
29-
from sentry.objectstore import get_attachments_session
29+
from sentry.objectstore import get_attachments_session, get_symbolicator_url
3030
from sentry.options.rollout import in_random_rollout
3131
from sentry.utils import metrics
32-
from sentry.utils.env import in_test_environment
3332

3433
MAX_ATTEMPTS = 3
3534

@@ -198,8 +197,7 @@ def process_minidump(
198197

199198
if minidump.stored_id:
200199
session = get_attachments_session(self.project.organization_id, self.project.id)
201-
storage_url = session.object_url(minidump.stored_id)
202-
storage_url = maybe_rewrite_objectstore_url(storage_url)
200+
storage_url = get_symbolicator_url(session, minidump.stored_id)
203201
json: dict[str, Any] = {
204202
"platform": platform,
205203
"sources": sources,
@@ -244,8 +242,7 @@ def process_applecrashreport(self, platform: str, report: CachedAttachment):
244242

245243
if report.stored_id:
246244
session = get_attachments_session(self.project.organization_id, self.project.id)
247-
storage_url = session.object_url(report.stored_id)
248-
storage_url = maybe_rewrite_objectstore_url(storage_url)
245+
storage_url = get_symbolicator_url(session, report.stored_id)
249246
json: dict[str, Any] = {
250247
"platform": platform,
251248
"sources": sources,
@@ -540,15 +537,3 @@ def query_task(self, task_id):
540537

541538
def reset_worker_id(self):
542539
self.worker_id = uuid.uuid4().hex
543-
544-
545-
def maybe_rewrite_objectstore_url(url: str) -> str:
546-
"""
547-
This is needed during development/testing to make Symbolicator reach Objectstore.
548-
This is because Sentry can reach Objectstore on 127.0.0.1 but Symbolicator cannot, as it's running in its own container.
549-
550-
Note: if you are using a local (not containerized) instance of Symbolicator, you need to disable this logic.
551-
"""
552-
if settings.IS_DEV or in_test_environment():
553-
url = url.replace("127.0.0.1", "objectstore")
554-
return url

src/sentry/objectstore/__init__.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
import subprocess
12
from datetime import timedelta
3+
from urllib.parse import urlparse, urlunparse
24

5+
from django.conf import settings
36
from objectstore_client import Client, MetricsBackend, Session, TimeToLive, Usecase
47
from objectstore_client.metrics import Tags
58

69
from sentry.utils import metrics as sentry_metrics
10+
from sentry.utils.env import in_test_environment
711

812
__all__ = ["get_attachments_session"]
913

@@ -49,3 +53,49 @@ def get_attachments_session(org: int, project: int) -> Session:
4953
)
5054

5155
return _ATTACHMENTS_CLIENT.session(_ATTACHMENTS_USECASE, org=org, project=project)
56+
57+
58+
_IS_SYMBOLICATOR_CONTAINER: bool | None = None
59+
60+
61+
def get_symbolicator_url(session: Session, key: str) -> str:
62+
"""
63+
Gets the URL that Symbolicator shall use to access the object at the given key in Objectstore.
64+
65+
In prod, this is simply the `object_url` returned by `objectstore_client`, as both Sentry and Symbolicator
66+
will talk to Objectstore using the same hostname.
67+
68+
While in development or testing, we might need to replace the hostname, depending on how Symbolicator is running.
69+
This function runs a `docker ps` to automatically return the correct URL in the following 2 cases:
70+
- Symbolicator running in Docker (possibly via `devservices`) -- this mirrors `sentry`'s CI.
71+
If this is detected, we replace Objectstore's hostname with the one reachable in the Docker network.
72+
73+
Note that this approach doesn't work if Objectstore is running both locally and in Docker, as we'll always
74+
rewrite the URL to the Docker one, so Sentry and Symbolicator might attempt to talk to 2 different Objectstores.
75+
- Symbolicator running locally -- this mirrors `symbolicator`'s CI.
76+
In this case, we don't need to rewrite the URL.
77+
"""
78+
global _IS_SYMBOLICATOR_CONTAINER # Cached to avoid running `docker ps` multiple times
79+
80+
url = session.object_url(key)
81+
if not (settings.IS_DEV or in_test_environment()):
82+
return url
83+
84+
if _IS_SYMBOLICATOR_CONTAINER is None:
85+
try:
86+
docker_ps = subprocess.run(
87+
["docker", "ps", "--format", "{{.Names}}"], capture_output=True, text=True
88+
)
89+
_IS_SYMBOLICATOR_CONTAINER = "symbolicator" in docker_ps.stdout
90+
except Exception:
91+
_IS_SYMBOLICATOR_CONTAINER = False
92+
93+
if not _IS_SYMBOLICATOR_CONTAINER:
94+
return url
95+
96+
replacement = "objectstore"
97+
parsed = urlparse(url)
98+
if parsed.port:
99+
replacement += f":{parsed.port}"
100+
updated = parsed._replace(netloc=replacement)
101+
return urlunparse(updated)

0 commit comments

Comments
 (0)