Skip to content

Commit

Permalink
feat(save_event): Always use cache for stacktrace processing (#56413)
Browse files Browse the repository at this point in the history
We enabled it for EA customers last week without any issues. It reduces
the stacktrace normalization by 40%. It's most noticeable with Native
events.
  • Loading branch information
armenzg committed Sep 19, 2023
1 parent dc18d59 commit 8bc7aec
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 41 deletions.
4 changes: 0 additions & 4 deletions src/sentry/event_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2411,14 +2411,10 @@ def _calculate_event_grouping(
Main entrypoint for modifying/enhancing and grouping an event, writes
hashes back into event payload.
"""
load_stacktrace_from_cache = bool(event.org_can_load_stacktrace_from_cache)
metric_tags: MutableTags = {
"grouping_config": grouping_config["id"],
"platform": event.platform or "unknown",
"loading_from_cache": load_stacktrace_from_cache,
}
# This will help us differentiate when a transaction uses caching vs not
sentry_sdk.set_tag("stacktrace.loaded_from_cache", load_stacktrace_from_cache)

with metrics.timer("event_manager.normalize_stacktraces_for_grouping", tags=metric_tags):
with sentry_sdk.start_span(op="event_manager.normalize_stacktraces_for_grouping"):
Expand Down
12 changes: 2 additions & 10 deletions src/sentry/eventstore/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from django.conf import settings
from django.utils.encoding import force_str

from sentry import eventtypes, features
from sentry import eventtypes
from sentry.db.models import NodeData
from sentry.grouping.result import CalculatedHashes
from sentry.interfaces.base import Interface, get_interfaces
Expand Down Expand Up @@ -419,11 +419,7 @@ def normalize_stacktraces_for_grouping(self, grouping_config) -> None:
"""
from sentry.stacktraces.processing import normalize_stacktraces_for_grouping

normalize_stacktraces_for_grouping(
self.data,
grouping_config,
load_stacktrace_from_cache=self.org_can_load_stacktrace_from_cache,
)
normalize_stacktraces_for_grouping(self.data, grouping_config)

# We have modified event data, so any cached interfaces have to be reset:
self.__dict__.pop("interfaces", None)
Expand Down Expand Up @@ -491,10 +487,6 @@ def get_span_groupings(
def organization(self) -> Organization:
return self.project.organization

@property
def org_can_load_stacktrace_from_cache(self) -> bool:
return features.has("organizations:stacktrace-processing-caching", self.organization)

@property
def version(self) -> str:
return cast(str, self.data.get("version", "5"))
Expand Down
27 changes: 6 additions & 21 deletions src/sentry/grouping/enhancer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ def apply_modifications_to_frame(
platform: str,
exception_data: dict[str, Any],
extra_fingerprint: str = "",
load_stacktrace_from_cache: bool = False,
) -> None:
"""This applies the frame modifications to the frames itself. This does not affect grouping."""
in_memory_cache: dict[str, str] = {}
Expand All @@ -158,12 +157,7 @@ def apply_modifications_to_frame(
cache_key = f"stacktrace_hash.{stacktrace_fingerprint}"
use_cache = bool(stacktrace_fingerprint)
if use_cache:
frames_changed = _update_frames_from_cached_values(
frames,
cache_key,
platform,
load_from_cache=load_stacktrace_from_cache,
)
frames_changed = _update_frames_from_cached_values(frames, cache_key, platform)
if frames_changed:
logger.info("The frames have been loaded from the cache. Skipping some work.")
return
Expand Down Expand Up @@ -503,26 +497,21 @@ def visit_quoted_ident(self, node, children):


def _update_frames_from_cached_values(
frames: Sequence[dict[str, Any]], cache_key: str, platform: str, load_from_cache: bool = False
frames: Sequence[dict[str, Any]], cache_key: str, platform: str
) -> bool:
"""
This will update the frames of the stacktrace if it's been cached.
Set load_from_cache to True to actually change the frames.
Returns if the merged has correctly happened.
Returns True if the merged has correctly happened.
"""
frames_changed = False
changed_frames_values = cache.get(cache_key, {})

# This helps tracking changes in the hit/miss ratio of the cache
metrics.incr(
f"{DATADOG_KEY}.cache.get",
tags={
"success": bool(changed_frames_values),
"platform": platform,
"loading_from_cache": load_from_cache,
},
tags={"success": bool(changed_frames_values), "platform": platform},
)
if changed_frames_values and load_from_cache:
if changed_frames_values:
try:
for frame, changed_frame_values in zip(frames, changed_frames_values):
if changed_frame_values.get("in_app") is not None:
Expand All @@ -545,11 +534,7 @@ def _update_frames_from_cached_values(

metrics.incr(
f"{DATADOG_KEY}.merged_cached_values",
tags={
"success": frames_changed,
"platform": platform,
"loading_from_cache": load_from_cache,
},
tags={"success": frames_changed, "platform": platform},
)
return frames_changed

Expand Down
8 changes: 2 additions & 6 deletions src/sentry/stacktraces/processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ def _normalize_in_app(stacktrace: Sequence[dict[str, str]]) -> str:


def normalize_stacktraces_for_grouping(
data: MutableMapping[str, Any], grouping_config=None, load_stacktrace_from_cache: bool = False
data: MutableMapping[str, Any], grouping_config=None
) -> None:
"""
Applies grouping enhancement rules and ensure in_app is set on all frames.
Expand Down Expand Up @@ -341,11 +341,7 @@ def normalize_stacktraces_for_grouping(
for frames, stacktrace_container in zip(stacktrace_frames, stacktrace_containers):
# This call has a caching mechanism when the same stacktrace and rules are used
grouping_config.enhancements.apply_modifications_to_frame(
frames,
platform,
stacktrace_container,
extra_fingerprint=grouping_config.id,
load_stacktrace_from_cache=load_stacktrace_from_cache,
frames, platform, stacktrace_container, extra_fingerprint=grouping_config.id
)

# normalize `in_app` values, noting and storing the event's mix of in-app and system frames, so
Expand Down

0 comments on commit 8bc7aec

Please sign in to comment.