Skip to content

Commit 119ab22

Browse files
Merge branch 'master' into isabella/metric-alert-rate-limit
2 parents 7aa233f + e88e83c commit 119ab22

File tree

316 files changed

+10321
-3359
lines changed

Some content is hidden

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

316 files changed

+10321
-3359
lines changed

CHANGES

+44
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,47 @@
1+
23.10.0
2+
-------
3+
4+
### Discord Integration (ongoing)
5+
6+
By: @17hogeju (#57522)
7+
8+
### Notification Analytics Milestone 2 (ongoing)
9+
10+
By: @scttcper (#56700)
11+
12+
### Notification Settings 2.0 (ongoing)
13+
14+
By: @snigdhas (#57053, #56717, #56621)
15+
16+
### Various fixes & improvements
17+
18+
- feat(crons): Add cron monitor created metric (#58017) by @davidenwang
19+
- ref(participants): Check for group list (#58204) by @ceorourke
20+
- feat(hybridcloud) Fix silo issues in shared issue HTML view (#57978) by @markstory
21+
- feat(sdk): Upgrade `@sentry` SDKs to v7.74.0 (#58198) by @billyvg
22+
- test(backup): Create backup version snapshot tests (#58173) by @azaslavsky
23+
- fix(hc): Silo fixes for alert rule actions (#58185) by @RyanSkonnord
24+
- meta(crons): Update API help text (#58048) by @rjo100
25+
- fix(ci): fix rate limit test (#58184) by @volokluev
26+
- feat(ui): Throw error on non-json api responses (#58129) by @scttcper
27+
- ref(bug reports): display name and email in list and details (#58087) by @michellewzhang
28+
- chore(actionable-items): remove feature flag backend (#57934) by @roggenkemper
29+
- update release threshold api routes (#58177) by @nhsiehgit
30+
- feat(backup): Support import decryption (#58128) by @azaslavsky
31+
- chore(alert-rule): Add jira server action to frontend enum (#58186) by @schew2381
32+
- feat(metrics): Add new option to toggle reading from new cache schema for indexer (#58170) by @john-z-yang
33+
- fix(hybridcloud) Assign control silo tasks to correct queues (#58112) by @markstory
34+
- fix(feedback): Improve spacing between feedback list items (#58182) by @ryan953
35+
- ref(bug reports): modify blueprint name and contact_email to reflect BE (#58083) by @michellewzhang
36+
- fix(hc): Fix silo availability error in send_alert_event (#58044) by @RyanSkonnord
37+
- ref(replay): Improve accessibility type names, and compat with replay frames (#58179) by @ryan953
38+
- feat(notifications): adds backfill for weekly report settings (#58168) by @scefali
39+
- feat(notifications): remove notification double write feature flag (#57863) by @scefali
40+
- feat(discord): adds logging of discord errors (#58176) by @scefali
41+
- fix(stat-detectors): Use 7 days for span analysis (#58096) by @narsaynorath
42+
43+
_Plus 1060 more_
44+
145
23.9.1
246
------
347

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Additional Use Grant: You may make use of the Licensed Work, provided that you d
1616
error-reporting or application monitoring features of the
1717
Licensed Work.
1818

19-
Change Date: 2026-09-20
19+
Change Date: 2026-10-16
2020

2121
Change License: Apache License, Version 2.0
2222

migrations_lockfile.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ feedback: 0003_feedback_add_env
99
hybridcloud: 0004_add_cache_version
1010
nodestore: 0002_nodestore_no_dictfield
1111
replays: 0003_add_size_to_recording_segment
12-
sentry: 0573_add_first_seen_index_groupedmessage
12+
sentry: 0575_incident_date_added_index
1313
social_auth: 0002_default_auto_field

package.json

+11-11
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,17 @@
4949
"@react-types/shared": "^3.18.1",
5050
"@sentry-internal/global-search": "^0.5.7",
5151
"@sentry-internal/react-inspector": "6.0.1-4",
52-
"@sentry-internal/rrweb": "2.0.0-beta11.0",
53-
"@sentry-internal/rrweb-player": "2.0.0-beta11.0",
54-
"@sentry-internal/rrweb-snapshot": "2.0.0-beta11.0",
55-
"@sentry/core": "7.73.0",
56-
"@sentry/integrations": "7.73.0",
57-
"@sentry/node": "7.73.0",
58-
"@sentry/react": "7.73.0",
52+
"@sentry-internal/rrweb": "2.0.1",
53+
"@sentry-internal/rrweb-player": "2.0.1",
54+
"@sentry-internal/rrweb-snapshot": "2.0.1",
55+
"@sentry/core": "7.74.0",
56+
"@sentry/integrations": "7.74.0",
57+
"@sentry/node": "7.74.0",
58+
"@sentry/react": "7.74.0",
5959
"@sentry/release-parser": "^1.3.1",
60-
"@sentry/tracing": "7.73.0",
61-
"@sentry/types": "7.73.0",
62-
"@sentry/utils": "7.73.0",
60+
"@sentry/tracing": "7.74.0",
61+
"@sentry/types": "7.74.0",
62+
"@sentry/utils": "7.74.0",
6363
"@tanstack/react-query": "^4.29.7",
6464
"@types/color": "^3.0.3",
6565
"@types/crypto-js": "^4.1.1",
@@ -134,7 +134,7 @@
134134
"papaparse": "^5.3.2",
135135
"pegjs": "^0.10.0",
136136
"pegjs-loader": "^0.5.6",
137-
"platformicons": "^5.6.5",
137+
"platformicons": "^5.7.1",
138138
"po-catalog-loader": "2.0.0",
139139
"prettier": "3.0.3",
140140
"prismjs": "^1.29.0",

pyproject.toml

-1
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,6 @@ module = [
384384
"sentry.identity.vsts.provider",
385385
"sentry.incidents.action_handlers",
386386
"sentry.incidents.endpoints.bases",
387-
"sentry.incidents.endpoints.organization_alert_rule_available_action_index",
388387
"sentry.incidents.endpoints.organization_alert_rule_details",
389388
"sentry.incidents.endpoints.organization_alert_rule_index",
390389
"sentry.incidents.endpoints.organization_incident_comment_details",

requirements-base.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ requests>=2.25.1
5858
rfc3339-validator>=0.1.2
5959
rfc3986-validator>=0.1.1
6060
# [end] jsonschema format validators
61-
sentry-arroyo>=2.14.10
62-
sentry-kafka-schemas>=0.1.30
61+
sentry-arroyo>=2.14.12
62+
sentry-kafka-schemas>=0.1.32
6363
sentry-redis-tools>=0.1.7
6464
sentry-relay>=0.8.32
6565
sentry-sdk>=1.31.0

requirements-dev-frozen.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,9 @@ rfc3986-validator==0.1.1
168168
rsa==4.8
169169
s3transfer==0.6.1
170170
selenium==4.3.0
171-
sentry-arroyo==2.14.10
171+
sentry-arroyo==2.14.12
172172
sentry-cli==2.16.0
173-
sentry-kafka-schemas==0.1.30
173+
sentry-kafka-schemas==0.1.32
174174
sentry-redis-tools==0.1.7
175175
sentry-relay==0.8.32
176176
sentry-sdk==1.31.0

requirements-frozen.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ rfc3339-validator==0.1.2
110110
rfc3986-validator==0.1.1
111111
rsa==4.8
112112
s3transfer==0.6.1
113-
sentry-arroyo==2.14.10
114-
sentry-kafka-schemas==0.1.30
113+
sentry-arroyo==2.14.12
114+
sentry-kafka-schemas==0.1.32
115115
sentry-redis-tools==0.1.7
116116
sentry-relay==0.8.32
117117
sentry-sdk==1.31.0

scripts/lib.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ create-superuser() {
188188
if [[ -n "${GITHUB_ACTIONS+x}" ]]; then
189189
sentry createuser --superuser --email [email protected] --no-password --no-input
190190
else
191-
sentry createuser --superuser --email [email protected] --password admin
191+
sentry createuser --superuser --email [email protected] --password admin --no-input
192192
echo "Password is admin."
193193
fi
194194
}

setup.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = sentry
3-
version = 23.10.0.dev0
3+
version = 23.11.0.dev0
44
description = A realtime logging and aggregation server.
55
long_description = file: README.md
66
long_description_content_type = text/markdown

src/sentry/analytics/events/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
from .codeowners_created import * # noqa: F401,F403
1010
from .codeowners_updated import * # noqa: F401,F403
1111
from .comment_webhooks import * # noqa: F401,F403
12+
from .cron_monitor_created import * # noqa: F401,F403
13+
from .eventuser_endpoint_request import * # noqa: F401,F403
1214
from .first_cron_checkin_sent import * # noqa: F401,F403
13-
from .first_cron_monitor_created import * # noqa: F401,F403
1415
from .first_event_sent import * # noqa: F401,F403
1516
from .first_profile_sent import * # noqa: F401,F403
1617
from .first_release_tag_sent import * # noqa: F401,F403
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
from sentry import analytics
22

33

4-
class FirstCronMonitorCreated(analytics.Event):
5-
type = "first_cron_monitor.created"
6-
4+
class CronMonitorEvent(analytics.Event):
75
attributes = (
86
analytics.Attribute("organization_id"),
97
analytics.Attribute("project_id"),
@@ -12,4 +10,13 @@ class FirstCronMonitorCreated(analytics.Event):
1210
)
1311

1412

13+
class CronMonitorCreated(CronMonitorEvent):
14+
type = "cron_monitor.created"
15+
16+
17+
class FirstCronMonitorCreated(CronMonitorEvent):
18+
type = "first_cron_monitor.created"
19+
20+
1521
analytics.register(FirstCronMonitorCreated)
22+
analytics.register(CronMonitorCreated)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from sentry import analytics
2+
3+
4+
class EventUserEndpointRequest(analytics.Event):
5+
type = "eventuser_endpoint.request"
6+
7+
attributes = (
8+
analytics.Attribute("endpoint", required=True),
9+
analytics.Attribute("project_id", required=True),
10+
)
11+
12+
13+
analytics.register(EventUserEndpointRequest)

src/sentry/api/bases/external_actor.py

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
AVAILABLE_PROVIDERS = {
2727
ExternalProviders.GITHUB,
28+
ExternalProviders.GITHUB_ENTERPRISE,
2829
ExternalProviders.GITLAB,
2930
ExternalProviders.SLACK,
3031
ExternalProviders.MSTEAMS,

src/sentry/api/bases/organization_events.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ def handle_data(
365365
# once those APIs are used across the application.
366366
if "transaction.status" in first_row:
367367
for row in results:
368-
if "transaction.status" in row:
368+
if "transaction.status" in row and type(row["transaction.status"]) is int:
369369
row["transaction.status"] = SPAN_STATUS_CODE_TO_NAME.get(
370370
row["transaction.status"]
371371
)

src/sentry/api/endpoints/actionable_items.py

+1-11
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from rest_framework.response import Response
66
from typing_extensions import TypedDict
77

8-
from sentry import eventstore, features
8+
from sentry import eventstore
99
from sentry.api.api_owners import ApiOwner
1010
from sentry.api.api_publish_status import ApiPublishStatus
1111
from sentry.api.base import region_silo_endpoint
@@ -17,7 +17,6 @@
1717
priority_ranking,
1818
)
1919
from sentry.models.eventerror import EventError
20-
from sentry.models.organization import Organization
2120
from sentry.models.project import Project
2221

2322

@@ -42,17 +41,8 @@ class ActionableItemsEndpoint(ProjectEndpoint):
4241
}
4342
owner = ApiOwner.ISSUES
4443

45-
def has_feature(self, organization: Organization, request: Request):
46-
return features.has("organizations:actionable-items", organization, actor=request.user)
47-
4844
def get(self, request: Request, project: Project, event_id: str) -> Response:
4945
# Retrieve information about actionable items (source maps, event errors, etc.) for a given event.
50-
organization = project.organization
51-
if not self.has_feature(organization, request):
52-
raise NotFound(
53-
detail="Endpoint not available without 'organizations:actionable-items' feature flag"
54-
)
55-
5646
event = eventstore.backend.get_event_by_id(project.id, event_id)
5747
if event is None:
5848
raise NotFound(detail="Event not found")

src/sentry/api/endpoints/group_tagkey_values.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from rest_framework.request import Request
22
from rest_framework.response import Response
33

4-
from sentry import tagstore
4+
from sentry import analytics, tagstore
55
from sentry.api.api_publish_status import ApiPublishStatus
66
from sentry.api.base import EnvironmentMixin, region_silo_endpoint
77
from sentry.api.bases.group import GroupEndpoint
@@ -29,6 +29,11 @@ def get(self, request: Request, group, key) -> Response:
2929
:pparam string key: the tag key to look the values up for.
3030
:auth: required
3131
"""
32+
analytics.record(
33+
"eventuser_endpoint.request",
34+
project_id=group.project_id,
35+
endpoint="sentry.api.endpoints.group_tagkey_values.get",
36+
)
3237
lookup_key = tagstore.prefix_reserved_key(key)
3338

3439
environment_ids = [e.id for e in get_environments(request, group.project.organization)]

src/sentry/api/endpoints/organization_events_root_cause_analysis.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,13 @@ def get_geo_data(period):
144144
adjusted_params["start"] = regression_breakpoint + BUFFER
145145

146146
geo_code_durations = metrics_query(
147-
["p95(transaction.duration)", "geo.country_code", "count()"],
147+
["p95(transaction.duration)", "geo.country_code", "tpm()"],
148148
f"event.type:transaction transaction:{transaction_name}",
149149
adjusted_params,
150150
referrer=f"{BASE_REFERRER}-{GEO_ANALYSIS}",
151151
limit=METRICS_MAX_LIMIT,
152-
# Order by descending count to ensure more active countries are prioritized
153-
orderby=["-count()"],
152+
# Order by descending TPM to ensure more active countries are prioritized
153+
orderby=["-tpm()"],
154154
)
155155

156156
return geo_code_durations
@@ -170,21 +170,28 @@ def get_geo_data(period):
170170

171171
analysis_results = []
172172
for key in changed_keys | new_keys:
173+
if key == "":
174+
continue
175+
173176
duration_before = (
174177
before_results[key]["p95_transaction_duration"] if before_results.get(key) else 0.0
175178
)
176179
duration_after = after_results[key]["p95_transaction_duration"]
177180
if duration_after > duration_before:
181+
duration_delta = duration_after - duration_before
178182
analysis_results.append(
179183
{
180184
"geo.country_code": key,
181185
"duration_before": duration_before,
182186
"duration_after": duration_after,
183-
"duration_delta": duration_after - duration_before,
187+
"duration_delta": duration_delta,
188+
# Multiply duration delta by current TPM to prioritize largest changes
189+
# by most active countries
190+
"score": duration_delta * after_results[key]["tpm"],
184191
}
185192
)
186193

187-
analysis_results.sort(key=lambda x: x["duration_delta"], reverse=True)
194+
analysis_results.sort(key=lambda x: x["score"], reverse=True)
188195
return analysis_results
189196

190197

src/sentry/api/endpoints/organization_profiling_profiles.py

-14
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from sentry.models.organization import Organization
1717
from sentry.profiles.flamegraph import (
1818
get_profile_ids,
19-
get_profile_ids_for_span_op,
2019
get_profile_ids_with_spans,
2120
get_profiles_with_function,
2221
)
@@ -67,32 +66,19 @@ def get(self, request: Request, organization: Organization) -> HttpResponse:
6766
if not features.has("organizations:profiling", organization, actor=request.user):
6867
return Response(status=404)
6968

70-
has_starfish = features.has("organizations:starfish-view", organization, actor=request.user)
71-
7269
params = self.get_snuba_params(request, organization, check_global_views=False)
7370
project_ids = params["project_id"]
7471
if len(project_ids) > 1:
7572
raise ParseError(detail="You cannot get a flamegraph from multiple projects.")
7673

7774
span_group = request.query_params.get("spans.group", None)
78-
span_op = request.query_params.get("spans.op", None)
7975
if span_group is not None:
8076
profile_ids = get_profile_ids_with_spans(
8177
organization.id,
8278
project_ids[0],
8379
params,
8480
span_group,
8581
)
86-
elif span_op is not None and has_starfish:
87-
backend = "indexed_spans"
88-
profile_ids = get_profile_ids_for_span_op(
89-
organization.id,
90-
project_ids[0],
91-
params,
92-
span_op,
93-
backend,
94-
request.query_params.get("query", None),
95-
)
9682
elif "fingerprint" in request.query_params:
9783
function_fingerprint = int(request.query_params["fingerprint"])
9884
profile_ids = get_profiles_with_function(

src/sentry/api/endpoints/organization_sessions.py

+1-12
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from rest_framework.request import Request
88
from rest_framework.response import Response
99

10-
from sentry import features, release_health
10+
from sentry import release_health
1111
from sentry.api.api_owners import ApiOwner
1212
from sentry.api.api_publish_status import ApiPublishStatus
1313
from sentry.api.base import region_silo_endpoint
@@ -28,17 +28,6 @@ class OrganizationSessionsEndpoint(OrganizationEventsEndpointBase):
2828
owner = ApiOwner.TELEMETRY_EXPERIENCE
2929

3030
def get(self, request: Request, organization) -> Response:
31-
query_params = MultiValueDict(request.GET)
32-
33-
fields = set(query_params.getlist("field", []))
34-
anr_fields = {"anr_rate()", "foreground_anr_rate()"}
35-
if fields.intersection(anr_fields) and not features.has(
36-
"organizations:anr-rate", organization, actor=request.user
37-
):
38-
return Response(
39-
{"detail": "This organization does not have the ANR rate feature"}, status=400
40-
)
41-
4231
def data_fn(offset: int, limit: int):
4332
with self.handle_query_errors():
4433
with sentry_sdk.start_span(

0 commit comments

Comments
 (0)