Skip to content

Commit f8b6ef1

Browse files
feat(onboarding): Add metrics onboarding for the Python SDK (#102641)
Empty state metrics onboarding for Python projects. Closes LOGS-458 --------- Co-authored-by: Priscila Oliveira <priscila.oliveira@sentry.io>
1 parent 6c990c4 commit f8b6ef1

Some content is hidden

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

68 files changed

+896
-37
lines changed

static/app/components/onboarding/productSelection.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ function getDisabledProducts(organization: Organization): DisabledProducts {
3333
const hasPerformance = organization.features.includes('performance-view');
3434
const hasProfiling = organization.features.includes('profiling-view');
3535
const hasLogs = organization.features.includes('ourlogs-enabled');
36+
const hasMetrics = organization.features.includes('tracemetrics-enabled');
3637
const isSelfHostedErrorsOnly = ConfigStore.get('isSelfHostedErrorsOnly');
3738

3839
let reason = t('This feature is not enabled on your Sentry installation.');
@@ -76,6 +77,12 @@ function getDisabledProducts(organization: Organization): DisabledProducts {
7677
onClick: createClickHandler('organizations:ourlogs-enabled', 'Logs'),
7778
};
7879
}
80+
if (!hasMetrics) {
81+
disabledProducts[ProductSolution.METRICS] = {
82+
reason,
83+
onClick: createClickHandler('organizations:tracemetrics-enabled', 'Metrics'),
84+
};
85+
}
7986
return disabledProducts;
8087
}
8188

@@ -236,91 +243,109 @@ export const platformProductAvailability = {
236243
ProductSolution.PERFORMANCE_MONITORING,
237244
ProductSolution.PROFILING,
238245
ProductSolution.LOGS,
246+
ProductSolution.METRICS,
239247
],
240248
'python-aiohttp': [
241249
ProductSolution.PERFORMANCE_MONITORING,
242250
ProductSolution.PROFILING,
243251
ProductSolution.LOGS,
252+
ProductSolution.METRICS,
244253
],
245254
'python-asgi': [
246255
ProductSolution.PERFORMANCE_MONITORING,
247256
ProductSolution.PROFILING,
248257
ProductSolution.LOGS,
258+
ProductSolution.METRICS,
249259
],
250260
'python-awslambda': [
251261
ProductSolution.PERFORMANCE_MONITORING,
252262
ProductSolution.PROFILING,
253263
ProductSolution.LOGS,
264+
ProductSolution.METRICS,
254265
],
255266
'python-bottle': [
256267
ProductSolution.PERFORMANCE_MONITORING,
257268
ProductSolution.PROFILING,
258269
ProductSolution.LOGS,
270+
ProductSolution.METRICS,
259271
],
260272
'python-celery': [
261273
ProductSolution.PERFORMANCE_MONITORING,
262274
ProductSolution.PROFILING,
263275
ProductSolution.LOGS,
276+
ProductSolution.METRICS,
264277
],
265278
'python-chalice': [
266279
ProductSolution.PERFORMANCE_MONITORING,
267280
ProductSolution.PROFILING,
268281
ProductSolution.LOGS,
282+
ProductSolution.METRICS,
269283
],
270284
'python-django': [
271285
ProductSolution.PERFORMANCE_MONITORING,
272286
ProductSolution.PROFILING,
273287
ProductSolution.LOGS,
288+
ProductSolution.METRICS,
274289
],
275290
'python-falcon': [
276291
ProductSolution.PERFORMANCE_MONITORING,
277292
ProductSolution.PROFILING,
278293
ProductSolution.LOGS,
294+
ProductSolution.METRICS,
279295
],
280296
'python-fastapi': [
281297
ProductSolution.PERFORMANCE_MONITORING,
282298
ProductSolution.PROFILING,
283299
ProductSolution.LOGS,
300+
ProductSolution.METRICS,
284301
],
285302
'python-flask': [
286303
ProductSolution.PERFORMANCE_MONITORING,
287304
ProductSolution.PROFILING,
288305
ProductSolution.LOGS,
306+
ProductSolution.METRICS,
289307
],
290308
'python-gcpfunctions': [
291309
ProductSolution.PERFORMANCE_MONITORING,
292310
ProductSolution.PROFILING,
293311
ProductSolution.LOGS,
312+
ProductSolution.METRICS,
294313
],
295314
'python-quart': [
296315
ProductSolution.PERFORMANCE_MONITORING,
297316
ProductSolution.PROFILING,
298317
ProductSolution.LOGS,
318+
ProductSolution.METRICS,
299319
],
300320
'python-rq': [
301321
ProductSolution.PERFORMANCE_MONITORING,
302322
ProductSolution.PROFILING,
303323
ProductSolution.LOGS,
324+
ProductSolution.METRICS,
304325
],
305326
'python-serverless': [
306327
ProductSolution.PERFORMANCE_MONITORING,
307328
ProductSolution.PROFILING,
308329
ProductSolution.LOGS,
330+
ProductSolution.METRICS,
309331
],
310332
'python-tornado': [
311333
ProductSolution.PERFORMANCE_MONITORING,
312334
ProductSolution.PROFILING,
313335
ProductSolution.LOGS,
336+
ProductSolution.METRICS,
314337
],
315338
'python-starlette': [
316339
ProductSolution.PERFORMANCE_MONITORING,
317340
ProductSolution.PROFILING,
318341
ProductSolution.LOGS,
342+
ProductSolution.METRICS,
319343
],
320344
'python-wsgi': [
321345
ProductSolution.PERFORMANCE_MONITORING,
322346
ProductSolution.PROFILING,
323347
ProductSolution.LOGS,
348+
ProductSolution.METRICS,
324349
],
325350
ruby: [
326351
ProductSolution.PERFORMANCE_MONITORING,
@@ -531,6 +556,18 @@ export function ProductSelection({
531556
checked={urlProducts.includes(ProductSolution.LOGS)}
532557
/>
533558
)}
559+
{products.includes(ProductSolution.METRICS) && (
560+
<Product
561+
label={t('Metrics')}
562+
description={t(
563+
'Custom metrics for tracking application performance and usage, automatically trace-connected.'
564+
)}
565+
docLink="https://docs.sentry.io/product/explore/metrics/"
566+
onClick={() => handleClickProduct(ProductSolution.METRICS)}
567+
disabled={disabledProducts[ProductSolution.METRICS]}
568+
checked={urlProducts.includes(ProductSolution.METRICS)}
569+
/>
570+
)}
534571
{products.includes(ProductSolution.SESSION_REPLAY) && (
535572
<Product
536573
label={t('Session Replay')}

static/app/data/platformCategories.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,29 @@ export const withoutLoggingSupport: Set<PlatformKey> = new Set([
391391
]);
392392

393393
// List of platforms that have metrics onboarding checklist content
394-
export const withMetricsOnboarding: Set<PlatformKey> = new Set([]);
394+
export const withMetricsOnboarding: Set<PlatformKey> = new Set([
395+
'python',
396+
'python-aiohttp',
397+
'python-asgi',
398+
'python-awslambda',
399+
'python-bottle',
400+
'python-celery',
401+
'python-chalice',
402+
'python-django',
403+
'python-falcon',
404+
'python-fastapi',
405+
'python-flask',
406+
'python-gcpfunctions',
407+
'python-pyramid',
408+
'python-quart',
409+
'python-rq',
410+
'python-sanic',
411+
'python-serverless',
412+
'python-starlette',
413+
'python-tornado',
414+
'python-tryton',
415+
'python-wsgi',
416+
]);
395417

396418
// List of platforms that do not have metrics support. We make use of this list in the product to not provide any Metrics
397419
export const withoutMetricsSupport: Set<PlatformKey> = new Set([]);

static/app/gettingStartedDocs/python/aiohttp/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {crashReport} from 'sentry/gettingStartedDocs/python/python/crashReport';
88
import {featureFlag} from 'sentry/gettingStartedDocs/python/python/featureFlag';
99
import {logs} from 'sentry/gettingStartedDocs/python/python/logs';
1010
import {mcp} from 'sentry/gettingStartedDocs/python/python/mcp';
11+
import {metrics} from 'sentry/gettingStartedDocs/python/python/metrics';
1112
import {profiling} from 'sentry/gettingStartedDocs/python/python/profiling';
1213

1314
import {onboarding} from './onboarding';
@@ -22,6 +23,7 @@ const docs: Docs = {
2223
agentMonitoringOnboarding: agentMonitoring,
2324
mcpOnboarding: mcp,
2425
logsOnboarding: logs(),
26+
metricsOnboarding: metrics(),
2527
};
2628

2729
export default docs;

static/app/gettingStartedDocs/python/aiohttp/onboarding.spec.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,30 @@ describe('aiohttp onboarding docs', () => {
119119
)
120120
).not.toBeInTheDocument();
121121
});
122+
123+
it('renders metrics configuration when metrics are selected', () => {
124+
renderWithOnboardingLayout(docs, {
125+
selectedProducts: [ProductSolution.METRICS],
126+
});
127+
128+
// Renders metrics verification steps
129+
expect(
130+
screen.getByText(
131+
'Send test metrics from your app to verify metrics are arriving in Sentry.'
132+
)
133+
).toBeInTheDocument();
134+
});
135+
136+
it('renders without metrics configuration when metrics are not selected', () => {
137+
renderWithOnboardingLayout(docs, {
138+
selectedProducts: [],
139+
});
140+
141+
// Does not render metrics verification steps
142+
expect(
143+
screen.queryByText(
144+
'Send test metrics from your app to verify metrics are arriving in Sentry.'
145+
)
146+
).not.toBeInTheDocument();
147+
});
122148
});

static/app/gettingStartedDocs/python/aiohttp/onboarding.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {
44
type DocsParams,
55
type OnboardingConfig,
66
} from 'sentry/components/onboarding/gettingStartedDoc/types';
7-
import {verify} from 'sentry/gettingStartedDocs/python/python/logs';
7+
import {logsVerify} from 'sentry/gettingStartedDocs/python/python/logs';
8+
import {metricsVerify} from 'sentry/gettingStartedDocs/python/python/metrics';
89
import {alternativeProfiling} from 'sentry/gettingStartedDocs/python/python/profiling';
910
import {
1011
getPythonAiocontextvarsCodeBlocks,
@@ -125,7 +126,8 @@ app.add_routes([web.get('/', hello)])
125126
web.run_app(app)
126127
`,
127128
},
128-
verify(params),
129+
logsVerify(params),
130+
metricsVerify(params),
129131
{
130132
type: 'text',
131133
text: [

static/app/gettingStartedDocs/python/asgi/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {agentMonitoring} from 'sentry/gettingStartedDocs/python/python/agentMoni
33
import {crashReport} from 'sentry/gettingStartedDocs/python/python/crashReport';
44
import {logs} from 'sentry/gettingStartedDocs/python/python/logs';
55
import {mcp} from 'sentry/gettingStartedDocs/python/python/mcp';
6+
import {metrics} from 'sentry/gettingStartedDocs/python/python/metrics';
67
import {profiling} from 'sentry/gettingStartedDocs/python/python/profiling';
78

89
import {onboarding} from './onboarding';
@@ -14,6 +15,7 @@ const docs: Docs = {
1415
agentMonitoringOnboarding: agentMonitoring,
1516
mcpOnboarding: mcp,
1617
logsOnboarding: logs(),
18+
metricsOnboarding: metrics(),
1719
};
1820

1921
export default docs;

static/app/gettingStartedDocs/python/asgi/onboarding.spec.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,30 @@ describe('asgi onboarding docs', () => {
115115
)
116116
).not.toBeInTheDocument();
117117
});
118+
119+
it('renders metrics configuration when metrics are selected', () => {
120+
renderWithOnboardingLayout(docs, {
121+
selectedProducts: [ProductSolution.METRICS],
122+
});
123+
124+
// Renders metrics verification steps
125+
expect(
126+
screen.getByText(
127+
'Send test metrics from your app to verify metrics are arriving in Sentry.'
128+
)
129+
).toBeInTheDocument();
130+
});
131+
132+
it('renders without metrics configuration when metrics are not selected', () => {
133+
renderWithOnboardingLayout(docs, {
134+
selectedProducts: [],
135+
});
136+
137+
// Does not render metrics verification steps
138+
expect(
139+
screen.queryByText(
140+
'Send test metrics from your app to verify metrics are arriving in Sentry.'
141+
)
142+
).not.toBeInTheDocument();
143+
});
118144
});

static/app/gettingStartedDocs/python/asgi/onboarding.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {
44
type DocsParams,
55
type OnboardingConfig,
66
} from 'sentry/components/onboarding/gettingStartedDoc/types';
7-
import {verify} from 'sentry/gettingStartedDocs/python/python/logs';
7+
import {logsVerify} from 'sentry/gettingStartedDocs/python/python/logs';
8+
import {metricsVerify} from 'sentry/gettingStartedDocs/python/python/metrics';
89
import {alternativeProfiling} from 'sentry/gettingStartedDocs/python/python/profiling';
910
import {getPythonInstallCodeBlock} from 'sentry/gettingStartedDocs/python/python/utils';
1011
import {t, tct} from 'sentry/locale';
@@ -139,7 +140,8 @@ export const onboarding: OnboardingConfig = {
139140
language: 'python',
140141
code: getVerifySnippet(),
141142
},
142-
verify(params),
143+
logsVerify(params),
144+
metricsVerify(params),
143145
{
144146
type: 'text',
145147
text: tct(

static/app/gettingStartedDocs/python/awslambda/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types';
22
import {agentMonitoring} from 'sentry/gettingStartedDocs/python/python/agentMonitoring';
33
import {crashReport} from 'sentry/gettingStartedDocs/python/python/crashReport';
44
import {logs} from 'sentry/gettingStartedDocs/python/python/logs';
5+
import {metrics} from 'sentry/gettingStartedDocs/python/python/metrics';
56

67
import {onboarding} from './onboarding';
78
import {profiling} from './profiling';
@@ -12,6 +13,7 @@ const docs: Docs = {
1213
profilingOnboarding: profiling,
1314
agentMonitoringOnboarding: agentMonitoring,
1415
logsOnboarding: logs(),
16+
metricsOnboarding: metrics(),
1517
};
1618

1719
export default docs;

static/app/gettingStartedDocs/python/awslambda/onboarding.spec.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,30 @@ describe('awslambda onboarding docs', () => {
9797
screen.queryByText(textWithMarkupMatcher(/enable_logs=True,/))
9898
).not.toBeInTheDocument();
9999
});
100+
101+
it('renders metrics configuration when metrics are selected', () => {
102+
renderWithOnboardingLayout(docs, {
103+
selectedProducts: [ProductSolution.METRICS],
104+
});
105+
106+
// Renders metrics verification steps
107+
expect(
108+
screen.getByText(
109+
'Send test metrics from your app to verify metrics are arriving in Sentry.'
110+
)
111+
).toBeInTheDocument();
112+
});
113+
114+
it('renders without metrics configuration when metrics are not selected', () => {
115+
renderWithOnboardingLayout(docs, {
116+
selectedProducts: [],
117+
});
118+
119+
// Does not render metrics verification steps
120+
expect(
121+
screen.queryByText(
122+
'Send test metrics from your app to verify metrics are arriving in Sentry.'
123+
)
124+
).not.toBeInTheDocument();
125+
});
100126
});

0 commit comments

Comments
 (0)