|
3 | 3 | from collections.abc import Mapping |
4 | 4 | from typing import Any |
5 | 5 |
|
6 | | -import orjson |
7 | | - |
8 | | -from sentry.attachments import CachedAttachment, attachment_cache |
9 | | -from sentry.ingest.consumer.processors import CACHE_TIMEOUT |
10 | 6 | from sentry.lang.java.utils import JAVA_PLATFORMS, get_jvm_images, get_proguard_images |
| 7 | +from sentry.lang.java.view_hierarchies import ViewHierarchies |
11 | 8 | from sentry.lang.native.error import SymbolicationFailed, write_error |
12 | 9 | from sentry.lang.native.symbolicator import Symbolicator |
13 | 10 | from sentry.models.eventerror import EventError |
14 | 11 | from sentry.models.project import Project |
15 | 12 | from sentry.models.release import Release |
16 | 13 | from sentry.stacktraces.processing import find_stacktraces_in_data |
17 | 14 | from sentry.utils import metrics |
18 | | -from sentry.utils.cache import cache_key_for_event |
19 | 15 | from sentry.utils.safe import get_path |
20 | 16 |
|
21 | 17 | logger = logging.getLogger(__name__) |
@@ -150,76 +146,6 @@ def _get_release_package(project: Project, release_name: str | None) -> str | No |
150 | 146 | return release.package if release else None |
151 | 147 |
|
152 | 148 |
|
153 | | -def _get_window_class_names(attachments: list[CachedAttachment]) -> list[str]: |
154 | | - """Returns the class names of all windows in all view hierarchies |
155 | | - contained in `attachments`.""" |
156 | | - |
157 | | - class_names = [] |
158 | | - windows_to_deobfuscate = [] |
159 | | - |
160 | | - for attachment in attachments: |
161 | | - if attachment.type == "event.view_hierarchy": |
162 | | - view_hierarchy = orjson.loads(attachment_cache.get_data(attachment)) |
163 | | - windows_to_deobfuscate.extend(view_hierarchy.get("windows")) |
164 | | - |
165 | | - while windows_to_deobfuscate: |
166 | | - window = windows_to_deobfuscate.pop() |
167 | | - if window.get("type") is not None: |
168 | | - class_names.append(window["type"]) |
169 | | - if children := window.get("children"): |
170 | | - windows_to_deobfuscate.extend(children) |
171 | | - |
172 | | - return class_names |
173 | | - |
174 | | - |
175 | | -def _deobfuscate_view_hierarchy(view_hierarchy: Any, class_names: dict[str, str]) -> None: |
176 | | - """Deobfuscates a view hierarchy in-place. |
177 | | -
|
178 | | - The `class_names` dict is used to resolve obfuscated to deobfuscated names. If |
179 | | - an obfuscated class name isn't present in `class_names`, it is left unchanged.""" |
180 | | - |
181 | | - windows_to_deobfuscate = [*view_hierarchy.get("windows")] |
182 | | - |
183 | | - while windows_to_deobfuscate: |
184 | | - window = windows_to_deobfuscate.pop() |
185 | | - if ( |
186 | | - window.get("type") is not None |
187 | | - and (mapped_type := class_names.get(window["type"])) is not None |
188 | | - ): |
189 | | - window["type"] = mapped_type |
190 | | - if children := window.get("children"): |
191 | | - windows_to_deobfuscate.extend(children) |
192 | | - |
193 | | - |
194 | | -def _deobfuscate_view_hierarchies( |
195 | | - attachments: list[CachedAttachment], class_names: dict[str, str] |
196 | | -) -> list[CachedAttachment]: |
197 | | - """Deobfuscates all view hierarchies contained in `attachments`, returning a new list of attachments. |
198 | | -
|
199 | | - Non-view-hierarchy attachments are unchanged. |
200 | | - """ |
201 | | - new_attachments = [] |
202 | | - for attachment in attachments: |
203 | | - if attachment.type == "event.view_hierarchy": |
204 | | - view_hierarchy = orjson.loads(attachment_cache.get_data(attachment)) |
205 | | - _deobfuscate_view_hierarchy(view_hierarchy, class_names) |
206 | | - # Reupload to cache as a unchunked data |
207 | | - new_attachments.append( |
208 | | - CachedAttachment( |
209 | | - type=attachment.type, |
210 | | - id=attachment.id, |
211 | | - name=attachment.name, |
212 | | - content_type=attachment.content_type, |
213 | | - data=orjson.dumps(view_hierarchy), |
214 | | - chunks=None, |
215 | | - ) |
216 | | - ) |
217 | | - else: |
218 | | - new_attachments.append(attachment) |
219 | | - |
220 | | - return new_attachments |
221 | | - |
222 | | - |
223 | 149 | def map_symbolicator_process_jvm_errors( |
224 | 150 | errors: list[dict[str, Any]] | None, |
225 | 151 | ) -> list[dict[str, Any]]: |
@@ -276,9 +202,8 @@ def process_jvm_stacktraces(symbolicator: Symbolicator, data: Any) -> Any: |
276 | 202 | ] |
277 | 203 |
|
278 | 204 | processable_exceptions = _get_exceptions_for_symbolication(data) |
279 | | - cache_key = cache_key_for_event(data) |
280 | | - attachments = [*attachment_cache.get(cache_key)] |
281 | | - window_class_names = _get_window_class_names(attachments) |
| 205 | + view_hierarchies = ViewHierarchies(data) |
| 206 | + window_class_names = view_hierarchies.get_window_class_names() |
282 | 207 |
|
283 | 208 | metrics.incr("proguard.symbolicator.events") |
284 | 209 |
|
@@ -341,7 +266,6 @@ def process_jvm_stacktraces(symbolicator: Symbolicator, data: Any) -> Any: |
341 | 266 | raw_exc["type"] = exc["type"] |
342 | 267 |
|
343 | 268 | classes = response.get("classes") |
344 | | - new_attachments = _deobfuscate_view_hierarchies(attachments, classes) |
345 | | - attachment_cache.set(cache_key, attachments=new_attachments, timeout=CACHE_TIMEOUT) |
| 269 | + view_hierarchies.deobfuscate_and_save(classes) |
346 | 270 |
|
347 | 271 | return data |
0 commit comments