Skip to content

Commit 978f32f

Browse files
committed
Merge remote-tracking branch 'origin/master' into adrian/add-test-analytics-table
2 parents e2654ca + 4091ded commit 978f32f

File tree

215 files changed

+4383
-5109
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

215 files changed

+4383
-5109
lines changed

.github/actions/setup-sentry/action.yml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,7 @@ runs:
5050
5151
### pytest configuration ###
5252
echo "PY_COLORS=1" >> "$GITHUB_ENV"
53-
# XXX(epurkihser): We've raised fail-slow from 60s to 120s since
54-
# 2025-05, our migration dependency tree has grown too large and it
55-
# takes these tests longer than 60 seconds to run. Once we've flattened
56-
# our migrations we can bring this back down (asottile is working on
57-
# this)
58-
echo "PYTEST_ADDOPTS=--reruns=5 --durations=10 --fail-slow=120s" >> $GITHUB_ENV
53+
echo "PYTEST_ADDOPTS=--reruns=5 --durations=10 --fail-slow=60s" >> $GITHUB_ENV
5954
echo "COVERAGE_CORE=sysmon" >> "$GITHUB_ENV"
6055
6156
### pytest-sentry configuration ###

migrations_lockfile.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ hybridcloud: 0021_django_arrayfield_scope_list
1313

1414
insights: 0001_add_starred_transactions_model
1515

16-
monitors: 0004_record_date_in_progress_sql_only
16+
monitors: 0005_record_date_in_progress_state
1717

1818
nodestore: 0002_nodestore_no_dictfield
1919

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"@sentry/react": "9.16.1",
6565
"@sentry/release-parser": "^1.3.1",
6666
"@sentry/status-page-list": "^0.6.0",
67-
"@sentry/webpack-plugin": "^3.1.1",
67+
"@sentry/webpack-plugin": "^3.4.0",
6868
"@spotlightjs/spotlight": "^2.0.0-alpha.1",
6969
"@tanstack/query-async-storage-persister": "^5.72.1",
7070
"@tanstack/react-query": "^5.72.1",
@@ -166,6 +166,7 @@
166166
"sprintf-js": "1.0.3",
167167
"style-loader": "4.0.0",
168168
"terser-webpack-plugin": "5.3.14",
169+
"ts-checker-rspack-plugin": "1.1.3",
169170
"ts-node": "^10.9.2",
170171
"tslib": "^2.8.1",
171172
"typescript": "^5.8.3",

pyproject.toml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,10 @@ module = [
290290
"sentry.issues.endpoints.related_issues",
291291
"sentry.issues.endpoints.shared_group_details",
292292
"sentry.issues.endpoints.team_groups_old",
293-
"sentry.issues.escalating",
294-
"sentry.issues.escalating_group_forecast",
295-
"sentry.issues.escalating_issues_alg",
296-
"sentry.issues.forecasts",
293+
"sentry.issues.escalating.escalating",
294+
"sentry.issues.escalating.escalating_group_forecast",
295+
"sentry.issues.escalating.escalating_issues_alg",
296+
"sentry.issues.escalating.forecasts",
297297
"sentry.issues.ignored",
298298
"sentry.issues.ingest",
299299
"sentry.issues.issue_occurrence",
@@ -480,16 +480,16 @@ module = [
480480
"tests.sentry.issues.endpoints.test_shared_group_details",
481481
"tests.sentry.issues.endpoints.test_source_map_debug",
482482
"tests.sentry.issues.endpoints.test_team_groups_old",
483+
"tests.sentry.issues.escalating.test_escalating",
484+
"tests.sentry.issues.escalating.test_escalating_issues_alg",
485+
"tests.sentry.issues.escalating.test_issue_velocity",
483486
"tests.sentry.issues.ownership.*",
484487
"tests.sentry.issues.test_attributes",
485-
"tests.sentry.issues.test_escalating",
486-
"tests.sentry.issues.test_escalating_issues_alg",
487488
"tests.sentry.issues.test_group_attributes_dataset",
488489
"tests.sentry.issues.test_grouptype",
489490
"tests.sentry.issues.test_ignored",
490491
"tests.sentry.issues.test_ingest",
491492
"tests.sentry.issues.test_issue_occurrence",
492-
"tests.sentry.issues.test_issue_velocity",
493493
"tests.sentry.issues.test_json_schemas",
494494
"tests.sentry.issues.test_merge",
495495
"tests.sentry.issues.test_occurrence_consumer",

rspack.config.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import rspack from '@rspack/core';
1212
import ReactRefreshRspackPlugin from '@rspack/plugin-react-refresh';
1313
import {sentryWebpackPlugin} from '@sentry/webpack-plugin';
1414
import CompressionPlugin from 'compression-webpack-plugin';
15-
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
1615
import HtmlWebpackPlugin from 'html-webpack-plugin';
1716
import fs from 'node:fs';
1817
import path from 'node:path';
18+
import {TsCheckerRspackPlugin} from 'ts-checker-rspack-plugin';
1919

2020
import LastBuiltPlugin from './build-utils/last-built-plugin';
2121

@@ -306,13 +306,9 @@ const appConfig: Configuration = {
306306

307307
...(SHOULD_FORK_TS
308308
? [
309-
new ForkTsCheckerWebpackPlugin({
309+
new TsCheckerRspackPlugin({
310310
typescript: {
311311
configFile: path.resolve(__dirname, './config/tsconfig.build.json'),
312-
configOverwrite: {
313-
compilerOptions: {incremental: true},
314-
},
315-
memoryLimit: 4096,
316312
},
317313
devServer: false,
318314
}),

src/sentry/api/endpoints/organization_sdk_deprecations.py

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,18 @@
22
from typing import DefaultDict, TypedDict
33

44
import sentry_sdk
5-
from packaging.version import InvalidVersion, Version
5+
from packaging.version import InvalidVersion
66
from packaging.version import parse as parse_version
77
from rest_framework import serializers
88
from rest_framework.request import Request
99
from rest_framework.response import Response
1010

11-
from sentry import options
1211
from sentry.api.api_owners import ApiOwner
1312
from sentry.api.api_publish_status import ApiPublishStatus
1413
from sentry.api.base import region_silo_endpoint
1514
from sentry.api.bases.organization import OrganizationEndpoint
1615
from sentry.models.project import Project
17-
from sentry.models.projectsdk import EventType, ProjectSDK
16+
from sentry.models.projectsdk import EventType, ProjectSDK, get_minimum_sdk_version
1817

1918

2019
class SDKDeprecationsSerializer(serializers.Serializer):
@@ -93,40 +92,18 @@ def get_event_types(raw_event_type: str) -> list[EventType]:
9392
raise ValueError(f"Unknown event type: {raw_event_type}")
9493

9594

96-
MINIMUM_SDK_VERSION_OPTIONS: dict[tuple[int, str], str] = {
97-
(EventType.PROFILE_CHUNK.value, "sentry.cocoa"): "sdk-deprecation.profile-chunk.cocoa",
98-
(EventType.PROFILE_CHUNK.value, "sentry.python"): "sdk-deprecation.profile-chunk.python",
99-
}
100-
101-
102-
def get_minimum_sdk_version(project_sdk: ProjectSDK) -> Version | None:
103-
parts = project_sdk.sdk_name.split(".", 2)
104-
if len(parts) < 2:
105-
return None
106-
107-
sdk_name = ".".join(parts[:2])
108-
109-
sdk_version_option = MINIMUM_SDK_VERSION_OPTIONS.get((project_sdk.event_type, sdk_name))
110-
if sdk_version_option is None:
111-
return None
112-
113-
sdk_version = options.get(sdk_version_option)
114-
if sdk_version:
115-
try:
116-
return parse_version(sdk_version)
117-
except InvalidVersion as e:
118-
sentry_sdk.capture_exception(e)
119-
return None
120-
121-
12295
def get_deprecation_status(project_sdk: ProjectSDK) -> SDKDeprecation | None:
12396
try:
12497
sdk_version = parse_version(project_sdk.sdk_version)
12598
except InvalidVersion as e:
12699
sentry_sdk.capture_exception(e)
127100
return None
128101

129-
minimum_sdk_version = get_minimum_sdk_version(project_sdk)
102+
minimum_sdk_version = get_minimum_sdk_version(
103+
project_sdk.event_type,
104+
project_sdk.sdk_name,
105+
hard_limit=False,
106+
)
130107

131108
# no minimum sdk version was specified
132109
if minimum_sdk_version is None:

src/sentry/celery.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ def holds_bad_pickle_object(value, memo=None):
3333
bad_object = holds_bad_pickle_object(item, memo)
3434
if bad_object is not None:
3535
return bad_object
36+
return
3637
elif isinstance(value, dict):
3738
for item in value.values():
3839
bad_object = holds_bad_pickle_object(item, memo)
3940
if bad_object is not None:
4041
return bad_object
41-
42+
return
4243
if isinstance(value, models.Model):
4344
return (
4445
value,
@@ -56,7 +57,7 @@ def holds_bad_pickle_object(value, memo=None):
5657
return None
5758
elif value is None:
5859
return None
59-
elif not isinstance(value, (dict, list, str, float, int, bool, tuple, frozenset)):
60+
elif not isinstance(value, (str, float, int, bool)):
6061
return value, "do not pickle stdlib classes"
6162
return None
6263

@@ -69,9 +70,9 @@ def good_use_of_pickle_or_bad_use_of_pickle(task, args, kwargs):
6970
if bad is not None:
7071
bad_object, reason = bad
7172
raise TypeError(
72-
"Task %r was invoked with an object that we do not want "
73+
"Task %s was invoked with an object that we do not want "
7374
"to pass via pickle (%r, reason is %s) in argument %s"
74-
% (task, bad_object, reason, name)
75+
% (task.name, bad_object, reason, name)
7576
)
7677

7778

src/sentry/conf/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1435,7 +1435,7 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
14351435
"sentry.integrations.tasks.update_comment",
14361436
"sentry.integrations.vsts.tasks.kickoff_subscription_check",
14371437
"sentry.integrations.vsts.tasks.subscription_check",
1438-
"sentry.issues.forecasts",
1438+
"sentry.issues.escalating.forecasts",
14391439
"sentry.middleware.integrations.tasks",
14401440
"sentry.monitors.tasks.clock_pulse",
14411441
"sentry.monitors.tasks.detect_broken_monitor_envs",

src/sentry/features/temporary.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ def register_temporary_features(manager: FeatureManager):
273273
manager.add("organizations:profiling-beta", OrganizationFeature, FeatureHandlerStrategy.INTERNAL, api_expose=True)
274274
# Enables monitoring for latest profiling sdk used
275275
manager.add("organizations:profiling-sdks", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
276+
# Enables dropping of deprecated profiling sdks used
277+
manager.add("organizations:profiling-deprecate-sdks", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
276278
# Enables production profiling in sentry browser application
277279
manager.add("organizations:profiling-browser", OrganizationFeature, FeatureHandlerStrategy.INTERNAL, api_expose=False)
278280
# Enables separate differential flamegraph page

src/sentry/grouping/enhancer/__init__.py

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,71 @@ def apply_category_and_updated_in_app_to_frames(
525525
),
526526
)
527527

528+
def assemble_stacktrace_component_legacy(
529+
self,
530+
variant_name: str,
531+
frame_components: list[FrameGroupingComponent],
532+
frames: list[dict[str, Any]],
533+
platform: str | None,
534+
exception_data: dict[str, Any] | None = None,
535+
) -> StacktraceGroupingComponent:
536+
"""
537+
This assembles a `stacktrace` grouping component out of the given
538+
`frame` components and source frames.
539+
540+
This also handles cases where the entire stacktrace should be discarded.
541+
"""
542+
543+
match_frames: list[Any] = [create_match_frame(frame, platform) for frame in frames]
544+
rust_frames = [RustFrame(contributes=c.contributes) for c in frame_components]
545+
rust_exception_data = make_rust_exception_data(exception_data)
546+
547+
# Modify the rust frames by applying +group/-group rules and getting hints for both those
548+
# changes and the `in_app` changes applied by earlier in the ingestion process by
549+
# `apply_category_and_updated_in_app_to_frames`. Also, get `hint` and `contributes` values
550+
# for the overall stacktrace (returned in `rust_results`).
551+
rust_stacktrace_results = self.rust_enhancements.assemble_stacktrace_component(
552+
match_frames, rust_exception_data, rust_frames
553+
)
554+
555+
# Tally the number of each type of frame in the stacktrace. Later on, this will allow us to
556+
# both collect metrics and use the information in decisions about whether to send the event
557+
# to Seer
558+
frame_counts: Counter[str] = Counter()
559+
560+
# Update frame components with results from rust
561+
for frame, frame_component, rust_frame in zip(frames, frame_components, rust_frames):
562+
rust_contributes = bool(rust_frame.contributes) # bool-ing this for mypy's sake
563+
rust_hint = rust_frame.hint
564+
rust_hint_type = (
565+
None
566+
if rust_hint is None
567+
else "in-app" if rust_hint.startswith("marked") else "contributes"
568+
)
569+
570+
hint = get_hint_for_frame(variant_name, frame, frame_component, rust_frame)
571+
572+
if not (variant_name == "system" and rust_hint_type == "in-app"):
573+
hint = rust_hint
574+
575+
frame_component.update(contributes=rust_contributes, hint=hint)
576+
577+
# Add this frame to our tally
578+
key = f"{"in_app" if frame_component.in_app else "system"}_{"contributing" if frame_component.contributes else "non_contributing"}_frames"
579+
frame_counts[key] += 1
580+
581+
stacktrace_contributes = rust_stacktrace_results.contributes
582+
stacktrace_hint = rust_stacktrace_results.hint
583+
584+
stacktrace_component = StacktraceGroupingComponent(
585+
values=frame_components,
586+
hint=stacktrace_hint,
587+
contributes=stacktrace_contributes,
588+
frame_counts=frame_counts,
589+
)
590+
591+
return stacktrace_component
592+
528593
def assemble_stacktrace_component(
529594
self,
530595
variant_name: str,
@@ -611,21 +676,12 @@ def assemble_stacktrace_component(
611676
in_app_rust_frames,
612677
contributes_rust_frames,
613678
):
614-
frame_type = "in-app" if frame_component.in_app else "system"
615-
rust_contributes = bool(rust_frame.contributes) # bool-ing this for mypy's sake
616-
rust_hint = rust_frame.hint
617-
rust_hint_type = (
618-
None
619-
if rust_hint is None
620-
else "in-app" if rust_hint.startswith("marked") else "contributes"
621-
)
622-
623679
# System frames should never contribute in the app variant, so if that's what we have,
624680
# force `contribtues=False`, regardless of the rust results
625-
if variant_name == "app" and frame_type == "system":
681+
if variant_name == "app" and not frame_component.in_app:
626682
contributes = False
627683
else:
628-
contributes = rust_contributes
684+
contributes = rust_frame.contributes
629685

630686
hint = get_hint_for_frame(variant_name, frame, frame_component, rust_frame)
631687
if self.run_split_enhancements:
@@ -640,15 +696,6 @@ def assemble_stacktrace_component(
640696
variant_name, frame, frame_component, contributes_rust_frame, "contributes"
641697
)
642698

643-
# TODO: Remove this workaround once we remove the legacy config. It's done this way (as
644-
# a second pass at setting the values that undoes what the first pass did, rather than
645-
# being incorporated into the first pass) so that we won't have to change any of the
646-
# main logic when we remove it.
647-
if self.bases and self.bases[0].startswith("legacy"):
648-
contributes = rust_contributes
649-
if not (variant_name == "system" and rust_hint_type == "in-app"):
650-
hint = rust_hint
651-
652699
frame_component.update(contributes=contributes, hint=hint)
653700

654701
# Add this frame to our tally
@@ -690,13 +737,7 @@ def assemble_stacktrace_component(
690737
# stacktrace to be wrong, too (if in the process of ignoring rust we turn a stacktrace with
691738
# at least one contributing frame into one without any). So we need to special-case here as
692739
# well.
693-
#
694-
# TODO: Remove the first condition once we get rid of the legacy config
695-
if (
696-
not (self.bases and self.bases[0].startswith("legacy"))
697-
and variant_name == "app"
698-
and frame_counts["in_app_contributing_frames"] == 0
699-
):
740+
if variant_name == "app" and frame_counts["in_app_contributing_frames"] == 0:
700741
stacktrace_contributes = False
701742
stacktrace_hint = None
702743
else:

src/sentry/grouping/strategies/legacy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ def stacktrace_legacy(
452452
frames_for_filtering.append(frame.get_raw_data())
453453
prev_frame = frame
454454

455-
stacktrace_component = context.config.enhancements.assemble_stacktrace_component(
455+
stacktrace_component = context.config.enhancements.assemble_stacktrace_component_legacy(
456456
variant_name, frame_components, frames_for_filtering, event.platform
457457
)
458458
stacktrace_component.update(contributes=contributes, hint=hint)

src/sentry/incidents/logic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ def get_metric_issue_aggregates(
415415
"incidents.get_incident_aggregates.snql.query.error",
416416
tags={
417417
"dataset": params.snuba_query.dataset,
418-
"entity": EntityKey.EAPSpans.value,
418+
"entity": EntityKey.EAPItemsSpan.value,
419419
},
420420
)
421421
raise

0 commit comments

Comments
 (0)