diff --git a/static/app/gettingStartedDocs/dotnet-aspnet/index.tsx b/static/app/gettingStartedDocs/dotnet-aspnet/index.tsx index 7a1808c107bd14..207cb2dbc3392a 100644 --- a/static/app/gettingStartedDocs/dotnet-aspnet/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-aspnet/index.tsx @@ -1,5 +1,6 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {dotnetLogs} from 'sentry/gettingStartedDocs/dotnet/logs'; +import {dotnetMetrics} from 'sentry/gettingStartedDocs/dotnet/metrics'; import { feedbackOnboardingJsLoader, replayOnboardingJsLoader, @@ -14,6 +15,7 @@ const docs: Docs = { crashReportOnboarding: crashReport, feedbackOnboardingJsLoader, logsOnboarding: dotnetLogs(), + metricsOnboarding: dotnetMetrics(), }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-aspnetcore/index.tsx b/static/app/gettingStartedDocs/dotnet-aspnetcore/index.tsx index 7a1808c107bd14..207cb2dbc3392a 100644 --- a/static/app/gettingStartedDocs/dotnet-aspnetcore/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-aspnetcore/index.tsx @@ -1,5 +1,6 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {dotnetLogs} from 'sentry/gettingStartedDocs/dotnet/logs'; +import {dotnetMetrics} from 'sentry/gettingStartedDocs/dotnet/metrics'; import { feedbackOnboardingJsLoader, replayOnboardingJsLoader, @@ -14,6 +15,7 @@ const docs: Docs = { crashReportOnboarding: crashReport, feedbackOnboardingJsLoader, logsOnboarding: dotnetLogs(), + metricsOnboarding: dotnetMetrics(), }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-awslambda/index.tsx b/static/app/gettingStartedDocs/dotnet-awslambda/index.tsx index c0b0a998cf224b..350daecc7abe1b 100644 --- a/static/app/gettingStartedDocs/dotnet-awslambda/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-awslambda/index.tsx @@ -1,6 +1,7 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {feedback} from 'sentry/gettingStartedDocs/dotnet/feedback'; import {dotnetLogs} from 'sentry/gettingStartedDocs/dotnet/logs'; +import {dotnetMetrics} from 'sentry/gettingStartedDocs/dotnet/metrics'; import {crashReport} from './crashReport'; import {onboarding} from './onboarding'; @@ -10,6 +11,7 @@ const docs: Docs = { feedbackOnboardingCrashApi: feedback, crashReportOnboarding: crashReport, logsOnboarding: dotnetLogs(), + metricsOnboarding: dotnetMetrics(), }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-gcpfunctions/index.tsx b/static/app/gettingStartedDocs/dotnet-gcpfunctions/index.tsx index c0b0a998cf224b..350daecc7abe1b 100644 --- a/static/app/gettingStartedDocs/dotnet-gcpfunctions/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-gcpfunctions/index.tsx @@ -1,6 +1,7 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {feedback} from 'sentry/gettingStartedDocs/dotnet/feedback'; import {dotnetLogs} from 'sentry/gettingStartedDocs/dotnet/logs'; +import {dotnetMetrics} from 'sentry/gettingStartedDocs/dotnet/metrics'; import {crashReport} from './crashReport'; import {onboarding} from './onboarding'; @@ -10,6 +11,7 @@ const docs: Docs = { feedbackOnboardingCrashApi: feedback, crashReportOnboarding: crashReport, logsOnboarding: dotnetLogs(), + metricsOnboarding: dotnetMetrics(), }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-maui/index.tsx b/static/app/gettingStartedDocs/dotnet-maui/index.tsx index c0b0a998cf224b..350daecc7abe1b 100644 --- a/static/app/gettingStartedDocs/dotnet-maui/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-maui/index.tsx @@ -1,6 +1,7 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {feedback} from 'sentry/gettingStartedDocs/dotnet/feedback'; import {dotnetLogs} from 'sentry/gettingStartedDocs/dotnet/logs'; +import {dotnetMetrics} from 'sentry/gettingStartedDocs/dotnet/metrics'; import {crashReport} from './crashReport'; import {onboarding} from './onboarding'; @@ -10,6 +11,7 @@ const docs: Docs = { feedbackOnboardingCrashApi: feedback, crashReportOnboarding: crashReport, logsOnboarding: dotnetLogs(), + metricsOnboarding: dotnetMetrics(), }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-winforms/index.tsx b/static/app/gettingStartedDocs/dotnet-winforms/index.tsx index c0b0a998cf224b..350daecc7abe1b 100644 --- a/static/app/gettingStartedDocs/dotnet-winforms/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-winforms/index.tsx @@ -1,6 +1,7 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {feedback} from 'sentry/gettingStartedDocs/dotnet/feedback'; import {dotnetLogs} from 'sentry/gettingStartedDocs/dotnet/logs'; +import {dotnetMetrics} from 'sentry/gettingStartedDocs/dotnet/metrics'; import {crashReport} from './crashReport'; import {onboarding} from './onboarding'; @@ -10,6 +11,7 @@ const docs: Docs = { feedbackOnboardingCrashApi: feedback, crashReportOnboarding: crashReport, logsOnboarding: dotnetLogs(), + metricsOnboarding: dotnetMetrics(), }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-wpf/index.tsx b/static/app/gettingStartedDocs/dotnet-wpf/index.tsx index c0b0a998cf224b..350daecc7abe1b 100644 --- a/static/app/gettingStartedDocs/dotnet-wpf/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-wpf/index.tsx @@ -1,6 +1,7 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {feedback} from 'sentry/gettingStartedDocs/dotnet/feedback'; import {dotnetLogs} from 'sentry/gettingStartedDocs/dotnet/logs'; +import {dotnetMetrics} from 'sentry/gettingStartedDocs/dotnet/metrics'; import {crashReport} from './crashReport'; import {onboarding} from './onboarding'; @@ -10,6 +11,7 @@ const docs: Docs = { feedbackOnboardingCrashApi: feedback, crashReportOnboarding: crashReport, logsOnboarding: dotnetLogs(), + metricsOnboarding: dotnetMetrics(), }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-xamarin/index.tsx b/static/app/gettingStartedDocs/dotnet-xamarin/index.tsx index c0b0a998cf224b..350daecc7abe1b 100644 --- a/static/app/gettingStartedDocs/dotnet-xamarin/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-xamarin/index.tsx @@ -1,6 +1,7 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {feedback} from 'sentry/gettingStartedDocs/dotnet/feedback'; import {dotnetLogs} from 'sentry/gettingStartedDocs/dotnet/logs'; +import {dotnetMetrics} from 'sentry/gettingStartedDocs/dotnet/metrics'; import {crashReport} from './crashReport'; import {onboarding} from './onboarding'; @@ -10,6 +11,7 @@ const docs: Docs = { feedbackOnboardingCrashApi: feedback, crashReportOnboarding: crashReport, logsOnboarding: dotnetLogs(), + metricsOnboarding: dotnetMetrics(), }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet/index.tsx b/static/app/gettingStartedDocs/dotnet/index.tsx index 93cddb7d29e984..3d89c3153966a3 100644 --- a/static/app/gettingStartedDocs/dotnet/index.tsx +++ b/static/app/gettingStartedDocs/dotnet/index.tsx @@ -1,5 +1,6 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {dotnetLogs} from 'sentry/gettingStartedDocs/dotnet/logs'; +import {dotnetMetrics} from 'sentry/gettingStartedDocs/dotnet/metrics'; import {crashReport} from './crashReport'; import {feedback} from './feedback'; @@ -12,6 +13,7 @@ const docs: Docs = { crashReportOnboarding: crashReport, profilingOnboarding: profiling, logsOnboarding: dotnetLogs(), + metricsOnboarding: dotnetMetrics(), }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet/metrics.spec.tsx b/static/app/gettingStartedDocs/dotnet/metrics.spec.tsx new file mode 100644 index 00000000000000..5d36ef607f9b07 --- /dev/null +++ b/static/app/gettingStartedDocs/dotnet/metrics.spec.tsx @@ -0,0 +1,34 @@ +// Only import and test functions that don't have circular dependencies +const {dotnetMetrics} = jest.requireActual('sentry/gettingStartedDocs/dotnet/metrics'); + +describe('metrics', () => { + const mockParams = { + dsn: { + public: 'https://test@example.com/123', + }, + sourcePackageRegistries: { + isLoading: false, + }, + }; + + it('generates metrics onboarding config with default parameters', () => { + const result = dotnetMetrics(); + + // Test install step + const installSteps = result.install(mockParams); + expect(installSteps).toHaveLength(1); + expect(installSteps[0].type).toBe('install'); + expect(installSteps[0].content).toHaveLength(2); + + // Test verify step + const verifySteps = result.verify(mockParams); + expect(verifySteps).toHaveLength(1); + expect(verifySteps[0].type).toBe('verify'); + expect(verifySteps[0].content).toHaveLength(3); + const codeSnippet = verifySteps[0].content[1].code; + + expect(codeSnippet).toContain('SentrySdk.Init'); + expect(codeSnippet).toContain(mockParams.dsn.public); + expect(codeSnippet).toContain('Metrics.EmitCounter'); + }); +}); diff --git a/static/app/gettingStartedDocs/dotnet/metrics.tsx b/static/app/gettingStartedDocs/dotnet/metrics.tsx index bacbf8c344097d..e9464f47ab6fc3 100644 --- a/static/app/gettingStartedDocs/dotnet/metrics.tsx +++ b/static/app/gettingStartedDocs/dotnet/metrics.tsx @@ -1,8 +1,14 @@ import {ExternalLink} from 'sentry/components/core/link'; import { + StepType, type ContentBlock, type DocsParams, + type OnboardingConfig, } from 'sentry/components/onboarding/gettingStartedDoc/types'; +import { + getInstallSnippetCoreCli, + getInstallSnippetPackageManager, +} from 'sentry/gettingStartedDocs/dotnet/utils'; import {tct} from 'sentry/locale'; export const metricsVerify = (params: DocsParams): ContentBlock => ({ @@ -39,3 +45,82 @@ SentrySdk.Experimental.Metrics.EmitGauge("page_load", 15.0, SentryUnits.Duration }, ], }); + +export const dotnetMetrics = (): OnboardingConfig => ({ + install: params => [ + { + type: StepType.INSTALL, + content: [ + { + type: 'text', + text: tct( + 'Install our .NET SDK with a minimum version that supports metrics ([code:6.1.0] or higher).', + { + code: , + } + ), + }, + { + type: 'code', + tabs: [ + { + label: 'Package Manager', + language: 'shell', + code: getInstallSnippetPackageManager(params), + }, + { + label: '.NET Core CLI', + language: 'shell', + code: getInstallSnippetCoreCli(params), + }, + ], + }, + ], + }, + ], + configure: () => [], + verify: (params: DocsParams) => [ + { + type: StepType.VERIFY, + content: [ + { + type: 'text', + text: tct( + 'Metrics are automatically enabled in your [code:SentrySdk.Init] configuration. You can emit metrics using the [code:SentrySdk.Experimental.Metrics] API.', + { + code: , + } + ), + }, + { + type: 'code', + language: 'dotnet', + code: `using Sentry; + +SentrySdk.Init(options => +{ + options.Dsn = ${params.dsn.public}; +}); + +SentrySdk.Experimental.Metrics.EmitCounter("button_click", 5, + [new KeyValuePair("browser", "Firefox"), new KeyValuePair("app_version", "1.0.0")]); +SentrySdk.Experimental.Metrics.EmitDistribution("page_load", 15.0, SentryUnits.Duration.Millisecond, + [new KeyValuePair("page", "/home")]); +SentrySdk.Experimental.Metrics.EmitGauge("page_load", 15.0, SentryUnits.Duration.Millisecond, + [new KeyValuePair("page", "/home")]);`, + }, + { + type: 'text', + text: tct( + 'For more detailed information, see the [link:metrics documentation].', + { + link: ( + + ), + } + ), + }, + ], + }, + ], +}); diff --git a/static/app/gettingStartedDocs/dotnet/utils.tsx b/static/app/gettingStartedDocs/dotnet/utils.tsx index 309afd7d8e4bde..9e2456452a7cef 100644 --- a/static/app/gettingStartedDocs/dotnet/utils.tsx +++ b/static/app/gettingStartedDocs/dotnet/utils.tsx @@ -3,7 +3,9 @@ import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersi export const getInstallSnippetPackageManager = (params: DocsParams) => { let version = '3.34.0'; - if (params.isLogsSelected) { + if (params.isMetricsSelected) { + version = '6.1.0'; + } else if (params.isLogsSelected) { version = '6.0.0'; } else if (params.isProfilingSelected) { version = '4.3.0'; @@ -15,7 +17,9 @@ Install-Package Sentry -Version ${getPackageVersion(params, 'sentry.dotnet', ver export const getInstallSnippetCoreCli = (params: DocsParams) => { let version = '3.34.0'; - if (params.isLogsSelected) { + if (params.isMetricsSelected) { + version = '6.1.0'; + } else if (params.isLogsSelected) { version = '6.0.0'; } else if (params.isProfilingSelected) { version = '4.3.0';