|
@@ -53,6 +53,7 @@ from sentry.grouping.result import CalculatedHashes
|
|
|
from sentry.ingest.inbound_filters import FilterStatKeys
|
|
|
from sentry.killswitches import killswitch_matches_context
|
|
|
from sentry.lang.native.utils import STORE_CRASH_REPORTS_ALL, convert_crashreport_count
|
|
|
+from sentry.locks import locks
|
|
|
from sentry.models import (
|
|
|
CRASH_REPORT_TYPES,
|
|
|
Activity,
|
|
@@ -601,13 +602,32 @@ def _auto_update_grouping(project):
|
|
|
|
|
|
# update to latest grouping config but not if a user is already on
|
|
|
# beta.
|
|
|
- if old_grouping != new_grouping and old_grouping != BETA_GROUPING_CONFIG:
|
|
|
- project.update_option("sentry:secondary_grouping_config", old_grouping)
|
|
|
- project.update_option(
|
|
|
- "sentry:secondary_grouping_expiry",
|
|
|
- int(time.time()) + settings.SENTRY_GROUPING_UPDATE_MIGRATION_PHASE,
|
|
|
- )
|
|
|
- project.update_option("sentry:grouping_config", new_grouping)
|
|
|
+ if old_grouping == new_grouping or old_grouping == BETA_GROUPING_CONFIG:
|
|
|
+ return
|
|
|
+
|
|
|
+ from sentry import audit_log
|
|
|
+ from sentry.utils.audit import create_system_audit_entry
|
|
|
+
|
|
|
+ expiry = int(time.time()) + settings.SENTRY_GROUPING_UPDATE_MIGRATION_PHASE
|
|
|
+ project.update_option("sentry:secondary_grouping_config", old_grouping)
|
|
|
+ project.update_option("sentry:secondary_grouping_expiry", expiry)
|
|
|
+ project.update_option("sentry:grouping_config", new_grouping)
|
|
|
+
|
|
|
+ # Write an audit log entry if we haven't yet. Because the way the auto grouping upgrade
|
|
|
+ # happening is racy, we want to try to write the audit log entry only once. For this a
|
|
|
+ # cache key is used. That's not perfect, but should reduce the risk significantly.
|
|
|
+ cache_key = f"grouping-config-update:{project.id}:{old_grouping}"
|
|
|
+ lock = f"grouping-update-lock:{project.id}"
|
|
|
+ if cache.get(cache_key) is None:
|
|
|
+ with locks.get(lock, duration=60, name="grouping-update-lock").acquire():
|
|
|
+ if cache.get(cache_key) is None:
|
|
|
+ cache.set(cache_key, "1", 60 * 5)
|
|
|
+ create_system_audit_entry(
|
|
|
+ organization=project.organization,
|
|
|
+ target_object=project.id,
|
|
|
+ event=audit_log.get_event_id("PROJECT_EDIT"),
|
|
|
+ data={"sentry:grouping_config": new_grouping, **project.get_audit_log_data()},
|
|
|
+ )
|
|
|
|
|
|
|
|
|
@metrics.wraps("event_manager.background_grouping")
|