54 Commits 999cd524de ... 83b493d1ba

Author SHA1 Message Date
  Arthur Knaus 83b493d1ba Merge remote-tracking branch 'origin/master' into aknaus/feat/metrics-extraction/selectable-aggregates 5 days ago
  ArthurKnaus 8268d1fe1d feat(metrics-extraction): Change extraction condition to object (#73419) 5 days ago
  Vjeran Grozdanić b2cd1452ec fix(metrics) Prevent negative crash_free_rate value to be returned to the client (#73353) 5 days ago
  Priscila Oliveira 03fcab02fa feat(settings-metrics): Add extrapolate metrics field (#73287) 5 days ago
  Ogi b750c60cfb fix(metrics): skip dot escape for tags (#73371) 5 days ago
  Riccardo Busetti b7abc00cd0 chore(dynamic-sampling): Remove logging used for debugging (#73368) 5 days ago
  Priscila Oliveira c4b844e52a ref(settings-debug-files): Convert to functional component (#73269) 5 days ago
  xurui-c bb8a74e922 Add CapMan metadata as tags to Sentry spans (#73331) 6 days ago
  Scott Cooper e5e2877185 feat(u2f): Register fallback promises (#73400) 6 days ago
  Josh Callender ebddda6a3a Project Setting Template Options Manager (#73392) 6 days ago
  Josh Ferge ba7fcabdee perf(similarity): use mulithreadpool to do nodestore calls concurrently (#73394) 6 days ago
  Michelle Zhang 2de72df456 ref(transactions/replay): fix replay tab query error (#73407) 6 days ago
  Mark Story d44fe31e13 chore(hybridcloud) Move apigateway middleware (#73396) 6 days ago
  Cathy Teng aa811f490d chore(slack): check if we can remove support for dialog_submission (#73401) 6 days ago
  Jodi Jang 34c5f0bd06 feat(similarity): Add delete record by hash task (#72767) 6 days ago
  edwardgou-sentry 6c95799bd9 fix(insights): removes unneeded empty state logic from Web Vitals module (#73375) 6 days ago
  Raj Joshi d13db8c2a0 feat(slack): Show culprit in notifications (#72980) 6 days ago
  Kevin Liu a8a4d7c133 feat(insights): add project has_insight_xx flags to frontend (#73199) 6 days ago
  Michelle Zhang f9306341ef feat(replay): add playback speed for mobile (#73343) 6 days ago
  edwardgou-sentry 449de6fc39 chore(insights): deletes unused hooks and wrappers from the web vitals module (#73380) 6 days ago
  getsentry-bot 1283be2f0c Revert "chore(chartcuterie): Slightly Modify Styles to Test Charcuterie Deployments (#73337)" 6 days ago
  Jenn Mueng 5b1e661963 feat(autofix): Add frontend for iterative user feedback (#72362) 6 days ago
  Raj Joshi 3e1fd621b2 fix(slack): Update How we Iterate to Slack Response in `users.list` (#73387) 6 days ago
  Cathy Teng c22b90f97b chore(slack): completely remove block kit flag (#73382) 6 days ago
  Tony Xiao c0a403a1c5 chore(perf): Add give feedback button (#73391) 6 days ago
  Jonas ade63b942a ref(trace) use event emitter to schedule events (#73284) 6 days ago
  Jenn Mueng a2c96d4822 fix(autofix): Graceful error state for no root causes (#73390) 6 days ago
  Mark Story fac6ccfb19 fix(typing) Fix typing errors in master (#73388) 6 days ago
  edwardgou-sentry 1dcce955b6 fix(performance): fix issue with mobile widget breaking due to non unique series names (#73385) 6 days ago
  William Mak 6e3cddfd06 ref: remove is_alerts_query (#73313) 6 days ago
  Athena Moghaddam c578ecbc7d feat[apis]: Clean-up events endpoints (#73365) 6 days ago
  Mark Story 09630273c9 chore(hybridcloud) Add sentry.hybridcloud.* to stronglist (#73377) 6 days ago
  Jonas 65823bf106 fix(trace): double zoom on click (#73374) 6 days ago
  Malachi Willey ae41258747 feat(query-builder): Add absolute date picker for date filters (#73321) 6 days ago
  Kevin Liu 1b212f1816 feat(web-vitals): add mobile browser vital percentiles (#73298) 6 days ago
  Scott Cooper ec62a89112 feat(u2f): Await bootstrap promises (#73315) 6 days ago
  Jodi Jang 4c410cac60 feat(similarity): Add delete record by hash endpoint (#71571) 6 days ago
  Mark Story 83bc355e4f chore(hybridcloud) Move RpcModel and utilities to sentry.hybridcloud (#73300) 6 days ago
  Cathy Teng a741388c40 chore(slack): remove block kit flag for handling group actions (#73248) 6 days ago
  Kevin Liu 3bdbbf37d4 feat(insights): return has_insights_xx flag in project serializers (#73197) 6 days ago
  Raj Joshi 9555078216 chore(chartcuterie): Slightly Modify Styles to Test Charcuterie Deployments (#73337) 6 days ago
  Tony Xiao ac249b58ec chore(profiling): Remove unhelpful unsupported platform alert (#73372) 6 days ago
  anthony sottile 14ce11a329 ref: fix HC stronglist entries (#73369) 6 days ago
  Mark Story 9bed2a9d4a chore(hybridcloud) Remove rpcmetrics module (#73319) 6 days ago
  getsentry-bot f5893f70a7 Revert "chore(on-demand-metrics): add prefill metric (#73278)" 6 days ago
  Priscila Oliveira 1a75611341 feat(settings-metrics): Add project/organization option extrapolatedMetrics (#73289) 6 days ago
  Anton Pirker 801a32dbb9 Update Sentry Python SDK to version 2.7.0 (#73366) 6 days ago
  ArthurKnaus 5499277c21 feat(metrics): Rename totals column (#73363) 6 days ago
  Daniel Szoke f35a642f5a ref(relay): Remove Hub API from Relay config (#73360) 6 days ago
  Daniel Szoke 4c64279c69 ref(utils): Replace Hub with Isolation Scopes in Snuba utils (#73279) 6 days ago
  Priscila Oliveira 95d861325a ref(settings-metrics): Show deprecated tag if alternative available (#73352) 6 days ago
  ArthurKnaus 28474fe686 feat(metrics-extraction): Hide known numeric tags from tag selection (#73358) 6 days ago
  Daniel Szoke 1270308b57 ref: Remove Hub from project configs endpoints (#73357) 6 days ago
  Daniel Szoke 05436019a7 ref(utils): Replace Hub with isolation scope in concurrent utils (#73275) 6 days ago

+ 1 - 7
pyproject.toml

@@ -528,10 +528,7 @@ module = [
     "sentry.grouping.component",
     "sentry.grouping.component",
     "sentry.grouping.fingerprinting",
     "sentry.grouping.fingerprinting",
     "sentry.grouping.parameterization",
     "sentry.grouping.parameterization",
-    "sentry.hybridcloud",
-    "sentry.hybridcloud.migrations.*",
-    "sentry.hybridcloud.options",
-    "sentry.hybridcloud.rpc_services.*",
+    "sentry.hybridcloud.*",
     "sentry.issues",
     "sentry.issues",
     "sentry.issues.analytics",
     "sentry.issues.analytics",
     "sentry.issues.apps",
     "sentry.issues.apps",
@@ -596,14 +593,11 @@ module = [
     "sentry.services.hybrid_cloud.orgauthtoken.*",
     "sentry.services.hybrid_cloud.orgauthtoken.*",
     "sentry.services.hybrid_cloud.project.*",
     "sentry.services.hybrid_cloud.project.*",
     "sentry.services.hybrid_cloud.project_key.*",
     "sentry.services.hybrid_cloud.project_key.*",
-    "sentry.services.hybrid_cloud.region",
     "sentry.services.hybrid_cloud.replica.*",
     "sentry.services.hybrid_cloud.replica.*",
     "sentry.services.hybrid_cloud.repository.*",
     "sentry.services.hybrid_cloud.repository.*",
-    "sentry.services.hybrid_cloud.rpcmetrics",
     "sentry.services.hybrid_cloud.tombstone.*",
     "sentry.services.hybrid_cloud.tombstone.*",
     "sentry.services.hybrid_cloud.user.*",
     "sentry.services.hybrid_cloud.user.*",
     "sentry.services.hybrid_cloud.user_option.*",
     "sentry.services.hybrid_cloud.user_option.*",
-    "sentry.services.hybrid_cloud.util",
     "sentry.snuba.metrics.extraction",
     "sentry.snuba.metrics.extraction",
     "sentry.stacktraces.platform",
     "sentry.stacktraces.platform",
     "sentry.tasks.beacon",
     "sentry.tasks.beacon",

+ 1 - 1
requirements-base.txt

@@ -66,7 +66,7 @@ sentry-kafka-schemas>=0.1.93
 sentry-ophio==0.2.7
 sentry-ophio==0.2.7
 sentry-redis-tools>=0.1.7
 sentry-redis-tools>=0.1.7
 sentry-relay>=0.8.67
 sentry-relay>=0.8.67
-sentry-sdk>=2.6.0
+sentry-sdk>=2.7.0
 slack-sdk>=3.27.2
 slack-sdk>=3.27.2
 snuba-sdk>=2.0.33
 snuba-sdk>=2.0.33
 simplejson>=3.17.6
 simplejson>=3.17.6

+ 1 - 1
requirements-dev-frozen.txt

@@ -186,7 +186,7 @@ sentry-kafka-schemas==0.1.93
 sentry-ophio==0.2.7
 sentry-ophio==0.2.7
 sentry-redis-tools==0.1.7
 sentry-redis-tools==0.1.7
 sentry-relay==0.8.67
 sentry-relay==0.8.67
-sentry-sdk==2.6.0
+sentry-sdk==2.7.0
 sentry-usage-accountant==0.0.10
 sentry-usage-accountant==0.0.10
 simplejson==3.17.6
 simplejson==3.17.6
 six==1.16.0
 six==1.16.0

+ 1 - 1
requirements-frozen.txt

@@ -127,7 +127,7 @@ sentry-kafka-schemas==0.1.93
 sentry-ophio==0.2.7
 sentry-ophio==0.2.7
 sentry-redis-tools==0.1.7
 sentry-redis-tools==0.1.7
 sentry-relay==0.8.67
 sentry-relay==0.8.67
-sentry-sdk==2.6.0
+sentry-sdk==2.7.0
 sentry-usage-accountant==0.0.10
 sentry-usage-accountant==0.0.10
 simplejson==3.17.6
 simplejson==3.17.6
 six==1.16.0
 six==1.16.0

+ 1 - 3
src/sentry/api/base.py

@@ -46,7 +46,6 @@ from sentry.utils.http import (
 )
 )
 from sentry.utils.sdk import capture_exception, merge_context_into_scope
 from sentry.utils.sdk import capture_exception, merge_context_into_scope
 
 
-from ..services.hybrid_cloud import rpcmetrics
 from ..utils.pagination_factory import (
 from ..utils.pagination_factory import (
     annotate_span_with_pagination_args,
     annotate_span_with_pagination_args,
     clamp_pagination_per_page,
     clamp_pagination_per_page,
@@ -449,8 +448,7 @@ class Endpoint(APIView):
                     getattr(part, "__name__", None) or str(part) for part in (type(self), handler)
                     getattr(part, "__name__", None) or str(part) for part in (type(self), handler)
                 ),
                 ),
             ) as span:
             ) as span:
-                with rpcmetrics.wrap_sdk_span(span):
-                    response = handler(request, *args, **kwargs)
+                response = handler(request, *args, **kwargs)
 
 
         except Exception as exc:
         except Exception as exc:
             response = self.handle_exception(request, exc)
             response = self.handle_exception(request, exc)

+ 4 - 1
src/sentry/api/endpoints/organization_details.py

@@ -36,6 +36,7 @@ from sentry.constants import (
     DATA_CONSENT_DEFAULT,
     DATA_CONSENT_DEFAULT,
     DEBUG_FILES_ROLE_DEFAULT,
     DEBUG_FILES_ROLE_DEFAULT,
     EVENTS_MEMBER_ADMIN_DEFAULT,
     EVENTS_MEMBER_ADMIN_DEFAULT,
+    EXTRAPOLATE_METRICS_DEFAULT,
     GITHUB_COMMENT_BOT_DEFAULT,
     GITHUB_COMMENT_BOT_DEFAULT,
     ISSUE_ALERTS_THREAD_DEFAULT,
     ISSUE_ALERTS_THREAD_DEFAULT,
     JOIN_REQUESTS_DEFAULT,
     JOIN_REQUESTS_DEFAULT,
@@ -52,6 +53,7 @@ from sentry.constants import (
     SENSITIVE_FIELDS_DEFAULT,
     SENSITIVE_FIELDS_DEFAULT,
 )
 )
 from sentry.datascrubbing import validate_pii_config_update, validate_pii_selectors
 from sentry.datascrubbing import validate_pii_config_update, validate_pii_selectors
+from sentry.hybridcloud.rpc import IDEMPOTENCY_KEY_LENGTH
 from sentry.integrations.utils.codecov import has_codecov_integration
 from sentry.integrations.utils.codecov import has_codecov_integration
 from sentry.lang.native.utils import (
 from sentry.lang.native.utils import (
     STORE_CRASH_REPORTS_DEFAULT,
     STORE_CRASH_REPORTS_DEFAULT,
@@ -63,7 +65,6 @@ from sentry.models.options.organization_option import OrganizationOption
 from sentry.models.organization import Organization, OrganizationStatus
 from sentry.models.organization import Organization, OrganizationStatus
 from sentry.models.scheduledeletion import RegionScheduledDeletion
 from sentry.models.scheduledeletion import RegionScheduledDeletion
 from sentry.models.useremail import UserEmail
 from sentry.models.useremail import UserEmail
-from sentry.services.hybrid_cloud import IDEMPOTENCY_KEY_LENGTH
 from sentry.services.hybrid_cloud.auth import auth_service
 from sentry.services.hybrid_cloud.auth import auth_service
 from sentry.services.hybrid_cloud.organization import organization_service
 from sentry.services.hybrid_cloud.organization import organization_service
 from sentry.services.hybrid_cloud.organization.model import (
 from sentry.services.hybrid_cloud.organization.model import (
@@ -204,6 +205,7 @@ ORG_OPTIONS = (
         bool,
         bool,
         METRICS_ACTIVATE_LAST_FOR_GAUGES_DEFAULT,
         METRICS_ACTIVATE_LAST_FOR_GAUGES_DEFAULT,
     ),
     ),
+    ("extrapolateMetrics", "sentry:extrapolate_metrics", bool, EXTRAPOLATE_METRICS_DEFAULT),
 )
 )
 
 
 DELETION_STATUSES = frozenset(
 DELETION_STATUSES = frozenset(
@@ -262,6 +264,7 @@ class OrganizationSerializer(BaseOrganizationSerializer):
     allowJoinRequests = serializers.BooleanField(required=False)
     allowJoinRequests = serializers.BooleanField(required=False)
     relayPiiConfig = serializers.CharField(required=False, allow_blank=True, allow_null=True)
     relayPiiConfig = serializers.CharField(required=False, allow_blank=True, allow_null=True)
     apdexThreshold = serializers.IntegerField(min_value=1, required=False)
     apdexThreshold = serializers.IntegerField(min_value=1, required=False)
+    extrapolateMetrics = serializers.BooleanField(required=False)
 
 
     @cached_property
     @cached_property
     def _has_legacy_rate_limits(self):
     def _has_legacy_rate_limits(self):

+ 1 - 0
src/sentry/api/endpoints/organization_events.py

@@ -194,6 +194,7 @@ class OrganizationEventsEndpoint(OrganizationEventsV2EndpointBase):
     publish_status = {
     publish_status = {
         "GET": ApiPublishStatus.PUBLIC,
         "GET": ApiPublishStatus.PUBLIC,
     }
     }
+    snuba_methods = ["GET"]
 
 
     enforce_rate_limit = True
     enforce_rate_limit = True
 
 

+ 3 - 1
src/sentry/api/endpoints/organization_events_meta.py

@@ -23,6 +23,7 @@ class OrganizationEventsMetaEndpoint(OrganizationEventsEndpointBase):
     publish_status = {
     publish_status = {
         "GET": ApiPublishStatus.PRIVATE,
         "GET": ApiPublishStatus.PRIVATE,
     }
     }
+    snuba_methods = ["GET"]
 
 
     def get(self, request: Request, organization) -> Response:
     def get(self, request: Request, organization) -> Response:
         try:
         try:
@@ -37,7 +38,7 @@ class OrganizationEventsMetaEndpoint(OrganizationEventsEndpointBase):
                 selected_columns=["count()"],
                 selected_columns=["count()"],
                 params=params,
                 params=params,
                 query=request.query_params.get("query"),
                 query=request.query_params.get("query"),
-                referrer="api.organization-events-meta",
+                referrer=Referrer.API_ORGANIZATION_EVENTS_META.value,
             )
             )
 
 
         return Response({"count": result["data"][0]["count"]})
         return Response({"count": result["data"][0]["count"]})
@@ -114,6 +115,7 @@ class OrganizationSpansSamplesEndpoint(OrganizationEventsEndpointBase):
     publish_status = {
     publish_status = {
         "GET": ApiPublishStatus.PRIVATE,
         "GET": ApiPublishStatus.PRIVATE,
     }
     }
+    snuba_methods = ["GET"]
 
 
     def get(self, request: Request, organization) -> Response:
     def get(self, request: Request, organization) -> Response:
         try:
         try:

+ 1 - 0
src/sentry/api/endpoints/organization_events_stats.py

@@ -111,6 +111,7 @@ class OrganizationEventsStatsEndpoint(OrganizationEventsV2EndpointBase):
     publish_status = {
     publish_status = {
         "GET": ApiPublishStatus.UNKNOWN,
         "GET": ApiPublishStatus.UNKNOWN,
     }
     }
+    sunba_methods = ["GET"]
 
 
     def get_features(self, organization: Organization, request: Request) -> Mapping[str, bool]:
     def get_features(self, organization: Organization, request: Request) -> Mapping[str, bool]:
         feature_names = [
         feature_names = [

+ 10 - 5
src/sentry/api/endpoints/organization_events_trace.py

@@ -277,7 +277,9 @@ class TraceEvent:
                         selected_columns=["occurrence_id"],
                         selected_columns=["occurrence_id"],
                     )
                     )
                     occurrence_ids = occurrence_query.process_results(
                     occurrence_ids = occurrence_query.process_results(
-                        occurrence_query.run_query("api.trace-view.get-occurrence-ids")
+                        occurrence_query.run_query(
+                            referrer=Referrer.API_TRACE_VIEW_GET_OCCURRENCE_IDS.value
+                        )
                     )["data"]
                     )["data"]
 
 
                     issue_occurrences = IssueOccurrence.fetch_multi(
                     issue_occurrences = IssueOccurrence.fetch_multi(
@@ -470,7 +472,9 @@ def count_performance_issues(trace_id: str, params: Mapping[str, str]) -> int:
         limit=MAX_TRACE_SIZE,
         limit=MAX_TRACE_SIZE,
     )
     )
     transaction_query.columns.append(Function("count()", alias="total_groups"))
     transaction_query.columns.append(Function("count()", alias="total_groups"))
-    count = transaction_query.run_query("api.trace-view.count-performance-issues")
+    count = transaction_query.run_query(
+        referrer=Referrer.API_TRACE_VIEW_COUNT_PERFORMANCE_ISSUES.value
+    )
     return count["data"][0].get("total_groups", 0)
     return count["data"][0].get("total_groups", 0)
 
 
 
 
@@ -627,7 +631,7 @@ def query_trace_data(
             error_query.get_snql_query(),
             error_query.get_snql_query(),
             occurrence_query.get_snql_query(),
             occurrence_query.get_snql_query(),
         ],
         ],
-        referrer="api.trace-view.get-events",
+        referrer=Referrer.API_TRACE_VIEW_GET_EVENTS.value,
     )
     )
 
 
     transformed_results = [
     transformed_results = [
@@ -837,7 +841,7 @@ def augment_transactions_with_spans(
             referrer=Referrer.API_TRACE_VIEW_GET_PARENTS.value,
             referrer=Referrer.API_TRACE_VIEW_GET_PARENTS.value,
         )
         )
         parents_results = results[0]
         parents_results = results[0]
-        for (result, query) in zip(results, queries):
+        for result, query in zip(results, queries):
             if len(result["data"]) == query.limit.limit:
             if len(result["data"]) == query.limit.limit:
                 hit_limit = True
                 hit_limit = True
         for result in results[1:]:
         for result in results[1:]:
@@ -887,6 +891,7 @@ class OrganizationEventsTraceEndpointBase(OrganizationEventsV2EndpointBase):
     publish_status = {
     publish_status = {
         "GET": ApiPublishStatus.PRIVATE,
         "GET": ApiPublishStatus.PRIVATE,
     }
     }
+    snuba_methods = ["GET"]
 
 
     def get_projects(self, request: Request, organization, project_ids=None, project_slugs=None):
     def get_projects(self, request: Request, organization, project_ids=None, project_slugs=None):
         """The trace endpoint always wants to get all projects regardless of what's passed into the API
         """The trace endpoint always wants to get all projects regardless of what's passed into the API
@@ -1601,7 +1606,7 @@ class OrganizationEventsTraceMetaEndpoint(OrganizationEventsTraceEndpointBase):
                 params=params,
                 params=params,
                 query=f"trace:{trace_id}",
                 query=f"trace:{trace_id}",
                 limit=1,
                 limit=1,
-                referrer="api.trace-view.get-meta",
+                referrer=Referrer.API_TRACE_VIEW_GET_META.value,
             )
             )
             if len(result["data"]) == 0:
             if len(result["data"]) == 0:
                 return Response(status=404)
                 return Response(status=404)

Some files were not shown because too many files changed in this diff