diff --git a/static/app/components/onboarding/productSelection.tsx b/static/app/components/onboarding/productSelection.tsx index db880858188804..393f05616baaf8 100644 --- a/static/app/components/onboarding/productSelection.tsx +++ b/static/app/components/onboarding/productSelection.tsx @@ -92,7 +92,11 @@ 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: [ + ProductSolution.PERFORMANCE_MONITORING, + ProductSolution.PROFILING, + ProductSolution.LOGS, + ], 'dotnet-aspnet': [ProductSolution.PERFORMANCE_MONITORING], 'dotnet-aspnetcore': [ProductSolution.PERFORMANCE_MONITORING], 'dotnet-awslambda': [ProductSolution.PERFORMANCE_MONITORING], @@ -180,6 +184,7 @@ export const platformProductAvailability = { ProductSolution.LOGS, ProductSolution.METRICS, ], + native: [ProductSolution.LOGS], node: [ ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING, @@ -270,6 +275,7 @@ export const platformProductAvailability = { 'php-symfony': [ ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING, + ProductSolution.LOGS, ProductSolution.METRICS, ], python: [ @@ -395,6 +401,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 8d3d3262561c19..d27a14bfde0356 100644 --- a/static/app/data/platformCategories.tsx +++ b/static/app/data/platformCategories.tsx @@ -304,7 +304,10 @@ export const withLoggingOnboarding: Set = new Set([ 'apple-ios', 'apple-macos', 'bun', + 'cocoa-objc', + 'cocoa-swift', 'dart', + 'dotnet', 'flutter', 'go', 'go-echo', @@ -336,6 +339,7 @@ export const withLoggingOnboarding: Set = new Set([ 'javascript-sveltekit', 'javascript-tanstackstart-react', 'javascript-vue', + 'native', 'node', 'node-azurefunctions', 'node-connect', @@ -350,6 +354,7 @@ export const withLoggingOnboarding: Set = new Set([ 'node-nestjs', 'php', 'php-laravel', + 'php-symfony', 'python', 'python-aiohttp', 'python-asgi', @@ -376,6 +381,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/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.tsx b/static/app/gettingStartedDocs/dotnet/logs.tsx new file mode 100644 index 00000000000000..c6a1e691ff8d47 --- /dev/null +++ b/static/app/gettingStartedDocs/dotnet/logs.tsx @@ -0,0 +1,88 @@ +import {ExternalLink} from 'sentry/components/core/link'; +import type { + DocsParams, + OnboardingConfig, +} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {t, tct} from 'sentry/locale'; + +export const logs: OnboardingConfig = { + install: () => [ + { + 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: , + } + ), + }, + ], + }, + ], + 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; +});`, + }, + ], + }, + ], + verify: () => [ + { + type: StepType.VERIFY, + content: [ + { + type: 'text', + text: t( + 'Once the feature is enabled on the SDK and the SDK is initialized, you can send logs using the SentrySdk.Logger APIs.' + ), + }, + { + type: 'text', + text: t( + 'The SentrySdk.Logger instance exposes six methods that you can use to log messages at different log levels: Trace, Debug, Info, Warning, Error, and Fatal.' + ), + }, + { + type: 'code', + language: 'csharp', + code: `SentrySdk.Logger.LogInfo("A simple log message"); +SentrySdk.Logger.LogError("A {0} log message", "formatted");`, + }, + { + type: 'text', + text: tct( + 'You can also attach custom attributes via a delegate. For more information, see the [link:Integrations documentation].', + { + link: ( + + ), + } + ), + }, + ], + }, + ], +}; diff --git a/static/app/gettingStartedDocs/dotnet/onboarding.tsx b/static/app/gettingStartedDocs/dotnet/onboarding.tsx index 5b66ae7c48029a..07b03580783e82 100644 --- a/static/app/gettingStartedDocs/dotnet/onboarding.tsx +++ b/static/app/gettingStartedDocs/dotnet/onboarding.tsx @@ -77,6 +77,13 @@ SentrySdk.Init(options => ));` }` : '' + }${ + params.isLogsSelected + ? ` + + // Enable logs to be sent to Sentry + options.EnableLogs = true;` + : '' } });`; @@ -255,6 +262,38 @@ export const onboarding: OnboardingConfig = { }, ] satisfies OnboardingStep[]) : []), + ...(params.isLogsSelected + ? ([ + { + title: t('Logs'), + content: [ + { + type: 'text', + text: t( + 'Once configured, you can send logs using the SentrySdk.Logger APIs:' + ), + }, + { + type: 'code', + language: 'csharp', + code: `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 about custom attributes and integrations.', + { + link: ( + + ), + } + ), + }, + ], + }, + ] satisfies OnboardingStep[]) + : []), { title: t('Samples'), 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..2d2f10cdd7ac29 --- /dev/null +++ b/static/app/gettingStartedDocs/native/logs.tsx @@ -0,0 +1,84 @@ +import {ExternalLink} from 'sentry/components/core/link'; +import type { + DocsParams, + OnboardingConfig, +} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {tct} from 'sentry/locale'; + +export const logs: OnboardingConfig = { + install: () => [ + { + type: StepType.INSTALL, + content: [ + { + type: 'text', + text: tct( + 'Logs in Native are supported in Sentry Native SDK version [link:0.11.1] and above.', + { + link: ( + + ), + } + ), + }, + ], + }, + ], + 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: () => [ + { + type: StepType.VERIFY, + content: [ + { + type: 'text', + text: tct( + 'Once the feature is enabled on the SDK and the SDK is initialized, you can send logs using the [code:sentry_log_X()] APIs.', + { + code: , + } + ), + }, + { + type: 'text', + text: tct( + 'The API exposes six methods that you can use to log messages at different log levels: [code:trace], [code:debug], [code:info], [code:warn], [code:error], and [code:fatal].', + { + code: , + } + ), + }, + { + type: 'code', + language: 'c', + code: `sentry_log_info("A simple log message"); +sentry_log_error("A %s log message", "formatted");`, + }, + ], + }, + ], +}; 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..fbf24d95088ee8 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, @@ -16,10 +17,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 +112,52 @@ export const onboarding: OnboardingConfig = { }, ], }, + ...(params.isLogsSelected + ? ([ + { + title: t('Logs'), + content: [ + { + type: 'text', + text: t( + 'Once logging is enabled, you can send logs using the sentry_log_X() APIs:' + ), + }, + { + 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: ( + + ), + } + ), + }, + ], + }, + ] 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..952ac2d0e84f15 --- /dev/null +++ b/static/app/gettingStartedDocs/php-symfony/logs.tsx @@ -0,0 +1,130 @@ +import {ExternalLink} from 'sentry/components/core/link'; +import type { + DocsParams, + OnboardingConfig, +} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {t, tct} from 'sentry/locale'; + +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: () => [ + { + type: StepType.VERIFY, + content: [ + { + type: 'text', + text: tct( + 'Once you have configured the Sentry log handler, you can use your regular [code:LoggerInterface]. It will send logs to Sentry:', + { + code: , + } + ), + }, + { + 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: t( + 'You can pass additional attributes directly to the logging functions. These properties will be sent to Sentry, and can be searched from within the Logs UI:' + ), + }, + { + type: 'code', + language: 'php', + code: `$this->logger->error('Something went wrong', [ + 'user_id' => $userId, + 'action' => 'update_profile', + 'additional_data' => $data, +]);`, + }, + ], + }, + ], +}; diff --git a/static/app/gettingStartedDocs/php-symfony/onboarding.tsx b/static/app/gettingStartedDocs/php-symfony/onboarding.tsx index bf3b226f70bd63..f4c0bc3cfd8603 100644 --- a/static/app/gettingStartedDocs/php-symfony/onboarding.tsx +++ b/static/app/gettingStartedDocs/php-symfony/onboarding.tsx @@ -2,9 +2,10 @@ 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 {getConfigureSnippet, getExcimerInstallSteps} from './utils'; @@ -66,7 +67,7 @@ SENTRY_DSN="${params.dsn.public}" ], }, ], - verify: () => [ + verify: (params: DocsParams) => [ { type: StepType.VERIFY, content: [ @@ -116,6 +117,50 @@ SENTRY_DSN="${params.dsn.public}" }, ], }, + ...(params.isLogsSelected + ? ([ + { + title: t('Logs'), + content: [ + { + type: 'text', + text: t( + 'Once configured, you can send logs using the standard PSR-3 logger interface:' + ), + }, + { + type: 'code', + language: 'php', + code: `use Psr\\Log\\LoggerInterface; + +class SomeService +{ + public function __construct( + private LoggerInterface $logger + ) {} + + public function someMethod(): void + { + $this->logger->info('A test log message'); + $this->logger->error('An error log message', ['context' => 'value']); + } +}`, + }, + { + type: 'text', + text: tct( + 'Check out [link:the Logs documentation] to learn more about Monolog integration.', + { + link: ( + + ), + } + ), + }, + ], + }, + ] 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/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..306f53b1aac46e --- /dev/null +++ b/static/app/gettingStartedDocs/unity/logs.tsx @@ -0,0 +1,127 @@ +import {ExternalLink} from 'sentry/components/core/link'; +import type { + DocsParams, + OnboardingConfig, +} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {t, tct} from 'sentry/locale'; + +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: () => [ + { + type: StepType.VERIFY, + content: [ + { + type: 'text', + text: tct( + 'Once the feature is enabled and the SDK is initialized, you can send logs using the [code:SentrySdk.Logger] API:', + { + code: , + } + ), + }, + { + type: 'code', + language: 'csharp', + code: `SentrySdk.Logger.LogInfo("A simple debug log message"); +SentrySdk.Logger.LogError("A {0} log message", "formatted");`, + }, + { + type: 'text', + text: tct( + "You can also use Unity's standard Debug logging. By default, [code:Debug.LogWarning] and above are automatically captured. [code:Debug.Log] calls are not sent unless you set [code:options.CaptureStructuredLogsForLogType[LogType.Log] = true].", + { + code: , + } + ), + }, + { + type: 'code', + language: 'csharp', + code: `// Debug.LogWarning and above are captured by default +Debug.LogWarning("Low memory warning."); +Debug.LogError("Failed to save game data."); + +// Debug.Log requires explicit opt-in via CaptureStructuredLogsForLogType[LogType.Log] = true +Debug.Log("Player position updated.");`, + }, + { + type: 'text', + text: t( + 'You can pass additional attributes directly to the logging functions. These properties will be sent to Sentry, and can be searched from within the Logs UI:' + ), + }, + { + type: 'code', + language: 'csharp', + code: `SentrySdk.Logger.LogWarning(static log => +{ + log.SetAttribute("my.attribute", "value"); +}, "A log message with additional attributes.");`, + }, + { + type: 'text', + text: tct( + 'For more configuration options, see the [link:Unity Logs documentation].', + { + link: , + } + ), + }, + ], + }, + ], +}; diff --git a/static/app/gettingStartedDocs/unity/onboarding.tsx b/static/app/gettingStartedDocs/unity/onboarding.tsx index ad557890dc7ce8..4e520ed1bc72a6 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'; @@ -57,6 +58,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 +85,7 @@ export const onboarding: OnboardingConfig = { ], }, ], - verify: params => [ + verify: (params: DocsParams) => [ { type: StepType.VERIFY, content: [ @@ -88,6 +102,42 @@ export const onboarding: OnboardingConfig = { }, ], }, + ...(params.isLogsSelected + ? ([ + { + title: t('Logs'), + 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.Warning (and higher severity levels) will automatically be captured +Debug.Warning("This warning will be sent to Sentry"); + +// Or use the SDK directly +SentrySdk.Logger.LogInfo("A simple log message"); +SentrySdk.Logger.LogError("An error log message");`, + }, + { + type: 'text', + text: tct('Check out [link:the Logs documentation] to learn more.', { + link: ( + + ), + }), + }, + ], + }, + ] 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..f70af8755dff67 --- /dev/null +++ b/static/app/gettingStartedDocs/unreal/logs.tsx @@ -0,0 +1,100 @@ +import {ExternalLink} from 'sentry/components/core/link'; +import type { + DocsParams, + OnboardingConfig, +} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types'; +import {t, tct} from 'sentry/locale'; + +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: () => [ + { + type: StepType.VERIFY, + content: [ + { + type: 'text', + text: t( + 'Once structured logging is enabled, you can send logs using the AddLog method on the Sentry subsystem.' + ), + }, + { + type: 'code', + language: 'cpp', + code: `USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem(); + +// Send logs at different severity levels +SentrySubsystem->AddLog(TEXT("A simple log message"), ESentryLevel::Info, TEXT("GameFlow")); +SentrySubsystem->AddLog(TEXT("Failed to save game data"), ESentryLevel::Error, TEXT("SaveSystem"));`, + }, + { + type: 'text', + text: tct( + 'You can also automatically capture Unreal Engine [code:UE_LOG] calls. For more information, see the [link:Automatic UE_LOG Integration documentation].', + { + code: , + link: ( + + ), + } + ), + }, + ], + }, + ], +}; diff --git a/static/app/gettingStartedDocs/unreal/onboarding.tsx b/static/app/gettingStartedDocs/unreal/onboarding.tsx index cdfd3b21c1cf0f..d59b1177869fea 100644 --- a/static/app/gettingStartedDocs/unreal/onboarding.tsx +++ b/static/app/gettingStartedDocs/unreal/onboarding.tsx @@ -9,8 +9,6 @@ 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; - const getVerifySnippet = () => ` #include "SentrySubsystem.h" @@ -24,7 +22,7 @@ void Verify() SentrySubsystem->CaptureMessage(TEXT("Capture message")); }`; -const getSettingsConfigureSnippet = (params: Params) => ` +const getSettingsConfigureSnippet = (params: DocsParams) => ` #include "SentrySubsystem.h" FConfigureSettingsDelegate OnConfigureSettings; @@ -39,7 +37,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 +52,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 +115,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( @@ -142,6 +160,42 @@ export const onboarding: OnboardingConfig = { }, ], }, + ...(params.isLogsSelected + ? ([ + { + title: t('Logs'), + content: [ + { + type: 'text', + text: t( + 'Once structured logging is enabled, you can send logs using the AddLog method on the Sentry subsystem:' + ), + }, + { + type: 'code', + language: 'cpp', + code: `USentrySubsystem* SentrySubsystem = GEngine->GetEngineSubsystem(); + +// Send logs at different severity levels +SentrySubsystem->AddLog(TEXT("A simple log message"), ESentryLevel::Info, TEXT("GameFlow")); +SentrySubsystem->AddLog(TEXT("Failed to save game data"), ESentryLevel::Error, TEXT("SaveSystem"));`, + }, + { + 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: ( + + ), + } + ), + }, + ], + }, + ] satisfies OnboardingStep[]) + : []), { title: t('Crash Reporter Client'), content: [