diff --git a/static/app/components/onboarding/productSelection.tsx b/static/app/components/onboarding/productSelection.tsx index 6481a90a1462ce..262285b3ab47df 100644 --- a/static/app/components/onboarding/productSelection.tsx +++ b/static/app/components/onboarding/productSelection.tsx @@ -92,15 +92,19 @@ export const platformProductAvailability = { 'apple-macos': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING], bun: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], capacitor: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.SESSION_REPLAY], - dotnet: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING], - 'dotnet-aspnet': [ProductSolution.PERFORMANCE_MONITORING], - 'dotnet-aspnetcore': [ProductSolution.PERFORMANCE_MONITORING], - 'dotnet-awslambda': [ProductSolution.PERFORMANCE_MONITORING], - 'dotnet-gcpfunctions': [ProductSolution.PERFORMANCE_MONITORING], - 'dotnet-maui': [ProductSolution.PERFORMANCE_MONITORING], - 'dotnet-winforms': [ProductSolution.PERFORMANCE_MONITORING], - 'dotnet-wpf': [ProductSolution.PERFORMANCE_MONITORING], - 'dotnet-xamarin': [ProductSolution.PERFORMANCE_MONITORING], + dotnet: [ + ProductSolution.PERFORMANCE_MONITORING, + ProductSolution.PROFILING, + ProductSolution.LOGS, + ], + 'dotnet-aspnet': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], + 'dotnet-aspnetcore': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], + 'dotnet-awslambda': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], + 'dotnet-gcpfunctions': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], + 'dotnet-maui': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], + 'dotnet-winforms': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], + 'dotnet-wpf': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], + 'dotnet-xamarin': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], dart: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], kotlin: [ProductSolution.PERFORMANCE_MONITORING], go: [ @@ -143,6 +147,7 @@ export const platformProductAvailability = { ProductSolution.LOGS, ProductSolution.METRICS, ], + godot: [ProductSolution.LOGS], ionic: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.SESSION_REPLAY], java: [ ProductSolution.PERFORMANCE_MONITORING, @@ -232,6 +237,7 @@ export const platformProductAvailability = { ProductSolution.LOGS, ProductSolution.METRICS, ], + native: [ProductSolution.LOGS], node: [ ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING, @@ -322,6 +328,7 @@ export const platformProductAvailability = { 'php-symfony': [ ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING, + ProductSolution.LOGS, ProductSolution.METRICS, ], python: [ @@ -447,6 +454,8 @@ export const platformProductAvailability = { ProductSolution.PROFILING, ProductSolution.LOGS, ], + unity: [ProductSolution.LOGS], + unreal: [ProductSolution.LOGS], } as Record; type ProductProps = { diff --git a/static/app/data/platformCategories.tsx b/static/app/data/platformCategories.tsx index efbead41d2cbf1..0674b52f79e4b5 100644 --- a/static/app/data/platformCategories.tsx +++ b/static/app/data/platformCategories.tsx @@ -304,7 +304,18 @@ export const withLoggingOnboarding: Set = new Set([ 'apple-ios', 'apple-macos', 'bun', + 'cocoa-objc', + 'cocoa-swift', 'dart', + 'dotnet', + 'dotnet-aspnet', + 'dotnet-aspnetcore', + 'dotnet-awslambda', + 'dotnet-gcpfunctions', + 'dotnet-maui', + 'dotnet-winforms', + 'dotnet-wpf', + 'dotnet-xamarin', 'flutter', 'go', 'go-echo', @@ -315,6 +326,7 @@ export const withLoggingOnboarding: Set = new Set([ 'go-iris', 'go-martini', 'go-negroni', + 'godot', 'java', 'java-log4j2', 'java-logback', @@ -336,6 +348,7 @@ export const withLoggingOnboarding: Set = new Set([ 'javascript-sveltekit', 'javascript-tanstackstart-react', 'javascript-vue', + 'native', 'node', 'node-azurefunctions', 'node-connect', @@ -350,6 +363,7 @@ export const withLoggingOnboarding: Set = new Set([ 'node-nestjs', 'php', 'php-laravel', + 'php-symfony', 'python', 'python-aiohttp', 'python-asgi', @@ -376,6 +390,8 @@ export const withLoggingOnboarding: Set = new Set([ 'ruby-rack', 'ruby-rails', 'rust', + 'unity', + 'unreal', ]); // List of platforms that do not have logging support. We make use of this list in the product to not provide any Logging diff --git a/static/app/gettingStartedDocs/dotnet-aspnet/index.tsx b/static/app/gettingStartedDocs/dotnet-aspnet/index.tsx index 418194d2ba23e5..40e9cd5b4d6615 100644 --- a/static/app/gettingStartedDocs/dotnet-aspnet/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-aspnet/index.tsx @@ -1,4 +1,5 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {logs} from 'sentry/gettingStartedDocs/dotnet/logs'; import { feedbackOnboardingJsLoader, replayOnboardingJsLoader, @@ -12,6 +13,7 @@ const docs: Docs = { replayOnboardingJsLoader, crashReportOnboarding: crashReport, feedbackOnboardingJsLoader, + logsOnboarding: logs, }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-aspnet/onboarding.spec.tsx b/static/app/gettingStartedDocs/dotnet-aspnet/onboarding.spec.tsx index 454be3250381ce..96843a7744a74c 100644 --- a/static/app/gettingStartedDocs/dotnet-aspnet/onboarding.spec.tsx +++ b/static/app/gettingStartedDocs/dotnet-aspnet/onboarding.spec.tsx @@ -14,12 +14,14 @@ describe('aspnet onboarding docs', () => { version: '1.99.9', }, }, + selectedProducts: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], }); // Renders main headings expect(screen.getByRole('heading', {name: 'Install'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Configure SDK'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Documentation'})).toBeInTheDocument(); + expect(screen.getByRole('heading', {name: 'Verify Logs'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Samples'})).toBeInTheDocument(); // Renders SDK version from registry @@ -39,4 +41,14 @@ describe('aspnet onboarding docs', () => { await screen.findByText(textWithMarkupMatcher(/o.TracesSampleRate/)) ).toBeInTheDocument(); }); + + it('renders logs onboarding docs correctly', async () => { + renderWithOnboardingLayout(docs, { + selectedProducts: [ProductSolution.LOGS], + }); + + expect( + await screen.findByText(textWithMarkupMatcher(/o.EnableLogs/)) + ).toBeInTheDocument(); + }); }); diff --git a/static/app/gettingStartedDocs/dotnet-aspnet/onboarding.tsx b/static/app/gettingStartedDocs/dotnet-aspnet/onboarding.tsx index 1854b54fe6eda7..bfa70ba82d1929 100644 --- a/static/app/gettingStartedDocs/dotnet-aspnet/onboarding.tsx +++ b/static/app/gettingStartedDocs/dotnet-aspnet/onboarding.tsx @@ -4,6 +4,7 @@ import type { OnboardingConfig, } from 'sentry/components/onboarding/gettingStartedDoc/types'; import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {logsVerify} from 'sentry/gettingStartedDocs/dotnet/logs'; import {t, tct} from 'sentry/locale'; import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion'; @@ -50,6 +51,12 @@ public class MvcApplication : HttpApplication // We recommend adjusting this value in production o.TracesSampleRate = 1.0;` : '' + }${ + params.isLogsSelected + ? ` + // Enable logs to be sent to Sentry + o.EnableLogs = true;` + : '' } // If you are using EF (and installed the NuGet package): o.AddEntityFramework(); @@ -136,7 +143,7 @@ export const onboarding: OnboardingConfig = { }, ], // TODO: Add proper verify step - verify: () => [ + verify: params => [ { title: t('Documentation'), content: [ @@ -153,6 +160,14 @@ export const onboarding: OnboardingConfig = { }, ], }, + ...(params.isLogsSelected + ? [ + { + title: t('Verify Logs'), + content: [logsVerify(params)], + }, + ] + : []), { title: t('Samples'), content: [ diff --git a/static/app/gettingStartedDocs/dotnet-aspnetcore/index.tsx b/static/app/gettingStartedDocs/dotnet-aspnetcore/index.tsx index 418194d2ba23e5..40e9cd5b4d6615 100644 --- a/static/app/gettingStartedDocs/dotnet-aspnetcore/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-aspnetcore/index.tsx @@ -1,4 +1,5 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {logs} from 'sentry/gettingStartedDocs/dotnet/logs'; import { feedbackOnboardingJsLoader, replayOnboardingJsLoader, @@ -12,6 +13,7 @@ const docs: Docs = { replayOnboardingJsLoader, crashReportOnboarding: crashReport, feedbackOnboardingJsLoader, + logsOnboarding: logs, }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-aspnetcore/onboarding.spec.tsx b/static/app/gettingStartedDocs/dotnet-aspnetcore/onboarding.spec.tsx index cdca3a177530c0..e4b5ce1edc12cf 100644 --- a/static/app/gettingStartedDocs/dotnet-aspnetcore/onboarding.spec.tsx +++ b/static/app/gettingStartedDocs/dotnet-aspnetcore/onboarding.spec.tsx @@ -14,6 +14,7 @@ describe('aspnetcore onboarding docs', () => { version: '1.99.9', }, }, + selectedProducts: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], }); // Renders main headings @@ -21,6 +22,7 @@ describe('aspnetcore onboarding docs', () => { expect(screen.getByRole('heading', {name: 'Configure SDK'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Verify'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Tracing'})).toBeInTheDocument(); + expect(screen.getByRole('heading', {name: 'Verify Logs'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Samples'})).toBeInTheDocument(); // Renders SDK version from registry @@ -40,4 +42,14 @@ describe('aspnetcore onboarding docs', () => { await screen.findByText(textWithMarkupMatcher(/o.TracesSampleRate/)) ).toBeInTheDocument(); }); + + it('renders logs onboarding docs correctly', async () => { + renderWithOnboardingLayout(docs, { + selectedProducts: [ProductSolution.LOGS], + }); + + expect( + await screen.findByText(textWithMarkupMatcher(/o.EnableLogs/)) + ).toBeInTheDocument(); + }); }); diff --git a/static/app/gettingStartedDocs/dotnet-aspnetcore/onboarding.tsx b/static/app/gettingStartedDocs/dotnet-aspnetcore/onboarding.tsx index eec93af36e87b7..d88b4bb36e3f43 100644 --- a/static/app/gettingStartedDocs/dotnet-aspnetcore/onboarding.tsx +++ b/static/app/gettingStartedDocs/dotnet-aspnetcore/onboarding.tsx @@ -5,6 +5,7 @@ import type { OnboardingStep, } from 'sentry/components/onboarding/gettingStartedDoc/types'; import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {logsVerify} from 'sentry/gettingStartedDocs/dotnet/logs'; import {t, tct} from 'sentry/locale'; import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion'; @@ -40,6 +41,12 @@ public static IHostBuilder CreateHostBuilder(string[] args) => // We recommend adjusting this value in production o.TracesSampleRate = 1.0;` : '' + }${ + params.isLogsSelected + ? ` + // Enable logs to be sent to Sentry + o.EnableLogs = true;` + : '' } }); });`; @@ -177,6 +184,14 @@ export const onboarding: OnboardingConfig = { }, ] satisfies OnboardingStep[]) : []), + ...(params.isLogsSelected + ? [ + { + title: t('Verify Logs'), + content: [logsVerify(params)], + }, + ] + : []), { title: t('Samples'), content: [ diff --git a/static/app/gettingStartedDocs/dotnet-awslambda/index.tsx b/static/app/gettingStartedDocs/dotnet-awslambda/index.tsx index 5a0e27e30c0730..8ebb0527b3b6ac 100644 --- a/static/app/gettingStartedDocs/dotnet-awslambda/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-awslambda/index.tsx @@ -1,5 +1,6 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {feedback} from 'sentry/gettingStartedDocs/dotnet/feedback'; +import {logs} from 'sentry/gettingStartedDocs/dotnet/logs'; import {crashReport} from './crashReport'; import {onboarding} from './onboarding'; @@ -8,6 +9,7 @@ const docs: Docs = { onboarding, feedbackOnboardingCrashApi: feedback, crashReportOnboarding: crashReport, + logsOnboarding: logs, }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-awslambda/onboarding.spec.tsx b/static/app/gettingStartedDocs/dotnet-awslambda/onboarding.spec.tsx index 02268d6e32b8a9..aef7247759e1b1 100644 --- a/static/app/gettingStartedDocs/dotnet-awslambda/onboarding.spec.tsx +++ b/static/app/gettingStartedDocs/dotnet-awslambda/onboarding.spec.tsx @@ -14,12 +14,14 @@ describe('awslambda onboarding docs', () => { version: '1.99.9', }, }, + selectedProducts: [ProductSolution.LOGS], }); // Renders main headings expect(screen.getByRole('heading', {name: 'Install'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Configure SDK'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Verify'})).toBeInTheDocument(); + expect(screen.getByRole('heading', {name: 'Verify Logs'})).toBeInTheDocument(); // Renders SDK version from registry expect( @@ -38,4 +40,14 @@ describe('awslambda onboarding docs', () => { await screen.findByText(textWithMarkupMatcher(/o.TracesSampleRate/)) ).toBeInTheDocument(); }); + + it('renders logs onboarding docs correctly', async () => { + renderWithOnboardingLayout(docs, { + selectedProducts: [ProductSolution.LOGS], + }); + + expect( + await screen.findByText(textWithMarkupMatcher(/o.EnableLogs/)) + ).toBeInTheDocument(); + }); }); diff --git a/static/app/gettingStartedDocs/dotnet-awslambda/onboarding.tsx b/static/app/gettingStartedDocs/dotnet-awslambda/onboarding.tsx index 1df5ee6f5d7e5c..b700e9baf64ce5 100644 --- a/static/app/gettingStartedDocs/dotnet-awslambda/onboarding.tsx +++ b/static/app/gettingStartedDocs/dotnet-awslambda/onboarding.tsx @@ -4,6 +4,7 @@ import type { OnboardingConfig, } from 'sentry/components/onboarding/gettingStartedDoc/types'; import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {logsVerify} from 'sentry/gettingStartedDocs/dotnet/logs'; import {t, tct} from 'sentry/locale'; import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion'; @@ -41,6 +42,12 @@ public class LambdaEntryPoint : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFu // We recommend adjusting this value in production. o.TracesSampleRate = 1.0;` : '' + }${ + params.isLogsSelected + ? ` + // Enable logs to be sent to Sentry + o.EnableLogs = true;` + : '' } }) .UseStartup(); @@ -126,7 +133,7 @@ export const onboarding: OnboardingConfig = { ], }, ], - verify: () => [ + verify: params => [ { type: StepType.VERIFY, content: [ @@ -161,5 +168,13 @@ export const onboarding: OnboardingConfig = { }, ], }, + ...(params.isLogsSelected + ? [ + { + title: t('Verify Logs'), + content: [logsVerify(params)], + }, + ] + : []), ], }; diff --git a/static/app/gettingStartedDocs/dotnet-gcpfunctions/index.tsx b/static/app/gettingStartedDocs/dotnet-gcpfunctions/index.tsx index 5a0e27e30c0730..8ebb0527b3b6ac 100644 --- a/static/app/gettingStartedDocs/dotnet-gcpfunctions/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-gcpfunctions/index.tsx @@ -1,5 +1,6 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {feedback} from 'sentry/gettingStartedDocs/dotnet/feedback'; +import {logs} from 'sentry/gettingStartedDocs/dotnet/logs'; import {crashReport} from './crashReport'; import {onboarding} from './onboarding'; @@ -8,6 +9,7 @@ const docs: Docs = { onboarding, feedbackOnboardingCrashApi: feedback, crashReportOnboarding: crashReport, + logsOnboarding: logs, }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-gcpfunctions/onboarding.spec.tsx b/static/app/gettingStartedDocs/dotnet-gcpfunctions/onboarding.spec.tsx index 7a86e1d25f5e75..ce508d0a26e19f 100644 --- a/static/app/gettingStartedDocs/dotnet-gcpfunctions/onboarding.spec.tsx +++ b/static/app/gettingStartedDocs/dotnet-gcpfunctions/onboarding.spec.tsx @@ -2,6 +2,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 './index'; describe('gcpfunctions onboarding docs', () => { @@ -12,12 +14,14 @@ describe('gcpfunctions onboarding docs', () => { version: '1.99.9', }, }, + selectedProducts: [ProductSolution.LOGS], }); // Renders main headings expect(screen.getByRole('heading', {name: 'Install'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Configure SDK'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Verify'})).toBeInTheDocument(); + expect(screen.getByRole('heading', {name: 'Verify Logs'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Samples'})).toBeInTheDocument(); // Renders SDK version from registry @@ -36,4 +40,14 @@ describe('gcpfunctions onboarding docs', () => { ) ).toBeInTheDocument(); }); + + it('renders logs onboarding docs correctly', async () => { + renderWithOnboardingLayout(docs, { + selectedProducts: [ProductSolution.LOGS], + }); + + expect( + await screen.findByText(textWithMarkupMatcher(/EnableLogs/)) + ).toBeInTheDocument(); + }); }); diff --git a/static/app/gettingStartedDocs/dotnet-gcpfunctions/onboarding.tsx b/static/app/gettingStartedDocs/dotnet-gcpfunctions/onboarding.tsx index 8636849bbfa8de..f4a1fe2b736887 100644 --- a/static/app/gettingStartedDocs/dotnet-gcpfunctions/onboarding.tsx +++ b/static/app/gettingStartedDocs/dotnet-gcpfunctions/onboarding.tsx @@ -4,6 +4,7 @@ import type { OnboardingConfig, } from 'sentry/components/onboarding/gettingStartedDoc/types'; import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {logsVerify} from 'sentry/gettingStartedDocs/dotnet/logs'; import {t, tct} from 'sentry/locale'; import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion'; @@ -58,6 +59,12 @@ const getConfigureJsonSnippet = (params: DocsParams) => ` // We recommend adjusting this value in production. "TracesSampleRate": 1` : '' + }${ + params.isLogsSelected + ? `, + // Enable logs to be sent to Sentry + "EnableLogs": true` + : '' } } }`; @@ -146,7 +153,7 @@ export const onboarding: OnboardingConfig = { ], }, ], - verify: () => [ + verify: params => [ { type: StepType.VERIFY, content: [ @@ -161,6 +168,14 @@ export const onboarding: OnboardingConfig = { }, ], }, + ...(params.isLogsSelected + ? [ + { + title: t('Verify Logs'), + content: [logsVerify(params)], + }, + ] + : []), { title: t('Samples'), content: [ diff --git a/static/app/gettingStartedDocs/dotnet-maui/index.tsx b/static/app/gettingStartedDocs/dotnet-maui/index.tsx index 5a0e27e30c0730..8ebb0527b3b6ac 100644 --- a/static/app/gettingStartedDocs/dotnet-maui/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-maui/index.tsx @@ -1,5 +1,6 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {feedback} from 'sentry/gettingStartedDocs/dotnet/feedback'; +import {logs} from 'sentry/gettingStartedDocs/dotnet/logs'; import {crashReport} from './crashReport'; import {onboarding} from './onboarding'; @@ -8,6 +9,7 @@ const docs: Docs = { onboarding, feedbackOnboardingCrashApi: feedback, crashReportOnboarding: crashReport, + logsOnboarding: logs, }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-maui/onboarding.spec.tsx b/static/app/gettingStartedDocs/dotnet-maui/onboarding.spec.tsx index b2e5bb106c95e1..8168b4c4ac2cc9 100644 --- a/static/app/gettingStartedDocs/dotnet-maui/onboarding.spec.tsx +++ b/static/app/gettingStartedDocs/dotnet-maui/onboarding.spec.tsx @@ -14,6 +14,7 @@ describe('maui onboarding docs', () => { version: '1.99.9', }, }, + selectedProducts: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], }); // Renders main headings @@ -21,6 +22,7 @@ describe('maui onboarding docs', () => { expect(screen.getByRole('heading', {name: 'Configure SDK'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Verify'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Tracing'})).toBeInTheDocument(); + expect(screen.getByRole('heading', {name: 'Verify Logs'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Sample Application'})).toBeInTheDocument(); // Renders SDK version from registry @@ -40,4 +42,14 @@ describe('maui onboarding docs', () => { await screen.findByText(textWithMarkupMatcher(/options.TracesSampleRate/)) ).toBeInTheDocument(); }); + + it('renders logs onboarding docs correctly', async () => { + renderWithOnboardingLayout(docs, { + selectedProducts: [ProductSolution.LOGS], + }); + + expect( + await screen.findByText(textWithMarkupMatcher(/options.EnableLogs/)) + ).toBeInTheDocument(); + }); }); diff --git a/static/app/gettingStartedDocs/dotnet-maui/onboarding.tsx b/static/app/gettingStartedDocs/dotnet-maui/onboarding.tsx index 027ac54907d6b7..202a972eed07f5 100644 --- a/static/app/gettingStartedDocs/dotnet-maui/onboarding.tsx +++ b/static/app/gettingStartedDocs/dotnet-maui/onboarding.tsx @@ -5,6 +5,7 @@ import type { OnboardingStep, } from 'sentry/components/onboarding/gettingStartedDoc/types'; import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {logsVerify} from 'sentry/gettingStartedDocs/dotnet/logs'; import {t, tct} from 'sentry/locale'; import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion'; @@ -46,6 +47,12 @@ public static MauiApp CreateMauiApp() // We recommend adjusting this value in production. options.TracesSampleRate = 1.0;` : '' + }${ + params.isLogsSelected + ? ` + // Enable logs to be sent to Sentry + options.EnableLogs = true;` + : '' } // Other Sentry options can be set here. @@ -204,6 +211,14 @@ export const onboarding: OnboardingConfig = { }, ] satisfies OnboardingStep[]) : []), + ...(params.isLogsSelected + ? [ + { + title: t('Verify Logs'), + content: [logsVerify(params)], + }, + ] + : []), { title: t('Sample Application'), content: [ diff --git a/static/app/gettingStartedDocs/dotnet-winforms/index.tsx b/static/app/gettingStartedDocs/dotnet-winforms/index.tsx index 5a0e27e30c0730..8ebb0527b3b6ac 100644 --- a/static/app/gettingStartedDocs/dotnet-winforms/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-winforms/index.tsx @@ -1,5 +1,6 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {feedback} from 'sentry/gettingStartedDocs/dotnet/feedback'; +import {logs} from 'sentry/gettingStartedDocs/dotnet/logs'; import {crashReport} from './crashReport'; import {onboarding} from './onboarding'; @@ -8,6 +9,7 @@ const docs: Docs = { onboarding, feedbackOnboardingCrashApi: feedback, crashReportOnboarding: crashReport, + logsOnboarding: logs, }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-winforms/onboarding.spec.tsx b/static/app/gettingStartedDocs/dotnet-winforms/onboarding.spec.tsx index a8daae30e306c9..ecf649896c319c 100644 --- a/static/app/gettingStartedDocs/dotnet-winforms/onboarding.spec.tsx +++ b/static/app/gettingStartedDocs/dotnet-winforms/onboarding.spec.tsx @@ -14,6 +14,7 @@ describe('winforms onboarding docs', () => { version: '1.99.9', }, }, + selectedProducts: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], }); // Renders main headings @@ -22,6 +23,7 @@ describe('winforms onboarding docs', () => { expect(screen.getByRole('heading', {name: 'Verify'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Tracing'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Documentation'})).toBeInTheDocument(); + expect(screen.getByRole('heading', {name: 'Verify Logs'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Samples'})).toBeInTheDocument(); // Renders SDK version from registry @@ -41,4 +43,14 @@ describe('winforms onboarding docs', () => { await screen.findByText(textWithMarkupMatcher(/o.TracesSampleRate/)) ).toBeInTheDocument(); }); + + it('renders logs onboarding docs correctly', async () => { + renderWithOnboardingLayout(docs, { + selectedProducts: [ProductSolution.LOGS], + }); + + expect( + await screen.findByText(textWithMarkupMatcher(/o.EnableLogs/)) + ).toBeInTheDocument(); + }); }); diff --git a/static/app/gettingStartedDocs/dotnet-winforms/onboarding.tsx b/static/app/gettingStartedDocs/dotnet-winforms/onboarding.tsx index c8fb24560fe707..a40a9f2f38ae8a 100644 --- a/static/app/gettingStartedDocs/dotnet-winforms/onboarding.tsx +++ b/static/app/gettingStartedDocs/dotnet-winforms/onboarding.tsx @@ -5,6 +5,7 @@ import type { OnboardingStep, } from 'sentry/components/onboarding/gettingStartedDoc/types'; import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {logsVerify} from 'sentry/gettingStartedDocs/dotnet/logs'; import {t, tct} from 'sentry/locale'; import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion'; @@ -37,6 +38,12 @@ static class Program // We recommend adjusting this value in production. o.TracesSampleRate = 1.0;` : '' + }${ + params.isLogsSelected + ? ` + // Enable logs to be sent to Sentry + o.EnableLogs = true;` + : '' } }); // Configure WinForms to throw exceptions so Sentry can capture them. @@ -177,6 +184,14 @@ export const onboarding: OnboardingConfig = { }, ] satisfies OnboardingStep[]) : []), + ...(params.isLogsSelected + ? [ + { + title: t('Verify Logs'), + content: [logsVerify(params)], + }, + ] + : []), { title: t('Samples'), content: [ diff --git a/static/app/gettingStartedDocs/dotnet-wpf/index.tsx b/static/app/gettingStartedDocs/dotnet-wpf/index.tsx index 5a0e27e30c0730..8ebb0527b3b6ac 100644 --- a/static/app/gettingStartedDocs/dotnet-wpf/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-wpf/index.tsx @@ -1,5 +1,6 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {feedback} from 'sentry/gettingStartedDocs/dotnet/feedback'; +import {logs} from 'sentry/gettingStartedDocs/dotnet/logs'; import {crashReport} from './crashReport'; import {onboarding} from './onboarding'; @@ -8,6 +9,7 @@ const docs: Docs = { onboarding, feedbackOnboardingCrashApi: feedback, crashReportOnboarding: crashReport, + logsOnboarding: logs, }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-wpf/onboarding.spec.tsx b/static/app/gettingStartedDocs/dotnet-wpf/onboarding.spec.tsx index a9ca3500d49ef6..fc0da5db51c823 100644 --- a/static/app/gettingStartedDocs/dotnet-wpf/onboarding.spec.tsx +++ b/static/app/gettingStartedDocs/dotnet-wpf/onboarding.spec.tsx @@ -14,6 +14,7 @@ describe('wpf onboarding docs', () => { version: '1.99.9', }, }, + selectedProducts: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], }); // Renders main headings @@ -22,6 +23,7 @@ describe('wpf onboarding docs', () => { expect(screen.getByRole('heading', {name: 'Verify'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Tracing'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Documentation'})).toBeInTheDocument(); + expect(screen.getByRole('heading', {name: 'Verify Logs'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Samples'})).toBeInTheDocument(); // Renders SDK version from registry @@ -41,4 +43,14 @@ describe('wpf onboarding docs', () => { await screen.findByText(textWithMarkupMatcher(/o.TracesSampleRate/)) ).toBeInTheDocument(); }); + + it('renders logs onboarding docs correctly', async () => { + renderWithOnboardingLayout(docs, { + selectedProducts: [ProductSolution.LOGS], + }); + + expect( + await screen.findByText(textWithMarkupMatcher(/o.EnableLogs/)) + ).toBeInTheDocument(); + }); }); diff --git a/static/app/gettingStartedDocs/dotnet-wpf/onboarding.tsx b/static/app/gettingStartedDocs/dotnet-wpf/onboarding.tsx index 979477248a423e..e5cfb167b44f59 100644 --- a/static/app/gettingStartedDocs/dotnet-wpf/onboarding.tsx +++ b/static/app/gettingStartedDocs/dotnet-wpf/onboarding.tsx @@ -5,6 +5,7 @@ import type { OnboardingStep, } from 'sentry/components/onboarding/gettingStartedDoc/types'; import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {logsVerify} from 'sentry/gettingStartedDocs/dotnet/logs'; import {t, tct} from 'sentry/locale'; import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion'; @@ -36,6 +37,12 @@ public partial class App : Application // We recommend adjusting this value in production. o.TracesSampleRate = 1.0;` : '' + }${ + params.isLogsSelected + ? ` + // Enable logs to be sent to Sentry + o.EnableLogs = true;` + : '' } }); } @@ -177,6 +184,14 @@ export const onboarding: OnboardingConfig = { }, ] satisfies OnboardingStep[]) : []), + ...(params.isLogsSelected + ? [ + { + title: t('Verify Logs'), + content: [logsVerify(params)], + }, + ] + : []), { title: t('Samples'), content: [ diff --git a/static/app/gettingStartedDocs/dotnet-xamarin/index.tsx b/static/app/gettingStartedDocs/dotnet-xamarin/index.tsx index 5a0e27e30c0730..8ebb0527b3b6ac 100644 --- a/static/app/gettingStartedDocs/dotnet-xamarin/index.tsx +++ b/static/app/gettingStartedDocs/dotnet-xamarin/index.tsx @@ -1,5 +1,6 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {feedback} from 'sentry/gettingStartedDocs/dotnet/feedback'; +import {logs} from 'sentry/gettingStartedDocs/dotnet/logs'; import {crashReport} from './crashReport'; import {onboarding} from './onboarding'; @@ -8,6 +9,7 @@ const docs: Docs = { onboarding, feedbackOnboardingCrashApi: feedback, crashReportOnboarding: crashReport, + logsOnboarding: logs, }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet-xamarin/onboarding.spec.tsx b/static/app/gettingStartedDocs/dotnet-xamarin/onboarding.spec.tsx index ca05fc9099fabe..4eabe228cfb584 100644 --- a/static/app/gettingStartedDocs/dotnet-xamarin/onboarding.spec.tsx +++ b/static/app/gettingStartedDocs/dotnet-xamarin/onboarding.spec.tsx @@ -2,6 +2,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 './index'; describe('xamarin onboarding docs', () => { @@ -12,6 +14,7 @@ describe('xamarin onboarding docs', () => { version: '1.99.9', }, }, + selectedProducts: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], }); // Renders main headings @@ -21,6 +24,7 @@ describe('xamarin onboarding docs', () => { expect(screen.getByRole('heading', {name: 'Tracing'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Documentation'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Limitations'})).toBeInTheDocument(); + expect(screen.getByRole('heading', {name: 'Verify Logs'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Samples'})).toBeInTheDocument(); // Renders SDK version from registry diff --git a/static/app/gettingStartedDocs/dotnet-xamarin/onboarding.tsx b/static/app/gettingStartedDocs/dotnet-xamarin/onboarding.tsx index 532b292c5a519c..07f42b4c8dcbb1 100644 --- a/static/app/gettingStartedDocs/dotnet-xamarin/onboarding.tsx +++ b/static/app/gettingStartedDocs/dotnet-xamarin/onboarding.tsx @@ -4,6 +4,7 @@ import type { OnboardingConfig, } from 'sentry/components/onboarding/gettingStartedDoc/types'; import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {logsVerify} from 'sentry/gettingStartedDocs/dotnet/logs'; import {t, tct} from 'sentry/locale'; import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion'; @@ -35,6 +36,8 @@ public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompa // Set TracesSampleRate to 1.0 to capture 100% of transactions for tracing. // We recommend adjusting this value in production. options.TracesSampleRate = 1.0; + // Enable logs to be sent to Sentry + options.EnableLogs = true; // If you installed Sentry.Xamarin.Forms: options.AddXamarinFormsIntegration(); });`; @@ -52,6 +55,8 @@ public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsAppli // Set TracesSampleRate to 1.0 to capture 100% of transactions for tracing. // We recommend adjusting this value in production. options.TracesSampleRate = 1.0; + // Enable logs to be sent to Sentry + options.EnableLogs = true; options.AddXamarinFormsIntegration(); });`; @@ -68,6 +73,8 @@ sealed partial class App : Application // Set TracesSampleRate to 1.0 to capture 100% of transactions for tracing. // We recommend adjusting this value in production. options.TracesSampleRate = 1.0; + // Enable logs to be sent to Sentry + options.EnableLogs = true; options.AddXamarinFormsIntegration(); });`; @@ -181,7 +188,7 @@ export const onboarding: OnboardingConfig = { ], }, ], - verify: () => [ + verify: params => [ { type: StepType.VERIFY, content: [ @@ -229,6 +236,14 @@ export const onboarding: OnboardingConfig = { }, ], }, + ...(params.isLogsSelected + ? [ + { + title: t('Verify Logs'), + content: [logsVerify(params)], + }, + ] + : []), { title: t('Documentation'), content: [ diff --git a/static/app/gettingStartedDocs/dotnet/index.tsx b/static/app/gettingStartedDocs/dotnet/index.tsx index acb003a7796e8a..dcf7712ca3498b 100644 --- a/static/app/gettingStartedDocs/dotnet/index.tsx +++ b/static/app/gettingStartedDocs/dotnet/index.tsx @@ -2,6 +2,7 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {crashReport} from './crashReport'; import {feedback} from './feedback'; +import {logs} from './logs'; import {onboarding} from './onboarding'; import {profiling} from './profiling'; @@ -10,6 +11,7 @@ const docs: Docs = { feedbackOnboardingCrashApi: feedback, crashReportOnboarding: crashReport, profilingOnboarding: profiling, + logsOnboarding: logs, }; export default docs; diff --git a/static/app/gettingStartedDocs/dotnet/logs.spec.tsx b/static/app/gettingStartedDocs/dotnet/logs.spec.tsx new file mode 100644 index 00000000000000..2fde26c37b0129 --- /dev/null +++ b/static/app/gettingStartedDocs/dotnet/logs.spec.tsx @@ -0,0 +1,25 @@ +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('dotnet logs onboarding docs', () => { + it('renders logs onboarding docs correctly', async () => { + renderWithOnboardingLayout(docs, { + selectedProducts: [ProductSolution.LOGS], + }); + + // Verify logs configuration is shown + expect( + await screen.findByText(textWithMarkupMatcher(/options\.EnableLogs/)) + ).toBeInTheDocument(); + + // Verify logs verification code is shown + expect( + await screen.findByText(textWithMarkupMatcher(/SentrySdk\.Logger\.LogInfo/)) + ).toBeInTheDocument(); + }); +}); diff --git a/static/app/gettingStartedDocs/dotnet/logs.tsx b/static/app/gettingStartedDocs/dotnet/logs.tsx new file mode 100644 index 00000000000000..1d671ebce576aa --- /dev/null +++ b/static/app/gettingStartedDocs/dotnet/logs.tsx @@ -0,0 +1,105 @@ +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 {t, tct} from 'sentry/locale'; + +export const logsVerify = (params: DocsParams): ContentBlock => ({ + type: 'conditional', + condition: params.isLogsSelected, + content: [ + { + type: 'text', + text: t('Send a test log from your app to verify logs are arriving in Sentry.'), + }, + { + type: 'code', + language: 'csharp', + code: `SentrySdk.Logger.LogInfo("A simple log message"); +SentrySdk.Logger.LogError("A {0} log message", "formatted");`, + }, + ], +}); + +export const logs: OnboardingConfig = { + install: params => [ + { + type: StepType.INSTALL, + content: [ + { + type: 'text', + text: tct( + 'Logs in .NET are supported in Sentry .NET SDK version [code:5.14.0] and above.', + { + code: , + } + ), + }, + { + type: 'code', + tabs: [ + { + label: 'Package Manager', + language: 'shell', + code: getInstallSnippetPackageManager(params), + }, + { + label: '.NET Core CLI', + language: 'shell', + code: getInstallSnippetCoreCli(params), + }, + ], + }, + ], + }, + ], + configure: (params: DocsParams) => [ + { + type: StepType.CONFIGURE, + content: [ + { + type: 'text', + text: tct( + 'To enable logging, you need to initialize the SDK with the [code:EnableLogs] option set to [code:true].', + { + code: , + } + ), + }, + { + type: 'code', + language: 'csharp', + code: `SentrySdk.Init(options => +{ + options.Dsn = "${params.dsn.public}"; + // Enable logs to be sent to Sentry + options.EnableLogs = true; +});`, + }, + { + type: 'text', + text: tct( + 'For more detailed information on logging configuration, see the [link:logs documentation].', + { + link: , + } + ), + }, + ], + }, + ], + verify: (params: DocsParams) => [ + { + type: StepType.VERIFY, + description: t('Test that logs are working by sending some test logs:'), + content: [logsVerify(params)], + }, + ], +}; diff --git a/static/app/gettingStartedDocs/dotnet/onboarding.spec.tsx b/static/app/gettingStartedDocs/dotnet/onboarding.spec.tsx index 1afd2b2e9d6ad0..50151073b5fb3b 100644 --- a/static/app/gettingStartedDocs/dotnet/onboarding.spec.tsx +++ b/static/app/gettingStartedDocs/dotnet/onboarding.spec.tsx @@ -14,6 +14,7 @@ describe('dotnet onboarding docs', () => { version: '1.99.9', }, }, + selectedProducts: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS], }); // Renders main headings @@ -21,6 +22,7 @@ describe('dotnet onboarding docs', () => { expect(screen.getByRole('heading', {name: 'Configure SDK'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Verify'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Tracing'})).toBeInTheDocument(); + expect(screen.getByRole('heading', {name: 'Verify Logs'})).toBeInTheDocument(); expect(screen.getByRole('heading', {name: 'Samples'})).toBeInTheDocument(); // Renders SDK version from registry @@ -53,4 +55,14 @@ describe('dotnet onboarding docs', () => { await screen.findByText(textWithMarkupMatcher(/options.ProfilesSampleRate/)) ).toBeInTheDocument(); }); + + it('renders logs onboarding docs correctly', async () => { + renderWithOnboardingLayout(docs, { + selectedProducts: [ProductSolution.LOGS], + }); + + expect( + await screen.findByText(textWithMarkupMatcher(/options.EnableLogs/)) + ).toBeInTheDocument(); + }); }); diff --git a/static/app/gettingStartedDocs/dotnet/onboarding.tsx b/static/app/gettingStartedDocs/dotnet/onboarding.tsx index 5b66ae7c48029a..3fdbb19979857f 100644 --- a/static/app/gettingStartedDocs/dotnet/onboarding.tsx +++ b/static/app/gettingStartedDocs/dotnet/onboarding.tsx @@ -5,6 +5,7 @@ import type { OnboardingStep, } from 'sentry/components/onboarding/gettingStartedDoc/types'; import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {logsVerify} from 'sentry/gettingStartedDocs/dotnet/logs'; import {t, tct} from 'sentry/locale'; import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion'; @@ -14,14 +15,14 @@ const getInstallProfilingSnippetPackageManager = (params: DocsParams) => ` Install-Package Sentry.Profiling -Version ${getPackageVersion( params, 'sentry.dotnet.profiling', - '4.3.0' + '6.0.0' )}`; const getInstallProfilingSnippetCoreCli = (params: DocsParams) => ` dotnet add package Sentry.Profiling -v ${getPackageVersion( params, 'sentry.dotnet.profiling', - '4.3.0' + '6.0.0' )}`; enum DotNetPlatform { @@ -77,6 +78,12 @@ SentrySdk.Init(options => ));` }` : '' + }${ + params.isLogsSelected + ? ` + // Enable logs to be sent to Sentry + options.EnableLogs = true;` + : '' } });`; @@ -255,6 +262,14 @@ export const onboarding: OnboardingConfig = { }, ] satisfies OnboardingStep[]) : []), + ...(params.isLogsSelected + ? [ + { + title: t('Verify Logs'), + content: [logsVerify(params)], + }, + ] + : []), { title: t('Samples'), content: [ diff --git a/static/app/gettingStartedDocs/dotnet/profiling.tsx b/static/app/gettingStartedDocs/dotnet/profiling.tsx index 7a2b80e91c4d8c..c98e4a8cb0037f 100644 --- a/static/app/gettingStartedDocs/dotnet/profiling.tsx +++ b/static/app/gettingStartedDocs/dotnet/profiling.tsx @@ -14,14 +14,14 @@ const getInstallProfilingSnippetPackageManager = (params: DocsParams) => ` Install-Package Sentry.Profiling -Version ${getPackageVersion( params, 'sentry.dotnet.profiling', - '4.3.0' + '6.0.0' )}`; const getInstallProfilingSnippetCoreCli = (params: DocsParams) => ` dotnet add package Sentry.Profiling -v ${getPackageVersion( params, 'sentry.dotnet.profiling', - '4.3.0' + '6.0.0' )}`; const getProfilingConfigureSnippet = ( diff --git a/static/app/gettingStartedDocs/dotnet/utils.tsx b/static/app/gettingStartedDocs/dotnet/utils.tsx index a9505a129e29b4..1497d79f2265c6 100644 --- a/static/app/gettingStartedDocs/dotnet/utils.tsx +++ b/static/app/gettingStartedDocs/dotnet/utils.tsx @@ -2,15 +2,7 @@ import type {DocsParams} from 'sentry/components/onboarding/gettingStartedDoc/ty import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion'; export const getInstallSnippetPackageManager = (params: DocsParams) => ` -Install-Package Sentry -Version ${getPackageVersion( - params, - 'sentry.dotnet', - params.isProfilingSelected ? '4.3.0' : '3.34.0' -)}`; +Install-Package Sentry -Version ${getPackageVersion(params, 'sentry.dotnet', '6.0.0')}`; export const getInstallSnippetCoreCli = (params: DocsParams) => ` -dotnet add package Sentry -v ${getPackageVersion( - params, - 'sentry.dotnet', - params.isProfilingSelected ? '4.3.0' : '3.34.0' -)}`; +dotnet add package Sentry -v ${getPackageVersion(params, 'sentry.dotnet', '6.0.0')}`; diff --git a/static/app/gettingStartedDocs/godot/index.tsx b/static/app/gettingStartedDocs/godot/index.tsx index acd1e9e2193af3..cae1711f42e30b 100644 --- a/static/app/gettingStartedDocs/godot/index.tsx +++ b/static/app/gettingStartedDocs/godot/index.tsx @@ -1,8 +1,10 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {logs} from 'sentry/gettingStartedDocs/godot/logs'; import {onboarding} from 'sentry/gettingStartedDocs/godot/onboarding'; const docs: Docs = { onboarding, + logsOnboarding: logs, }; export default docs; diff --git a/static/app/gettingStartedDocs/godot/logs.tsx b/static/app/gettingStartedDocs/godot/logs.tsx new file mode 100644 index 00000000000000..d4d9d8c8ea3a9d --- /dev/null +++ b/static/app/gettingStartedDocs/godot/logs.tsx @@ -0,0 +1,94 @@ +import {ExternalLink} from 'sentry/components/core/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 logsVerify = (params: DocsParams): ContentBlock => ({ + type: 'conditional', + condition: params.isLogsSelected, + content: [ + { + type: 'text', + text: t( + "Once logging is enabled, you can send logs using the SentrySDK.logger API or Godot's built-in logging functions:" + ), + }, + { + type: 'code', + language: 'gdscript', + code: `# Use the logger API directly +SentrySDK.logger.info("Level loaded successfully") +SentrySDK.logger.warn("Item configuration not found") +SentrySDK.logger.error("Failed to save game state") + +# Or use Godot's built-in functions (automatically captured) +print("This info message will be sent to Sentry") +push_warning("This warning will be sent to Sentry") +push_error("This error will be sent to Sentry")`, + }, + { + type: 'text', + text: tct('Check out [link:the Logs documentation] to learn more.', { + link: , + }), + }, + ], +}); + +export const logs: OnboardingConfig = { + install: () => [ + { + type: StepType.INSTALL, + content: [ + { + type: 'text', + text: tct( + 'Logs for Godot Engine are supported in Sentry SDK version [code:1.1.0] and above.', + { + code: , + } + ), + }, + ], + }, + ], + configure: (params: DocsParams) => [ + { + type: StepType.CONFIGURE, + content: [ + { + type: 'text', + text: t( + 'To enable structured logs, navigate to Project Settings in Godot, then go to Sentry > Options and enable the Enable Logs option.' + ), + }, + { + type: 'text', + text: t( + 'Alternatively, you can configure logging programmatically when initializing the SDK:' + ), + }, + { + type: 'code', + language: 'gdscript', + code: `SentrySDK.init(func(options: SentryOptions) -> void: + options.dsn = "${params.dsn.public}" + + # Enable logs + options.enable_logs = true +)`, + }, + ], + }, + ], + verify: (params: DocsParams) => [ + { + type: StepType.VERIFY, + content: [logsVerify(params)], + }, + ], +}; diff --git a/static/app/gettingStartedDocs/godot/onboarding.tsx b/static/app/gettingStartedDocs/godot/onboarding.tsx index b374a608b8caaf..937dfa05726b0e 100644 --- a/static/app/gettingStartedDocs/godot/onboarding.tsx +++ b/static/app/gettingStartedDocs/godot/onboarding.tsx @@ -3,17 +3,20 @@ import {StoreCrashReportsConfig} from 'sentry/components/onboarding/gettingStart import type { DocsParams, OnboardingConfig, + OnboardingStep, } from 'sentry/components/onboarding/gettingStartedDoc/types'; import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {t, tct} from 'sentry/locale'; -const getVerifySnippet = () => ` -extends Node +import {logsVerify} from './logs'; + +const getVerifySnippet = () => { + return `extends Node func _ready(): SentrySDK.add_breadcrumb(SentryBreadcrumb.create("Just about to welcome the World.")) - SentrySDK.capture_message("Hello, World!") -`; + SentrySDK.capture_message("Hello, World!")`; +}; export const onboarding: OnboardingConfig = { install: () => [ @@ -42,7 +45,7 @@ export const onboarding: OnboardingConfig = { { type: 'text', text: tct( - 'Sentry can be configured in the Project Settings window or [link: programmatically]. To access project settings in Godot Engine, navigate to [code:Project > Project Settings > Sentry] section, and enter the DSN for the [code:Dsn] option.', + 'Sentry can be configured in the Project Settings window or [link:programmatically]. To access project settings in Godot Engine, navigate to [code:Project > Project Settings > Sentry] section, and enter the DSN for the [code:Dsn] option.', { code: , link: ( @@ -56,6 +59,19 @@ export const onboarding: OnboardingConfig = { language: 'url', code: params.dsn.public, }, + { + type: 'conditional', + condition: params.isLogsSelected, + content: [ + { + type: 'text', + text: tct( + 'To enable structured logs, go to [strong:Project Settings > Sentry > Options > Enable Logs].', + {strong: } + ), + }, + ], + }, ], }, ], @@ -90,6 +106,14 @@ export const onboarding: OnboardingConfig = { }, ], }, + ...(params.isLogsSelected + ? ([ + { + title: t('Logs'), + content: [logsVerify(params)], + }, + ] satisfies OnboardingStep[]) + : []), { title: t('Further Settings'), content: [ diff --git a/static/app/gettingStartedDocs/native/index.tsx b/static/app/gettingStartedDocs/native/index.tsx index 9b3b3c93f62de5..7ebe9ffdecf519 100644 --- a/static/app/gettingStartedDocs/native/index.tsx +++ b/static/app/gettingStartedDocs/native/index.tsx @@ -1,11 +1,13 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {CrashReportWebApiOnboarding} from 'sentry/components/onboarding/gettingStartedDoc/utils/feedbackOnboarding'; +import {logs} from './logs'; import {onboarding} from './onboarding'; const docs: Docs = { onboarding, crashReportOnboarding: CrashReportWebApiOnboarding, + logsOnboarding: logs, }; export default docs; diff --git a/static/app/gettingStartedDocs/native/logs.tsx b/static/app/gettingStartedDocs/native/logs.tsx new file mode 100644 index 00000000000000..0017f8f44d1e5f --- /dev/null +++ b/static/app/gettingStartedDocs/native/logs.tsx @@ -0,0 +1,89 @@ +import {ExternalLink} from 'sentry/components/core/link'; +import type { + ContentBlock, + DocsParams, + OnboardingConfig, +} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {tct} from 'sentry/locale'; + +export const logsVerify = (params: DocsParams): ContentBlock => ({ + type: 'conditional', + condition: params.isLogsSelected, + content: [ + { + type: 'text', + text: tct( + 'Once logging is enabled, you can send logs using the [code:sentry_log_X()] APIs:', + { + code: , + } + ), + }, + { + type: 'code', + language: 'c', + code: `sentry_log_info("A simple log message"); +sentry_log_error("A %s log message", "formatted");`, + }, + { + type: 'text', + text: tct( + 'Check out [link:the Logs documentation] to learn more about additional attributes and options.', + { + link: , + } + ), + }, + ], +}); + +export const logs: OnboardingConfig = { + install: () => [ + { + type: StepType.INSTALL, + content: [ + { + type: 'text', + text: tct( + 'Logs in Native are supported in Sentry Native SDK version [code:0.11.1] and above.', + { + code: , + } + ), + }, + ], + }, + ], + configure: (params: DocsParams) => [ + { + type: StepType.CONFIGURE, + content: [ + { + type: 'text', + text: tct( + 'To enable logging, you need to initialize the SDK with the [code:enable_logs] option set to [code:true].', + { + code: , + } + ), + }, + { + type: 'code', + language: 'c', + code: `sentry_options_t *options = sentry_options_new(); +sentry_options_set_dsn(options, "${params.dsn.public}"); +sentry_options_set_enable_logs(options, 1); +// set other options +sentry_init(options);`, + }, + ], + }, + ], + verify: (params: DocsParams) => [ + { + type: StepType.VERIFY, + content: [logsVerify(params)], + }, + ], +}; diff --git a/static/app/gettingStartedDocs/native/onboarding.spec.tsx b/static/app/gettingStartedDocs/native/onboarding.spec.tsx index cd9361eba8e1d6..c6fa11817f779c 100644 --- a/static/app/gettingStartedDocs/native/onboarding.spec.tsx +++ b/static/app/gettingStartedDocs/native/onboarding.spec.tsx @@ -1,10 +1,21 @@ +import {ProjectFixture} from 'sentry-fixture/project'; + import {renderWithOnboardingLayout} from 'sentry-test/onboarding/renderWithOnboardingLayout'; import {screen} from 'sentry-test/reactTestingLibrary'; import docs from '.'; +function renderMockRequests() { + MockApiClient.addMockResponse({ + url: '/projects/org-slug/project-slug/', + body: [ProjectFixture()], + }); +} + describe('getting started with native', () => { it('renders docs correctly', () => { + renderMockRequests(); + renderWithOnboardingLayout(docs); // Renders main headings diff --git a/static/app/gettingStartedDocs/native/onboarding.tsx b/static/app/gettingStartedDocs/native/onboarding.tsx index fcbef9ee1f1d25..5c17f957322e44 100644 --- a/static/app/gettingStartedDocs/native/onboarding.tsx +++ b/static/app/gettingStartedDocs/native/onboarding.tsx @@ -1,4 +1,5 @@ import {ExternalLink} from 'sentry/components/core/link'; +import {StoreCrashReportsConfig} from 'sentry/components/onboarding/gettingStartedDoc/storeCrashReportsConfig'; import type { DocsParams, OnboardingConfig, @@ -6,6 +7,7 @@ import type { } from 'sentry/components/onboarding/gettingStartedDoc/types'; import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {getConsoleExtensions} from 'sentry/components/onboarding/gettingStartedDoc/utils/consoleExtensions'; +import {logsVerify} from 'sentry/gettingStartedDocs/native/logs'; import {getVerifySnippet} from 'sentry/gettingStartedDocs/native/utils'; import {t, tct} from 'sentry/locale'; @@ -16,10 +18,15 @@ int main(void) { sentry_options_t *options = sentry_options_new(); sentry_options_set_dsn(options, "${params.dsn.public}"); // This is also the default-path. For further information and recommendations: - // https://docs.sentry.io/platforms/native/configuration/options/#database-path + // https://docs.sentry.io/platforms/native/configuration/options/#database_path sentry_options_set_database_path(options, ".sentry-native"); sentry_options_set_release(options, "my-project-name@2.3.12"); - sentry_options_set_debug(options, 1); + sentry_options_set_debug(options, 1);${ + params.isLogsSelected + ? ` + sentry_options_set_enable_logs(options, 1);` + : '' + } sentry_init(options); /* ... */ @@ -106,6 +113,28 @@ export const onboarding: OnboardingConfig = { }, ], }, + ...(params.isLogsSelected + ? ([ + { + title: t('Logs'), + content: [logsVerify(params)], + }, + ] satisfies OnboardingStep[]) + : []), ...([getConsoleExtensions(params)].filter(Boolean) as OnboardingStep[]), + { + title: t('Further Settings'), + content: [ + { + type: 'custom', + content: ( + + ), + }, + ], + }, ], }; diff --git a/static/app/gettingStartedDocs/php-symfony/index.tsx b/static/app/gettingStartedDocs/php-symfony/index.tsx index 550e19e9a56d8c..1c6afffac14cfd 100644 --- a/static/app/gettingStartedDocs/php-symfony/index.tsx +++ b/static/app/gettingStartedDocs/php-symfony/index.tsx @@ -5,6 +5,7 @@ import { } from 'sentry/gettingStartedDocs/javascript/jsLoader'; import {crashReport} from './crashReport'; +import {logs} from './logs'; import {metrics} from './metrics'; import {onboarding} from './onboarding'; import {profiling} from './profiling'; @@ -15,6 +16,7 @@ const docs: Docs = { profilingOnboarding: profiling, crashReportOnboarding: crashReport, feedbackOnboardingJsLoader, + logsOnboarding: logs, metricsOnboarding: metrics, }; diff --git a/static/app/gettingStartedDocs/php-symfony/logs.tsx b/static/app/gettingStartedDocs/php-symfony/logs.tsx new file mode 100644 index 00000000000000..fd5c7feb4aed94 --- /dev/null +++ b/static/app/gettingStartedDocs/php-symfony/logs.tsx @@ -0,0 +1,130 @@ +import {ExternalLink} from 'sentry/components/core/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 logsVerify = (params: DocsParams): ContentBlock => ({ + type: 'conditional', + condition: params.isLogsSelected, + content: [ + { + type: 'text', + text: t( + 'Once configured, you can send logs using the standard PSR-3 logger interface:' + ), + }, + { + type: 'code', + language: 'php', + code: `$this->logger->info("This is an info message"); +$this->logger->warning('User {id} failed to login.', ['id' => $user->id]); +$this->logger->error("This is an error message");`, + }, + { + type: 'text', + text: tct( + 'Check out [link:the Logs documentation] to learn more about Monolog integration.', + { + link: ( + + ), + } + ), + }, + ], +}); + +export const logs: OnboardingConfig = { + install: () => [ + { + type: StepType.INSTALL, + content: [ + { + type: 'text', + text: tct( + 'Logs for Symfony are supported in Sentry Symfony SDK version [code:5.4.0] and above.', + { + code: , + } + ), + }, + { + type: 'text', + text: t('Make sure you have the latest version of the Sentry Symfony bundle:'), + }, + { + type: 'code', + language: 'bash', + code: 'composer require sentry/sentry-symfony', + }, + ], + }, + ], + configure: (params: DocsParams) => [ + { + type: StepType.CONFIGURE, + content: [ + { + type: 'text', + text: t( + 'To configure Sentry logging, add the Monolog handler to your configuration:' + ), + }, + { + type: 'code', + language: 'yaml', + code: `# config/packages/monolog.yaml +monolog: + handlers: + sentry_logs: + type: service + id: Sentry\\SentryBundle\\Monolog\\LogsHandler`, + }, + { + type: 'text', + text: t('Configure the service and choose a minimum log level:'), + }, + { + type: 'code', + language: 'yaml', + code: `# config/packages/sentry.yaml +services: + Sentry\\SentryBundle\\Monolog\\LogsHandler: + arguments: + - !php/const Monolog\\Logger::INFO`, + }, + { + type: 'text', + text: t('Enable the logs option:'), + }, + { + type: 'code', + language: 'yaml', + code: `# config/packages/sentry.yaml +sentry: + dsn: '${params.dsn.public}' + options: + enable_logs: true`, + }, + { + type: 'text', + text: tct('For more details, see the [link:Symfony Logs documentation].', { + link: ( + + ), + }), + }, + ], + }, + ], + verify: (params: DocsParams) => [ + { + type: StepType.VERIFY, + content: [logsVerify(params)], + }, + ], +}; diff --git a/static/app/gettingStartedDocs/php-symfony/onboarding.tsx b/static/app/gettingStartedDocs/php-symfony/onboarding.tsx index bf3b226f70bd63..89272cd77bbdbb 100644 --- a/static/app/gettingStartedDocs/php-symfony/onboarding.tsx +++ b/static/app/gettingStartedDocs/php-symfony/onboarding.tsx @@ -2,10 +2,12 @@ import {ExternalLink} from 'sentry/components/core/link'; import type { DocsParams, OnboardingConfig, + OnboardingStep, } from 'sentry/components/onboarding/gettingStartedDoc/types'; import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; -import {tct} from 'sentry/locale'; +import {t, tct} from 'sentry/locale'; +import {logsVerify} from './logs'; import {getConfigureSnippet, getExcimerInstallSteps} from './utils'; export const onboarding: OnboardingConfig = { @@ -66,7 +68,7 @@ SENTRY_DSN="${params.dsn.public}" ], }, ], - verify: () => [ + verify: (params: DocsParams) => [ { type: StepType.VERIFY, content: [ @@ -116,6 +118,14 @@ SENTRY_DSN="${params.dsn.public}" }, ], }, + ...(params.isLogsSelected + ? ([ + { + title: t('Logs'), + content: [logsVerify(params)], + }, + ] satisfies OnboardingStep[]) + : []), ], nextSteps: () => [], }; diff --git a/static/app/gettingStartedDocs/php-symfony/utils.tsx b/static/app/gettingStartedDocs/php-symfony/utils.tsx index 5c1fa9c6a80644..9adde5433c6646 100644 --- a/static/app/gettingStartedDocs/php-symfony/utils.tsx +++ b/static/app/gettingStartedDocs/php-symfony/utils.tsx @@ -35,7 +35,11 @@ export const getExcimerInstallSteps = (params: DocsParams): ContentBlock[] => { }; export const getConfigureSnippet = (params: DocsParams): ContentBlock[] => { - if (!params.isPerformanceSelected && !params.isProfilingSelected) { + if ( + !params.isPerformanceSelected && + !params.isProfilingSelected && + !params.isLogsSelected + ) { return []; } @@ -53,7 +57,9 @@ export const getConfigureSnippet = (params: DocsParams): ContentBlock[] => { code: `when@prod: sentry: dsn: '%env(SENTRY_DSN)%'${ - params.isPerformanceSelected || params.isProfilingSelected + params.isPerformanceSelected || + params.isProfilingSelected || + params.isLogsSelected ? ` options:` : '' @@ -69,6 +75,12 @@ export const getConfigureSnippet = (params: DocsParams): ContentBlock[] => { # Set a sampling rate for profiling - this is relative to traces_sample_rate profiles_sample_rate: 1.0` : '' + }${ + params.isLogsSelected + ? ` + # Enable logs to be sent to Sentry + enable_logs: true` + : '' }`, }, ]; diff --git a/static/app/gettingStartedDocs/python/logs.spec.tsx b/static/app/gettingStartedDocs/python/logs.spec.tsx index ad80efc74ed7f5..883245a9d09460 100644 --- a/static/app/gettingStartedDocs/python/logs.spec.tsx +++ b/static/app/gettingStartedDocs/python/logs.spec.tsx @@ -1,47 +1,26 @@ -// Only import and test functions that don't have circular dependencies -const {logs} = jest.requireActual('sentry/gettingStartedDocs/python/logs'); +import {renderWithOnboardingLayout} from 'sentry-test/onboarding/renderWithOnboardingLayout'; +import {screen} from 'sentry-test/reactTestingLibrary'; +import {textWithMarkupMatcher} from 'sentry-test/utils'; -describe('logs', () => { - const mockParams = { - dsn: { - public: 'https://test@example.com/123', - }, - }; +import {ProductSolution} from 'sentry/components/onboarding/gettingStartedDoc/types'; - it('generates logs onboarding config with default parameters', () => { - const result = logs(); +import docs from '.'; - // Test install step - const installSteps = result.install(); - expect(installSteps).toHaveLength(1); - 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('enable_logs=True'); - expect(configureSteps[0].content[1].code).toContain(mockParams.dsn.public); - - // Test verify step - const verifySteps = result.verify({isLogsSelected: true}); - 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.logger.info'); - expect(conditionalContent[3].code).toContain('import logging'); - }); - - it('generates logs onboarding config with custom parameters', () => { - const result = logs({ - packageName: 'custom-sentry-sdk', - minimumVersion: '3.0.0', +describe('python logs onboarding docs', () => { + it('renders logs onboarding docs correctly', () => { + renderWithOnboardingLayout(docs, { + selectedProducts: [ProductSolution.LOGS], }); - const installSteps = result.install(); - expect(installSteps[0].content).toHaveLength(2); + // Verify logs configuration is shown + expect( + screen.getByText(textWithMarkupMatcher(/enable_logs=True/)) + ).toBeInTheDocument(); + + // Verify logs verification code is shown + expect( + screen.getByText(textWithMarkupMatcher(/sentry_sdk\.logger\.info/)) + ).toBeInTheDocument(); + expect(screen.getByText(textWithMarkupMatcher(/import logging/))).toBeInTheDocument(); }); }); diff --git a/static/app/gettingStartedDocs/unity/index.tsx b/static/app/gettingStartedDocs/unity/index.tsx index 6c1e6b06917266..2d9adc901245c9 100644 --- a/static/app/gettingStartedDocs/unity/index.tsx +++ b/static/app/gettingStartedDocs/unity/index.tsx @@ -1,12 +1,14 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {crashReport} from './crashReport'; +import {logs} from './logs'; import {onboarding} from './onboarding'; const docs: Docs = { onboarding, feedbackOnboardingCrashApi: crashReport, crashReportOnboarding: crashReport, + logsOnboarding: logs, }; export default docs; diff --git a/static/app/gettingStartedDocs/unity/logs.tsx b/static/app/gettingStartedDocs/unity/logs.tsx new file mode 100644 index 00000000000000..5106b448e74fa8 --- /dev/null +++ b/static/app/gettingStartedDocs/unity/logs.tsx @@ -0,0 +1,102 @@ +import {ExternalLink} from 'sentry/components/core/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 logsVerify = (params: DocsParams): ContentBlock => ({ + type: 'conditional', + condition: params.isLogsSelected, + content: [ + { + type: 'text', + text: t( + 'Once logging is enabled, you can send logs using the Debug.Log API or directly via the SDK:' + ), + }, + { + type: 'code', + language: 'csharp', + code: `using Sentry; +using UnityEngine; + +// Unity's Debug.LogWarning (and higher severity levels) will automatically be captured +Debug.LogWarning("This warning will be sent to Sentry"); + +// Or use the SDK directly +SentrySdk.Logger.LogInfo("A simple log message"); +SentrySdk.Logger.LogError("A {0} log message", "formatted");`, + }, + { + type: 'text', + text: tct('Check out [link:the Logs documentation] to learn more.', { + link: , + }), + }, + ], +}); + +export const logs: OnboardingConfig = { + install: () => [ + { + type: StepType.INSTALL, + content: [ + { + type: 'text', + text: tct( + 'Logs for Unity are supported in Sentry SDK version [code:4.0.0] and above.', + { + code: , + } + ), + }, + ], + }, + ], + configure: (params: DocsParams) => [ + { + type: StepType.CONFIGURE, + content: [ + { + type: 'text', + text: t( + 'To enable logging in your Unity game, you need to configure the Sentry SDK with structured logging enabled.' + ), + }, + { + type: 'text', + text: tct( + 'Open your project settings: [strong:Tools > Sentry > Logging] and check the [strong:Enable Structured Logging] option.', + { + strong: , + } + ), + }, + { + type: 'text', + text: t('Alternatively, you can enable logging programmatically:'), + }, + { + type: 'code', + language: 'csharp', + code: `SentrySdk.Init(options => +{ + options.Dsn = "${params.dsn.public}"; + + // Enable logs to be sent to Sentry + options.EnableLogs = true; +});`, + }, + ], + }, + ], + verify: (params: DocsParams) => [ + { + type: StepType.VERIFY, + content: [logsVerify(params)], + }, + ], +}; diff --git a/static/app/gettingStartedDocs/unity/onboarding.tsx b/static/app/gettingStartedDocs/unity/onboarding.tsx index ad557890dc7ce8..75bb7a5b40c29f 100644 --- a/static/app/gettingStartedDocs/unity/onboarding.tsx +++ b/static/app/gettingStartedDocs/unity/onboarding.tsx @@ -1,6 +1,7 @@ import {ExternalLink} from 'sentry/components/core/link'; import {StoreCrashReportsConfig} from 'sentry/components/onboarding/gettingStartedDoc/storeCrashReportsConfig'; import type { + DocsParams, OnboardingConfig, OnboardingStep, } from 'sentry/components/onboarding/gettingStartedDoc/types'; @@ -8,6 +9,8 @@ import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {getConsoleExtensions} from 'sentry/components/onboarding/gettingStartedDoc/utils/consoleExtensions'; import {t, tct} from 'sentry/locale'; +import {logsVerify} from './logs'; + const getVerifySnippet = () => ` using Sentry; // On the top of the script @@ -57,6 +60,19 @@ export const onboarding: OnboardingConfig = { type: 'text', text: t("And that's it! Now Sentry can capture errors automatically."), }, + { + type: 'conditional', + condition: params.isLogsSelected, + content: [ + { + type: 'text', + text: tct( + 'To enable structured logging, check the [code:Enable Logs] option in the Sentry configuration window.', + {code: } + ), + }, + ], + }, { type: 'text', text: tct( @@ -71,7 +87,7 @@ export const onboarding: OnboardingConfig = { ], }, ], - verify: params => [ + verify: (params: DocsParams) => [ { type: StepType.VERIFY, content: [ @@ -88,6 +104,14 @@ export const onboarding: OnboardingConfig = { }, ], }, + ...(params.isLogsSelected + ? ([ + { + title: t('Logs'), + content: [logsVerify(params)], + }, + ] satisfies OnboardingStep[]) + : []), { title: t('Troubleshooting'), content: [ diff --git a/static/app/gettingStartedDocs/unreal/index.tsx b/static/app/gettingStartedDocs/unreal/index.tsx index 6c1e6b06917266..2d9adc901245c9 100644 --- a/static/app/gettingStartedDocs/unreal/index.tsx +++ b/static/app/gettingStartedDocs/unreal/index.tsx @@ -1,12 +1,14 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {crashReport} from './crashReport'; +import {logs} from './logs'; import {onboarding} from './onboarding'; const docs: Docs = { onboarding, feedbackOnboardingCrashApi: crashReport, crashReportOnboarding: crashReport, + logsOnboarding: logs, }; export default docs; diff --git a/static/app/gettingStartedDocs/unreal/logs.tsx b/static/app/gettingStartedDocs/unreal/logs.tsx new file mode 100644 index 00000000000000..1c0269cf22229e --- /dev/null +++ b/static/app/gettingStartedDocs/unreal/logs.tsx @@ -0,0 +1,104 @@ +import {ExternalLink} from 'sentry/components/core/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 logsVerify = (params: DocsParams): ContentBlock => ({ + type: 'conditional', + condition: params.isLogsSelected, + content: [ + { + type: 'text', + text: t('Send a test log from your app to verify logs are arriving in Sentry.'), + }, + { + type: 'code', + language: 'cpp', + code: `USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem(); + +// Send logs at different severity levels +SentrySubsystem->LogInfo(TEXT("Test log message"), TEXT("Test")); +SentrySubsystem->LogWarning(TEXT("Warning message"), TEXT("Test")); +SentrySubsystem->LogError(TEXT("Error message"), TEXT("Test"));`, + }, + { + type: 'text', + text: tct( + 'You can also automatically capture Unreal Engine [code:UE_LOG] calls. Check out [link:the Logs documentation] to learn more.', + { + code: , + link: , + } + ), + }, + ], +}); + +export const logs: OnboardingConfig = { + install: () => [ + { + type: StepType.INSTALL, + content: [ + { + type: 'text', + text: tct( + 'Logs for Unreal Engine are supported in Sentry Unreal Engine SDK version [code:1.2.0] and above.', + { + code: , + } + ), + }, + ], + }, + ], + configure: (params: DocsParams) => [ + { + type: StepType.CONFIGURE, + content: [ + { + type: 'text', + text: t( + 'To enable logging in your Unreal Engine project, you need to configure the Sentry SDK with structured logging enabled.' + ), + }, + { + type: 'text', + text: tct( + 'Open your project settings: [strong:Project Settings > Plugins > Sentry] and check the [strong:Enable Structured Logging] option.', + { + strong: , + } + ), + }, + { + type: 'text', + text: t('Alternatively, you can enable logging programmatically:'), + }, + { + type: 'code', + language: 'cpp', + code: `#include "SentrySubsystem.h" + +USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem(); + +// Create settings with logging enabled +SentrySubsystem->InitializeWithSettings(FConfigureSettingsNativeDelegate::CreateLambda([=](USentrySettings* Settings) +{ + Settings->Dsn = TEXT("${params.dsn.public}"); + Settings->EnableStructuredLogging = true; +}));`, + }, + ], + }, + ], + verify: (params: DocsParams) => [ + { + type: StepType.VERIFY, + content: [logsVerify(params)], + }, + ], +}; diff --git a/static/app/gettingStartedDocs/unreal/onboarding.tsx b/static/app/gettingStartedDocs/unreal/onboarding.tsx index cdfd3b21c1cf0f..def4fbba0d01e0 100644 --- a/static/app/gettingStartedDocs/unreal/onboarding.tsx +++ b/static/app/gettingStartedDocs/unreal/onboarding.tsx @@ -9,22 +9,31 @@ import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; import {getConsoleExtensions} from 'sentry/components/onboarding/gettingStartedDoc/utils/consoleExtensions'; import {t, tct} from 'sentry/locale'; -type Params = DocsParams; +import {logsVerify} from './logs'; -const getVerifySnippet = () => ` -#include "SentrySubsystem.h" +const getVerifySnippet = (params: DocsParams) => { + const logsCode = params.isLogsSelected + ? ` + + // Send logs at different severity levels + SentrySubsystem->LogInfo(TEXT("A simple log message"), TEXT("GameFlow"));` + : ''; + + return `#include "SentrySubsystem.h" void Verify() { // Obtain reference to GameInstance UGameInstance* GameInstance = ...; - // Capture message USentrySubsystem* SentrySubsystem = GameInstance->GetSubsystem(); - SentrySubsystem->CaptureMessage(TEXT("Capture message")); + + // Capture message + SentrySubsystem->CaptureMessage(TEXT("Capture message"));${logsCode} }`; +}; -const getSettingsConfigureSnippet = (params: Params) => ` +const getSettingsConfigureSnippet = (params: DocsParams) => ` #include "SentrySubsystem.h" FConfigureSettingsDelegate OnConfigureSettings; @@ -39,7 +48,14 @@ void UMyGameInstance::ConfigureSentrySettings(USentrySettings* Settings) Settings->SendDefaultPii = true; // If your game/app doesn't have sensitive data, you can get screenshots on error events automatically - Settings->AttachScreenshot = true; + Settings->AttachScreenshot = true;${ + params.isLogsSelected + ? ` + + // Enable structured logging + Settings->EnableStructuredLogging = true;` + : '' + } } ... @@ -47,7 +63,7 @@ void UMyGameInstance::ConfigureSentrySettings(USentrySettings* Settings) USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem(); SentrySubsystem->InitializeWithSettings(OnConfigureSettings);`; -const getCrashReporterConfigSnippet = (params: Params) => ` +const getCrashReporterConfigSnippet = (params: DocsParams) => ` [CrashReportClient] CrashReportClientVersion=1.0 DataRouterUrl="${params.dsn.unreal}"`; @@ -110,6 +126,19 @@ export const onboarding: OnboardingConfig = { language: 'url', code: params.dsn.public, }, + { + type: 'conditional', + condition: params.isLogsSelected, + content: [ + { + type: 'text', + text: tct( + 'To enable structured logging, check the [strong:Enable Structured Logging] option in the Sentry configuration window.', + {strong: } + ), + }, + ], + }, { type: 'text', text: tct( @@ -138,10 +167,18 @@ export const onboarding: OnboardingConfig = { { type: 'code', language: 'cpp', - code: getVerifySnippet(), + code: getVerifySnippet(params), }, ], }, + ...(params.isLogsSelected + ? ([ + { + title: t('Logs'), + content: [logsVerify(params)], + }, + ] satisfies OnboardingStep[]) + : []), { title: t('Crash Reporter Client'), content: [