diff --git a/static/app/views/alerts/rules/uptime/httpSnippet.spec.tsx b/static/app/views/alerts/rules/uptime/httpSnippet.spec.tsx
index 8adc5980055bf1..7df1d079e87259 100644
--- a/static/app/views/alerts/rules/uptime/httpSnippet.spec.tsx
+++ b/static/app/views/alerts/rules/uptime/httpSnippet.spec.tsx
@@ -1,3 +1,5 @@
+import {generateSentryTraceHeader} from '@sentry/utils';
+
import {render} from 'sentry-test/reactTestingLibrary';
import {HTTPSnippet} from './httpSnippet';
@@ -15,9 +17,16 @@ describe('HTTPSnippet', function () {
method="POST"
body={'{"key": "value"}'}
headers={[['X-Something', 'Header Value']]}
+ traceSampling={false}
/>
);
+ expect(jest.mocked(generateSentryTraceHeader)).toHaveBeenCalledWith(
+ undefined,
+ undefined,
+ false
+ );
+
const expected = [
'POST /test?query=value HTTP/1.1',
'Host: example.com',
diff --git a/static/app/views/alerts/rules/uptime/httpSnippet.tsx b/static/app/views/alerts/rules/uptime/httpSnippet.tsx
index fcfbdcca37dece..4eb4870d19ddaf 100644
--- a/static/app/views/alerts/rules/uptime/httpSnippet.tsx
+++ b/static/app/views/alerts/rules/uptime/httpSnippet.tsx
@@ -1,4 +1,4 @@
-import {useState} from 'react';
+import {useMemo} from 'react';
import styled from '@emotion/styled';
import {generateSentryTraceHeader} from '@sentry/utils';
@@ -10,12 +10,15 @@ interface Props {
body: string | null;
headers: Array<[key: string, value: string]>;
method: string;
+ traceSampling: boolean;
url: string;
}
-export function HTTPSnippet({body, headers, method, url}: Props) {
- const [exampleTrace] = useState(() =>
- generateSentryTraceHeader(undefined, undefined, true)
+export function HTTPSnippet({body, headers, method, url, traceSampling}: Props) {
+ const exampleTrace = useMemo(
+ () =>
+ generateSentryTraceHeader(undefined, undefined, traceSampling ? undefined : false),
+ [traceSampling]
);
const urlObject = safeURL(url);
diff --git a/static/app/views/alerts/rules/uptime/types.tsx b/static/app/views/alerts/rules/uptime/types.tsx
index 79eb43a862f83d..5aab4d2ad8c4e0 100644
--- a/static/app/views/alerts/rules/uptime/types.tsx
+++ b/static/app/views/alerts/rules/uptime/types.tsx
@@ -24,5 +24,6 @@ export interface UptimeRule {
projectSlug: string;
status: UptimeMonitorStatus;
timeoutMs: number;
+ traceSampling: boolean;
url: string;
}
diff --git a/static/app/views/alerts/rules/uptime/uptimeAlertForm.spec.tsx b/static/app/views/alerts/rules/uptime/uptimeAlertForm.spec.tsx
index cecf25cf40ad11..8f6f8e42c9f45b 100644
--- a/static/app/views/alerts/rules/uptime/uptimeAlertForm.spec.tsx
+++ b/static/app/views/alerts/rules/uptime/uptimeAlertForm.spec.tsx
@@ -54,6 +54,8 @@ describe('Uptime Alert Form', function () {
await userEvent.type(input('Name of header 1'), 'X-Something');
await userEvent.type(input('Value of X-Something'), 'Header Value');
+ await userEvent.click(screen.getByRole('checkbox', {name: 'Allow Tracing'}));
+
const name = input('Uptime rule name');
await userEvent.clear(name);
await userEvent.type(name, 'New Uptime Rule');
@@ -78,6 +80,7 @@ describe('Uptime Alert Form', function () {
method: 'POST',
headers: [['X-Something', 'Header Value']],
body: '{"key": "value"}',
+ traceSampling: true,
intervalSeconds: 60,
}),
})
@@ -96,6 +99,7 @@ describe('Uptime Alert Form', function () {
['X-Test2', 'value 2'],
],
body: '{"key": "value"}',
+ traceSampling: true,
owner: ActorFixture(),
});
render(
@@ -115,6 +119,7 @@ describe('Uptime Alert Form', function () {
expect(screen.getByRole('menuitemradio', {name: 'POST'})).toBeChecked();
await selectEvent.openMenu(input('Environment'));
expect(screen.getByRole('menuitemradio', {name: 'prod'})).toBeChecked();
+ expect(screen.getByRole('checkbox', {name: 'Allow Tracing'})).toBeChecked();
});
it('handles simple edits', async function () {
@@ -163,6 +168,7 @@ describe('Uptime Alert Form', function () {
projectSlug: project.slug,
url: 'https://existing-url.com',
owner: ActorFixture(),
+ traceSampling: false,
});
render(
,
@@ -188,6 +194,8 @@ describe('Uptime Alert Form', function () {
await userEvent.type(input('Name of header 2'), 'X-Another');
await userEvent.type(input('Value of X-Another'), 'Second Value');
+ await userEvent.click(screen.getByRole('checkbox', {name: 'Allow Tracing'}));
+
const name = input('Uptime rule name');
await userEvent.clear(name);
await userEvent.type(name, 'Updated name');
@@ -216,6 +224,7 @@ describe('Uptime Alert Form', function () {
],
body: '{"different": "value"}',
intervalSeconds: 60 * 10,
+ traceSampling: true,
}),
})
);
diff --git a/static/app/views/alerts/rules/uptime/uptimeAlertForm.tsx b/static/app/views/alerts/rules/uptime/uptimeAlertForm.tsx
index a9d81852551288..13f0daf779e7ab 100644
--- a/static/app/views/alerts/rules/uptime/uptimeAlertForm.tsx
+++ b/static/app/views/alerts/rules/uptime/uptimeAlertForm.tsx
@@ -6,6 +6,7 @@ import {Observer} from 'mobx-react';
import {Button} from 'sentry/components/button';
import Confirm from 'sentry/components/confirm';
import FieldWrapper from 'sentry/components/forms/fieldGroup/fieldWrapper';
+import BooleanField from 'sentry/components/forms/fields/booleanField';
import HiddenField from 'sentry/components/forms/fields/hiddenField';
import SelectField from 'sentry/components/forms/fields/selectField';
import SentryMemberTeamSelectorField from 'sentry/components/forms/fields/sentryMemberTeamSelectorField';
@@ -62,6 +63,7 @@ function getFormDataFromRule(rule: UptimeRule) {
body: rule.body,
headers: rule.headers,
intervalSeconds: rule.intervalSeconds,
+ traceSampling: rule.traceSampling,
owner: rule.owner ? `${rule.owner.type}:${rule.owner.id}` : null,
};
}
@@ -216,6 +218,15 @@ export function UptimeAlertForm({project, handleDelete, rule}: Props) {
label={t('Headers')}
flexibleControlStateSize
/>
+
)}
diff --git a/tests/js/fixtures/uptimeRule.ts b/tests/js/fixtures/uptimeRule.ts
index a3d5d2a123779d..1c232e27648822 100644
--- a/tests/js/fixtures/uptimeRule.ts
+++ b/tests/js/fixtures/uptimeRule.ts
@@ -16,6 +16,7 @@ export function UptimeRuleFixture(params: Partial = {}): UptimeRule
headers: [],
method: 'GET',
body: null,
+ traceSampling: false,
...params,
}
}