From dd80eeda1b1352200b01a4364bfaa7999703b140 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 14 Nov 2025 09:09:31 +0100 Subject: [PATCH 1/7] feat(onboarding): Simplify metrics onboarding for the Python SDK --- .../app/gettingStartedDocs/python/metrics.tsx | 66 +++++++------------ .../explore/metrics/metricsOnboarding.tsx | 12 ++-- 2 files changed, 26 insertions(+), 52 deletions(-) diff --git a/static/app/gettingStartedDocs/python/metrics.tsx b/static/app/gettingStartedDocs/python/metrics.tsx index f278da85d4bec9..621d7cb76e70b6 100644 --- a/static/app/gettingStartedDocs/python/metrics.tsx +++ b/static/app/gettingStartedDocs/python/metrics.tsx @@ -13,6 +13,15 @@ export const metricsVerify = (params: DocsParams): ContentBlock => ({ type: 'conditional', condition: params.isMetricsSelected, content: [ + { + type: 'text', + text: tct( + 'Metrics are automatically enabled in your [code:sentry_sdk.init()] configuration. You can emit metrics using the [code:sentry_sdk.metrics] API.', + { + code: , + } + ), + }, { type: 'text', text: t( @@ -22,13 +31,23 @@ export const metricsVerify = (params: DocsParams): ContentBlock => ({ { type: 'code', language: 'python', - code: `from sentry_sdk import metrics + code: `import sentry_sdk +from sentry_sdk import metrics + +sentry_sdk.init( + dsn="${params.dsn.public}", +) -# Emit metrics metrics.count("checkout.failed", 1) metrics.gauge("queue.depth", 42) metrics.distribution("cart.amount_usd", 187.5)`, }, + { + type: 'text', + text: tct('For more detailed information, see the [link:metrics documentation].', { + link: , + }), + }, ], }); @@ -57,48 +76,7 @@ export const metrics = ({ ], }, ], - configure: (params: DocsParams) => [ - { - type: StepType.CONFIGURE, - content: [ - { - type: 'text', - text: tct( - 'Metrics are automatically enabled in your [code:sentry_sdk.init()] configuration. You can emit metrics using the [code:sentry_sdk.metrics] API.', - { - code: , - } - ), - }, - { - type: 'code', - language: 'python', - code: `import sentry_sdk -from sentry_sdk import metrics - -sentry_sdk.init( - dsn="${params.dsn.public}", -) - -# Emit custom metrics -metrics.count("checkout.failed", 1) -metrics.gauge("queue.depth", 42) -metrics.distribution("cart.amount_usd", 187.5)`, - }, - { - type: 'text', - text: tct( - 'For more detailed information, see the [link:metrics documentation].', - { - link: ( - - ), - } - ), - }, - ], - }, - ], + configure: () => [], verify: (params: DocsParams) => [ { type: StepType.VERIFY, diff --git a/static/app/views/explore/metrics/metricsOnboarding.tsx b/static/app/views/explore/metrics/metricsOnboarding.tsx index 24587a2cf2f0d1..7fcef814275191 100644 --- a/static/app/views/explore/metrics/metricsOnboarding.tsx +++ b/static/app/views/explore/metrics/metricsOnboarding.tsx @@ -10,10 +10,7 @@ import LoadingIndicator from 'sentry/components/loadingIndicator'; import {AuthTokenGeneratorProvider} from 'sentry/components/onboarding/gettingStartedDoc/authTokenGenerator'; import {ContentBlocksRenderer} from 'sentry/components/onboarding/gettingStartedDoc/contentBlocks/renderer'; import type {DocsParams} from 'sentry/components/onboarding/gettingStartedDoc/types'; -import { - ProductSolution, - StepType, -} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {ProductSolution} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {useSourcePackageRegistries} from 'sentry/components/onboarding/gettingStartedDoc/useSourcePackageRegistries'; import {useLoadGettingStarted} from 'sentry/components/onboarding/gettingStartedDoc/utils/useLoadGettingStarted'; import {DatePageFilter} from 'sentry/components/organizations/datePageFilter'; @@ -95,10 +92,9 @@ function OnboardingPanel({ ); } -const STEP_TITLES: Record = { - [StepType.INSTALL]: t('Install Sentry'), - [StepType.CONFIGURE]: t('Configure Sentry'), - [StepType.VERIFY]: t('Verify Sentry'), +const STEP_TITLES: Record<'install' | 'verify', string> = { + ['install']: t('Install Sentry'), + ['verify']: t('Send Metrics and Verify'), }; function Onboarding({organization, project}: OnboardingProps) { From 154180abb6fbb8dbfd3ba208475f60aeeb0fe8d8 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 14 Nov 2025 09:16:31 +0100 Subject: [PATCH 2/7] . --- .../app/views/explore/metrics/metricsOnboarding.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/static/app/views/explore/metrics/metricsOnboarding.tsx b/static/app/views/explore/metrics/metricsOnboarding.tsx index 7fcef814275191..45b0bc661496a2 100644 --- a/static/app/views/explore/metrics/metricsOnboarding.tsx +++ b/static/app/views/explore/metrics/metricsOnboarding.tsx @@ -10,7 +10,10 @@ import LoadingIndicator from 'sentry/components/loadingIndicator'; import {AuthTokenGeneratorProvider} from 'sentry/components/onboarding/gettingStartedDoc/authTokenGenerator'; import {ContentBlocksRenderer} from 'sentry/components/onboarding/gettingStartedDoc/contentBlocks/renderer'; import type {DocsParams} from 'sentry/components/onboarding/gettingStartedDoc/types'; -import {ProductSolution} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import { + ProductSolution, + StepType, +} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {useSourcePackageRegistries} from 'sentry/components/onboarding/gettingStartedDoc/useSourcePackageRegistries'; import {useLoadGettingStarted} from 'sentry/components/onboarding/gettingStartedDoc/utils/useLoadGettingStarted'; import {DatePageFilter} from 'sentry/components/organizations/datePageFilter'; @@ -92,9 +95,10 @@ function OnboardingPanel({ ); } -const STEP_TITLES: Record<'install' | 'verify', string> = { - ['install']: t('Install Sentry'), - ['verify']: t('Send Metrics and Verify'), +const STEP_TITLES: Record = { + [StepType.INSTALL]: t('Install Sentry'), + [StepType.CONFIGURE]: t('Configure Sentry'), + [StepType.VERIFY]: t('Send Metrics and Verify'), }; function Onboarding({organization, project}: OnboardingProps) { From ac330e3f8bd7f7c153cbac84168508b275e0e83f Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 14 Nov 2025 09:35:26 +0100 Subject: [PATCH 3/7] . --- .../app/gettingStartedDocs/python/metrics.spec.tsx | 13 +++++-------- static/app/gettingStartedDocs/python/metrics.tsx | 8 +------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/static/app/gettingStartedDocs/python/metrics.spec.tsx b/static/app/gettingStartedDocs/python/metrics.spec.tsx index 227b2087ee21d7..3581cab3b2cb4c 100644 --- a/static/app/gettingStartedDocs/python/metrics.spec.tsx +++ b/static/app/gettingStartedDocs/python/metrics.spec.tsx @@ -3,6 +3,7 @@ const {metrics} = jest.requireActual('sentry/gettingStartedDocs/python/metrics') describe('metrics', () => { const mockParams = { + isMetricsSelected: true, dsn: { public: 'https://test@example.com/123', }, @@ -17,20 +18,16 @@ describe('metrics', () => { expect(installSteps[0].type).toBe('install'); expect(installSteps[0].content).toHaveLength(2); - // Test configure step - const configureSteps = result.configure(mockParams); - expect(configureSteps).toHaveLength(1); - expect(configureSteps[0].type).toBe('configure'); - expect(configureSteps[0].content[1].code).toContain('sentry_sdk.init'); - expect(configureSteps[0].content[1].code).toContain(mockParams.dsn.public); - // Test verify step - const verifySteps = result.verify({isMetricsSelected: true}); + const verifySteps = result.verify(mockParams); expect(verifySteps).toHaveLength(1); expect(verifySteps[0].type).toBe('verify'); expect(verifySteps[0].content).toHaveLength(1); expect(verifySteps[0].content[0].type).toBe('conditional'); const conditionalContent = verifySteps[0].content[0].content; + + // expect(conditionalContent[1].code).toContain('sentry_sdk.init'); + // expect(conditionalContent[1].code).toContain(mockParams.dsn.public); expect(conditionalContent[1].code).toContain('metrics.count'); }); diff --git a/static/app/gettingStartedDocs/python/metrics.tsx b/static/app/gettingStartedDocs/python/metrics.tsx index 621d7cb76e70b6..7821cfc72d9a65 100644 --- a/static/app/gettingStartedDocs/python/metrics.tsx +++ b/static/app/gettingStartedDocs/python/metrics.tsx @@ -5,7 +5,7 @@ import { type DocsParams, type OnboardingConfig, } from 'sentry/components/onboarding/gettingStartedDoc/types'; -import {t, tct} from 'sentry/locale'; +import {tct} from 'sentry/locale'; import {getPythonInstallCodeBlock} from './utils'; @@ -22,12 +22,6 @@ export const metricsVerify = (params: DocsParams): ContentBlock => ({ } ), }, - { - type: 'text', - text: t( - 'Send test metrics from your app to verify metrics are arriving in Sentry.' - ), - }, { type: 'code', language: 'python', From 68b01e6b7d8f319d65ef3731f78449ed9d2a18da Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 14 Nov 2025 09:50:34 +0100 Subject: [PATCH 4/7] . --- .../app/gettingStartedDocs/python/metrics.tsx | 62 ++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/static/app/gettingStartedDocs/python/metrics.tsx b/static/app/gettingStartedDocs/python/metrics.tsx index 7821cfc72d9a65..8d08b1a5b949a3 100644 --- a/static/app/gettingStartedDocs/python/metrics.tsx +++ b/static/app/gettingStartedDocs/python/metrics.tsx @@ -5,7 +5,7 @@ import { type DocsParams, type OnboardingConfig, } from 'sentry/components/onboarding/gettingStartedDoc/types'; -import {tct} from 'sentry/locale'; +import {t, tct} from 'sentry/locale'; import {getPythonInstallCodeBlock} from './utils'; @@ -15,33 +15,18 @@ export const metricsVerify = (params: DocsParams): ContentBlock => ({ content: [ { type: 'text', - text: tct( - 'Metrics are automatically enabled in your [code:sentry_sdk.init()] configuration. You can emit metrics using the [code:sentry_sdk.metrics] API.', - { - code: , - } - ), + text: t('Send metrics from your app to verify metrics are arriving in Sentry.'), }, { type: 'code', language: 'python', - code: `import sentry_sdk -from sentry_sdk import metrics - -sentry_sdk.init( - dsn="${params.dsn.public}", -) + code: `from sentry_sdk import metrics +# Emit metrics metrics.count("checkout.failed", 1) metrics.gauge("queue.depth", 42) metrics.distribution("cart.amount_usd", 187.5)`, }, - { - type: 'text', - text: tct('For more detailed information, see the [link:metrics documentation].', { - link: , - }), - }, ], }); @@ -73,8 +58,43 @@ export const metrics = ({ configure: () => [], verify: (params: DocsParams) => [ { - type: StepType.VERIFY, - content: [metricsVerify(params)], + type: StepType.CONFIGURE, + content: [ + { + type: 'text', + text: tct( + 'Metrics are automatically enabled in your [code:sentry_sdk.init()] configuration. You can emit metrics using the [code:sentry_sdk.metrics] API.', + { + code: , + } + ), + }, + { + type: 'code', + language: 'python', + code: `import sentry_sdk +from sentry_sdk import metrics + +sentry_sdk.init( + dsn="${params.dsn.public}", +) + +metrics.count("checkout.failed", 1) +metrics.gauge("queue.depth", 42) +metrics.distribution("cart.amount_usd", 187.5)`, + }, + { + type: 'text', + text: tct( + 'For more detailed information, see the [link:metrics documentation].', + { + link: ( + + ), + } + ), + }, + ], }, ], }); From 37004705d464c76d762ce3e57ca2c18d494ed62a Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 14 Nov 2025 09:58:38 +0100 Subject: [PATCH 5/7] . --- static/app/gettingStartedDocs/python/metrics.spec.tsx | 4 ++-- static/app/gettingStartedDocs/python/metrics.tsx | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/static/app/gettingStartedDocs/python/metrics.spec.tsx b/static/app/gettingStartedDocs/python/metrics.spec.tsx index 3581cab3b2cb4c..1a46d5241f2c86 100644 --- a/static/app/gettingStartedDocs/python/metrics.spec.tsx +++ b/static/app/gettingStartedDocs/python/metrics.spec.tsx @@ -26,8 +26,8 @@ describe('metrics', () => { expect(verifySteps[0].content[0].type).toBe('conditional'); const conditionalContent = verifySteps[0].content[0].content; - // expect(conditionalContent[1].code).toContain('sentry_sdk.init'); - // expect(conditionalContent[1].code).toContain(mockParams.dsn.public); + expect(conditionalContent[1].code).toContain('sentry_sdk.init'); + expect(conditionalContent[1].code).toContain(mockParams.dsn.public); expect(conditionalContent[1].code).toContain('metrics.count'); }); diff --git a/static/app/gettingStartedDocs/python/metrics.tsx b/static/app/gettingStartedDocs/python/metrics.tsx index 8d08b1a5b949a3..a12f20ee26a809 100644 --- a/static/app/gettingStartedDocs/python/metrics.tsx +++ b/static/app/gettingStartedDocs/python/metrics.tsx @@ -15,7 +15,9 @@ export const metricsVerify = (params: DocsParams): ContentBlock => ({ content: [ { type: 'text', - text: t('Send metrics from your app to verify metrics are arriving in Sentry.'), + text: t( + 'Send test metrics from your app to verify metrics are arriving in Sentry.' + ), }, { type: 'code', From 73849d96b5b6f00c9f9c77f00e3227cc0d0386f9 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 14 Nov 2025 10:04:00 +0100 Subject: [PATCH 6/7] . --- static/app/gettingStartedDocs/python/metrics.spec.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/static/app/gettingStartedDocs/python/metrics.spec.tsx b/static/app/gettingStartedDocs/python/metrics.spec.tsx index 1a46d5241f2c86..44e848a637a16b 100644 --- a/static/app/gettingStartedDocs/python/metrics.spec.tsx +++ b/static/app/gettingStartedDocs/python/metrics.spec.tsx @@ -3,7 +3,6 @@ const {metrics} = jest.requireActual('sentry/gettingStartedDocs/python/metrics') describe('metrics', () => { const mockParams = { - isMetricsSelected: true, dsn: { public: 'https://test@example.com/123', }, From a6fdc8fd586534f24ed32d3159c2b608c28dfdb0 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Fri, 14 Nov 2025 10:11:18 +0100 Subject: [PATCH 7/7] . --- static/app/gettingStartedDocs/python/metrics.spec.tsx | 11 +++++------ static/app/gettingStartedDocs/python/metrics.tsx | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/static/app/gettingStartedDocs/python/metrics.spec.tsx b/static/app/gettingStartedDocs/python/metrics.spec.tsx index 44e848a637a16b..cde3b1fa0d0347 100644 --- a/static/app/gettingStartedDocs/python/metrics.spec.tsx +++ b/static/app/gettingStartedDocs/python/metrics.spec.tsx @@ -21,13 +21,12 @@ describe('metrics', () => { const verifySteps = result.verify(mockParams); expect(verifySteps).toHaveLength(1); expect(verifySteps[0].type).toBe('verify'); - expect(verifySteps[0].content).toHaveLength(1); - expect(verifySteps[0].content[0].type).toBe('conditional'); - const conditionalContent = verifySteps[0].content[0].content; + expect(verifySteps[0].content).toHaveLength(3); + const codeSnippet = verifySteps[0].content[1].code; - expect(conditionalContent[1].code).toContain('sentry_sdk.init'); - expect(conditionalContent[1].code).toContain(mockParams.dsn.public); - expect(conditionalContent[1].code).toContain('metrics.count'); + expect(codeSnippet).toContain('sentry_sdk.init'); + expect(codeSnippet).toContain(mockParams.dsn.public); + expect(codeSnippet).toContain('metrics.count'); }); it('generates metrics onboarding config with custom parameters', () => { diff --git a/static/app/gettingStartedDocs/python/metrics.tsx b/static/app/gettingStartedDocs/python/metrics.tsx index a12f20ee26a809..173f45597ff50b 100644 --- a/static/app/gettingStartedDocs/python/metrics.tsx +++ b/static/app/gettingStartedDocs/python/metrics.tsx @@ -60,7 +60,7 @@ export const metrics = ({ configure: () => [], verify: (params: DocsParams) => [ { - type: StepType.CONFIGURE, + type: StepType.VERIFY, content: [ { type: 'text',