Skip to content

Commit 14cca56

Browse files
authored
Merge branch 'master' into roggenkemper/exposeaidetectionflag
2 parents 9a76abb + b66bf27 commit 14cca56

12 files changed

Lines changed: 135 additions & 55 deletions

File tree

src/sentry/integrations/utils/metrics.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from typing import Any, Self
99

1010
import sentry_sdk
11-
from django.conf import settings
1211

1312
from sentry import options
1413
from sentry.exceptions import RestrictedIPAddress
@@ -168,7 +167,6 @@ def record_event(
168167

169168
sample_rate = 1.0
170169
metrics.incr(key, tags=tags, sample_rate=sample_rate)
171-
sentry_sdk.metrics.count(f"{settings.SENTRY_METRICS_PREFIX}{key}", 1, attributes=dict(tags))
172170

173171
sentry_sdk.set_tags(tags)
174172

src/sentry/options/defaults.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,24 @@
13871387
default=False,
13881388
flags=FLAG_MODIFIABLE_BOOL | FLAG_AUTOMATOR_MODIFIABLE,
13891389
)
1390+
register(
1391+
"seer.supergroups_backfill_lightweight.batch_size",
1392+
type=Int,
1393+
default=40,
1394+
flags=FLAG_AUTOMATOR_MODIFIABLE,
1395+
)
1396+
register(
1397+
"seer.supergroups_backfill_lightweight.inter_batch_delay_s",
1398+
type=Int,
1399+
default=5,
1400+
flags=FLAG_AUTOMATOR_MODIFIABLE,
1401+
)
1402+
register(
1403+
"seer.supergroups_backfill_lightweight.max_failures_per_batch",
1404+
type=Int,
1405+
default=20,
1406+
flags=FLAG_AUTOMATOR_MODIFIABLE,
1407+
)
13901408

13911409
# ## sentry.killswitches
13921410
#

src/sentry/tasks/seer/backfill_supergroups_lightweight.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@
2525

2626
logger = logging.getLogger(__name__)
2727

28-
BATCH_SIZE = 25
29-
INTER_BATCH_DELAY_S = 10
30-
MAX_FAILURES_PER_BATCH = 10
31-
3228

3329
@instrumented_task(
3430
name="sentry.tasks.seer.backfill_supergroups_lightweight.backfill_supergroups_lightweight_for_org",
@@ -77,6 +73,21 @@ def _backfill_org(
7773
last_project_id: int,
7874
last_group_id: int,
7975
) -> None:
76+
batch_size: int = options.get("seer.supergroups_backfill_lightweight.batch_size")
77+
inter_batch_delay_s: int = options.get(
78+
"seer.supergroups_backfill_lightweight.inter_batch_delay_s"
79+
)
80+
max_failures_per_batch: int = options.get(
81+
"seer.supergroups_backfill_lightweight.max_failures_per_batch"
82+
)
83+
84+
if batch_size <= 0:
85+
logger.error(
86+
"supergroups_backfill_lightweight.invalid_batch_size",
87+
extra={"organization_id": organization_id, "batch_size": batch_size},
88+
)
89+
return
90+
8091
# Get the next project to process, starting from where we left off
8192
project = (
8293
Project.objects.filter(
@@ -107,7 +118,7 @@ def _backfill_org(
107118
substatus__in=UNRESOLVED_SUBSTATUS_CHOICES,
108119
)
109120
.select_related("project", "project__organization")
110-
.order_by("id")[:BATCH_SIZE]
121+
.order_by("id")[:batch_size]
111122
)
112123

113124
if not groups:
@@ -118,7 +129,7 @@ def _backfill_org(
118129
"last_project_id": project.id + 1,
119130
"last_group_id": 0,
120131
},
121-
countdown=INTER_BATCH_DELAY_S,
132+
countdown=inter_batch_delay_s,
122133
headers={"sentry-propagate-traces": False},
123134
)
124135
return
@@ -182,7 +193,7 @@ def _backfill_org(
182193

183194
last_processed_group_id = group.id
184195

185-
if failure_count >= MAX_FAILURES_PER_BATCH:
196+
if max_failures_per_batch > 0 and failure_count >= max_failures_per_batch:
186197
logger.error(
187198
"supergroups_backfill_lightweight.max_failures_reached",
188199
extra={
@@ -214,11 +225,11 @@ def _backfill_org(
214225
},
215226
)
216227

217-
if failure_count >= MAX_FAILURES_PER_BATCH:
228+
if max_failures_per_batch > 0 and failure_count >= max_failures_per_batch:
218229
return
219230

220231
# Self-chain: more groups in this project, or move to next project
221-
if len(groups) == BATCH_SIZE:
232+
if len(groups) == batch_size:
222233
next_project_id = project.id
223234
next_group_id = groups[-1].id
224235
else:
@@ -231,7 +242,7 @@ def _backfill_org(
231242
"last_project_id": next_project_id,
232243
"last_group_id": next_group_id,
233244
},
234-
countdown=INTER_BATCH_DELAY_S,
245+
countdown=inter_batch_delay_s,
235246
headers={"sentry-propagate-traces": False},
236247
)
237248

static/app/components/events/eventDrawer.tsx

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type {ComponentPropsWithoutRef} from 'react';
12
import styled from '@emotion/styled';
23

34
import {InputGroup} from '@sentry/scraps/input';
@@ -6,6 +7,11 @@ import {Flex, type FlexProps} from '@sentry/scraps/layout';
67
import {Breadcrumbs as NavigationBreadcrumbs} from 'sentry/components/breadcrumbs';
78
import {DrawerBody, DrawerHeader} from 'sentry/components/globalDrawer/components';
89
import {MIN_NAV_HEIGHT} from 'sentry/views/issueDetails/streamline/eventTitle';
10+
import {
11+
NAVIGATION_MOBILE_TOPBAR_HEIGHT_WITH_PAGE_FRAME,
12+
PRIMARY_HEADER_HEIGHT,
13+
} from 'sentry/views/navigation/constants';
14+
import {useHasPageFrameFeature} from 'sentry/views/navigation/useHasPageFrameFeature';
915

1016
export const Header = styled('h3')`
1117
display: block;
@@ -31,16 +37,45 @@ export const ShortId = styled('div')`
3137
line-height: 1;
3238
`;
3339

34-
export const EventDrawerContainer = styled('div')`
40+
const EventDrawerContainerRoot = styled('div')<{hasPageFrameFeature: boolean}>`
3541
height: 100%;
3642
display: grid;
3743
grid-template-rows: max-content max-content auto;
44+
45+
${p =>
46+
p.hasPageFrameFeature &&
47+
`
48+
/* Responsive height that matches the TopBar (48px mobile, 53px desktop) */
49+
--event-drawer-header-height: ${NAVIGATION_MOBILE_TOPBAR_HEIGHT_WITH_PAGE_FRAME}px;
50+
--event-navigator-box-shadow: none;
51+
--event-navigator-border-bottom: 1px solid ${p.theme.tokens.border.primary};
52+
53+
@media (min-width: ${p.theme.breakpoints.md}) {
54+
--event-drawer-header-height: ${PRIMARY_HEADER_HEIGHT}px;
55+
}
56+
`}
3857
`;
3958

59+
export function EventDrawerContainer(props: ComponentPropsWithoutRef<'div'>) {
60+
const hasPageFrameFeature = useHasPageFrameFeature();
61+
62+
return (
63+
<EventDrawerContainerRoot {...props} hasPageFrameFeature={hasPageFrameFeature} />
64+
);
65+
}
66+
4067
export const EventDrawerHeader = styled(DrawerHeader)`
4168
position: unset;
42-
max-height: var(--drawer-header-height, ${MIN_NAV_HEIGHT}px);
43-
min-height: var(--drawer-header-height, ${MIN_NAV_HEIGHT}px);
69+
/* Height priority: container variable (responsive) → DrawerHeader height prop → default */
70+
height: var(--event-drawer-header-height, var(--drawer-header-height, auto));
71+
max-height: var(
72+
--event-drawer-header-height,
73+
var(--drawer-header-height, ${MIN_NAV_HEIGHT}px)
74+
);
75+
min-height: var(
76+
--event-drawer-header-height,
77+
var(--drawer-header-height, ${MIN_NAV_HEIGHT}px)
78+
);
4479
align-items: center;
4580
box-shadow: none;
4681
border-bottom: 1px solid ${p => p.theme.tokens.border.primary};
@@ -54,12 +89,17 @@ export const EventNavigator = styled('div')`
5489
grid-template-columns: 1fr auto;
5590
align-items: center;
5691
column-gap: ${p => p.theme.space.md};
57-
padding: ${p => p.theme.space.sm} 24px;
92+
padding: 0 24px;
5893
background: ${p => p.theme.tokens.background.primary};
5994
z-index: 2; /* Just above EventStickyControls */
60-
min-height: ${MIN_NAV_HEIGHT}px;
95+
height: var(--event-drawer-header-height, auto);
96+
min-height: var(--event-drawer-header-height, ${MIN_NAV_HEIGHT}px);
97+
border-bottom: var(--event-navigator-border-bottom, 0);
6198
/* eslint-disable-next-line @sentry/scraps/use-semantic-token */
62-
box-shadow: ${p => p.theme.tokens.border.primary} 0 1px;
99+
box-shadow: var(
100+
--event-navigator-box-shadow,
101+
${p => `${p.theme.tokens.border.primary} 0 1px`}
102+
);
63103
`;
64104

65105
export const EventStickyControls = styled('div')`

static/app/components/questionTooltip.stories.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ export default Storybook.story('QuestionTooltip', story => {
1414
The <Storybook.JSXNode name="QuestionTooltip" /> component is a small{' '}
1515
<Storybook.JSXNode name="IconQuestion" /> where you can specify a tooltip to go
1616
with it. It is useful for placing after headers and titles to include additional
17-
information. You'll see it often at the top of Sentry's pages, near the page
18-
titles.
17+
information. Prefer <Storybook.JSXNode name="InfoTip" /> for new usages.
1918
</p>
2019
<p>
2120
An example <Storybook.JSXNode name="QuestionTooltip" /> looks like this:

static/app/components/questionTooltip.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ interface QuestionProps extends Partial<
3131
icon?: 'question' | 'info';
3232
}
3333

34+
/**
35+
* @deprecated Prefer `InfoTip` from `@sentry/scraps/info` for new usages.
36+
*/
3437
export function QuestionTooltip({
3538
title,
3639
size,

static/app/views/discover/table/cellAction.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {defined} from 'sentry/utils';
1212
import type {TableDataRow} from 'sentry/utils/discover/discoverQuery';
1313
import {
1414
fieldAlignment,
15+
isEquation,
1516
isEquationAlias,
1617
isRelativeSpanOperationBreakdownField,
1718
} from 'sentry/utils/discover/fields';
@@ -193,7 +194,7 @@ function makeCellActions({
193194
}
194195

195196
// Do not render context menu buttons for the equation fields until we can query on them
196-
if (isEquationAlias(column.name)) {
197+
if (isEquationAlias(column.name) || isEquation(column.key as string)) {
197198
return null;
198199
}
199200

static/app/views/explore/metrics/metricInfoTabs/aggregatesTab.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,7 @@ export function AggregatesTab({traceMetric, isMetricOptionsEmpty}: AggregatesTab
250250
}
251251

252252
const direction = sorts.find(s => s.field === field)?.kind;
253-
const canSort =
254-
displayColumns.find(column => column.key === field)?.isSortable !== false;
253+
const canSort = field !== TraceMetricKnownFieldKey.METRIC_NAME;
255254

256255
function updateSort() {
257256
const kind = direction === 'desc' ? 'asc' : 'desc';

static/app/views/explore/metrics/metricToolbar/filter.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,9 @@ export function Filter({traceMetric, skipTraceMetricFilter}: FilterProps) {
156156
searchSource: 'tracemetrics',
157157
namespace: traceMetric.name,
158158

159-
// Disable the recent searches when not using a trace metric filter because
160-
// the recent searches for metrics need to be namespaced on the trace metric filter.
161-
disableRecentSearches: skipTraceMetricFilter,
159+
// Disable the recent searches when not using a trace metric filter or when the metric name
160+
// is not set because the recent searches for metrics need to be namespaced on the trace metric filter.
161+
disableRecentSearches: skipTraceMetricFilter || !traceMetric.name,
162162
};
163163
}, [
164164
query,

static/app/views/explore/metrics/useSaveAsMetricItems.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,24 +111,37 @@ export function useSaveAsMetricItems(_options: UseSaveAsMetricItemsOptions) {
111111
label: t('All Metrics'),
112112
textValue: t('All Metrics'),
113113
onAction: () => {
114-
addToDashboard(metricQueries);
114+
addToDashboard(
115+
metricQueries.filter(
116+
metricQuery =>
117+
!isVisualizeEquation(metricQuery.queryParams.visualizes[0]!)
118+
)
119+
);
115120
},
116121
},
117122
]
118123
: []),
119124
...metricQueries.map((metricQuery, index) => {
125+
const visualize = metricQuery.queryParams.visualizes[0]!;
120126
return {
121127
key: `add-to-dashboard-${index}`,
122-
label: `${metricQuery.label ?? getVisualizeLabel(index, isVisualizeEquation(metricQuery.queryParams.visualizes[0]!))}: ${
128+
label: `${metricQuery.label ?? getVisualizeLabel(index, isVisualizeEquation(visualize))}: ${
123129
formatTraceMetricsFunction(
124130
metricQuery.queryParams.aggregateFields
125131
.filter(isVisualize)
126132
.map(v => v.yAxis)
127133
) as string
128134
}`,
129135
onAction: () => {
136+
if (isVisualizeEquation(visualize)) {
137+
return;
138+
}
130139
addToDashboard(metricQuery);
131140
},
141+
disabled: isVisualizeEquation(visualize),
142+
tooltip: isVisualizeEquation(visualize)
143+
? t('Equations cannot currently be added to a dashboard')
144+
: undefined,
132145
};
133146
}),
134147
],

0 commit comments

Comments
 (0)