diff --git a/static/app/components/onboarding/productSelection.tsx b/static/app/components/onboarding/productSelection.tsx index 0c8abf9bab2095..42cdb0dc0855f9 100644 --- a/static/app/components/onboarding/productSelection.tsx +++ b/static/app/components/onboarding/productSelection.tsx @@ -489,7 +489,7 @@ export const platformProductAvailability = { ProductSolution.PROFILING, ProductSolution.LOGS, ], - unity: [ProductSolution.LOGS], + unity: [ProductSolution.LOGS, ProductSolution.METRICS], unreal: [ProductSolution.LOGS], } as Record; diff --git a/static/app/data/platformCategories.tsx b/static/app/data/platformCategories.tsx index 113ae30aa0b8d0..0b94f86fd672ad 100644 --- a/static/app/data/platformCategories.tsx +++ b/static/app/data/platformCategories.tsx @@ -485,6 +485,7 @@ export const withMetricsOnboarding: Set = new Set([ 'ruby', 'ruby-rack', 'ruby-rails', + 'unity', ]); // List of platforms that do not have metrics support. We make use of this list in the product to not provide any Metrics @@ -506,6 +507,7 @@ export const limitedMetricsSupportPrefixes: Set = new Set([ 'react-native', 'ruby', 'flutter', + 'unity', ]); export const profiling: PlatformKey[] = [ diff --git a/static/app/gettingStartedDocs/unity/index.tsx b/static/app/gettingStartedDocs/unity/index.tsx index 2d9adc901245c9..68bc2582cbae8c 100644 --- a/static/app/gettingStartedDocs/unity/index.tsx +++ b/static/app/gettingStartedDocs/unity/index.tsx @@ -2,6 +2,7 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {crashReport} from './crashReport'; import {logs} from './logs'; +import {metrics} from './metrics'; import {onboarding} from './onboarding'; const docs: Docs = { @@ -9,6 +10,7 @@ const docs: Docs = { feedbackOnboardingCrashApi: crashReport, crashReportOnboarding: crashReport, logsOnboarding: logs, + metricsOnboarding: metrics, }; export default docs; diff --git a/static/app/gettingStartedDocs/unity/metrics.spec.tsx b/static/app/gettingStartedDocs/unity/metrics.spec.tsx new file mode 100644 index 00000000000000..cb1a63e74cdae6 --- /dev/null +++ b/static/app/gettingStartedDocs/unity/metrics.spec.tsx @@ -0,0 +1,29 @@ +import {renderWithOnboardingLayout} from 'sentry-test/onboarding/renderWithOnboardingLayout'; +import {screen} from 'sentry-test/reactTestingLibrary'; +import {textWithMarkupMatcher} from 'sentry-test/utils'; + +import {ProductSolution} from 'sentry/components/onboarding/gettingStartedDoc/types'; + +import docs from '.'; + +describe('metrics', () => { + it('unity metrics onboarding docs', () => { + renderWithOnboardingLayout(docs, { + selectedProducts: [ProductSolution.METRICS], + }); + + expect( + screen.getByText(textWithMarkupMatcher(/SentrySdk\.Metrics\.Increment/)) + ).toBeInTheDocument(); + }); + + it('does not render metrics configuration when metrics is not enabled', () => { + renderWithOnboardingLayout(docs, { + selectedProducts: [], + }); + + expect( + screen.queryByText(textWithMarkupMatcher(/SentrySdk\.Metrics\.Increment/)) + ).not.toBeInTheDocument(); + }); +}); diff --git a/static/app/gettingStartedDocs/unity/metrics.tsx b/static/app/gettingStartedDocs/unity/metrics.tsx new file mode 100644 index 00000000000000..9da762075eb957 --- /dev/null +++ b/static/app/gettingStartedDocs/unity/metrics.tsx @@ -0,0 +1,106 @@ +import {ExternalLink} from '@sentry/scraps/link'; + +import type { + ContentBlock, + DocsParams, + OnboardingConfig, +} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {t, tct} from 'sentry/locale'; + +export const metricsVerify = (params: DocsParams): ContentBlock => ({ + type: 'conditional', + condition: params.isMetricsSelected, + content: [ + { + type: 'text', + text: t( + 'Send test metrics from your app to verify metrics are arriving in Sentry.' + ), + }, + { + type: 'code', + language: 'csharp', + code: `using Sentry; + +SentrySdk.Metrics.Increment("player_interaction", + tags: new Dictionary {{"action", "jump"}, {"scene", "main_menu"}}); +SentrySdk.Metrics.Distribution("scene_load", 230, + unit: MeasurementUnit.Duration.Millisecond, + tags: new Dictionary {{"scene", "world_1"}}); +SentrySdk.Metrics.Gauge("active_players", 42, + tags: new Dictionary {{"server", "us-east-1"}});`, + }, + { + type: 'text', + text: tct('For more detailed information, see the [link:metrics documentation].', { + link: , + }), + }, + ], +}); + +export const metrics: OnboardingConfig = { + install: () => [ + { + type: StepType.INSTALL, + content: [ + { + type: 'text', + text: tct( + 'Metrics for Unity are supported in Sentry SDK version [code:4.1.0] and above.', + { + code: , + } + ), + }, + ], + }, + ], + configure: (params: DocsParams) => [ + { + type: StepType.CONFIGURE, + content: [ + { + type: 'text', + text: t( + 'To enable metrics in your Unity game, you need to configure the Sentry SDK with metrics enabled.' + ), + }, + { + type: 'text', + text: tct( + 'Open your project settings: [strong:Tools > Sentry > Advanced > Metrics] and check the [strong:Enable Metrics] option.', + { + strong: , + } + ), + }, + { + type: 'text', + text: t('Alternatively, you can enable metrics programmatically:'), + }, + { + type: 'code', + language: 'csharp', + code: `SentrySdk.Init(options => +{ + options.Dsn = "${params.dsn.public}"; + + // Enable metrics to be sent to Sentry + options.ExperimentalMetrics = new ExperimentalMetricsOptions + { + EnableCodeLocations = true + }; +});`, + }, + ], + }, + ], + verify: (params: DocsParams) => [ + { + type: StepType.VERIFY, + content: [metricsVerify(params)], + }, + ], +}; diff --git a/static/app/gettingStartedDocs/unity/onboarding.spec.tsx b/static/app/gettingStartedDocs/unity/onboarding.spec.tsx index 3bc144b21733a5..3e88a2ad9e3050 100644 --- a/static/app/gettingStartedDocs/unity/onboarding.spec.tsx +++ b/static/app/gettingStartedDocs/unity/onboarding.spec.tsx @@ -4,6 +4,8 @@ import {renderWithOnboardingLayout} from 'sentry-test/onboarding/renderWithOnboa import {screen} from 'sentry-test/reactTestingLibrary'; import {textWithMarkupMatcher} from 'sentry-test/utils'; +import {ProductSolution} from 'sentry/components/onboarding/gettingStartedDoc/types'; + import docs from '.'; function renderMockRequests() { @@ -32,4 +34,16 @@ describe('unity onboarding docs', () => { ) ).toBeInTheDocument(); }); + + it('renders metrics snippet when metrics product is selected', () => { + renderMockRequests(); + + renderWithOnboardingLayout(docs, { + selectedProducts: [ProductSolution.METRICS], + }); + + expect( + screen.getByText(textWithMarkupMatcher(/SentrySdk\.Metrics\.Increment/)) + ).toBeInTheDocument(); + }); }); diff --git a/static/app/gettingStartedDocs/unity/onboarding.tsx b/static/app/gettingStartedDocs/unity/onboarding.tsx index 6ac25fed2f8005..b3123a46519409 100644 --- a/static/app/gettingStartedDocs/unity/onboarding.tsx +++ b/static/app/gettingStartedDocs/unity/onboarding.tsx @@ -11,6 +11,7 @@ import {getConsoleExtensions} from 'sentry/components/onboarding/gettingStartedD import {t, tct} from 'sentry/locale'; import {logsVerify} from './logs'; +import {metricsVerify} from './metrics'; const getVerifySnippet = () => ` using Sentry; // On the top of the script @@ -74,6 +75,19 @@ export const onboarding: OnboardingConfig = { }, ], }, + { + type: 'conditional', + condition: params.isMetricsSelected, + content: [ + { + type: 'text', + text: tct( + 'To enable metrics, navigate to [strong:Tools > Sentry > Advanced > Metrics] and check the [strong:Enable Metrics] option.', + {strong: } + ), + }, + ], + }, { type: 'text', text: tct( @@ -113,6 +127,14 @@ export const onboarding: OnboardingConfig = { }, ] satisfies OnboardingStep[]) : []), + ...(params.isMetricsSelected + ? ([ + { + title: t('Metrics'), + content: [metricsVerify(params)], + }, + ] satisfies OnboardingStep[]) + : []), { title: t('Troubleshooting'), content: [