laravel.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. import ExternalLink from 'sentry/components/links/externalLink';
  2. import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
  3. import type {
  4. Docs,
  5. DocsParams,
  6. OnboardingConfig,
  7. } from 'sentry/components/onboarding/gettingStartedDoc/types';
  8. import {
  9. getCrashReportModalConfigDescription,
  10. getCrashReportModalIntroduction,
  11. getCrashReportSDKInstallFirstStep,
  12. } from 'sentry/components/onboarding/gettingStartedDoc/utils/feedbackOnboarding';
  13. import exampleSnippets from 'sentry/components/onboarding/gettingStartedDoc/utils/metricsExampleSnippets';
  14. import {metricTagsExplanation} from 'sentry/components/onboarding/gettingStartedDoc/utils/metricsOnboarding';
  15. import replayOnboardingJsLoader from 'sentry/gettingStartedDocs/javascript/jsLoader/jsLoader';
  16. import {t, tct} from 'sentry/locale';
  17. type Params = DocsParams;
  18. const getExceptionHandlerSnippet = () => `
  19. <?php
  20. use Illuminate\\Foundation\\Application;
  21. use Illuminate\\Foundation\\Configuration\\Exceptions;
  22. use Illuminate\\Foundation\\Configuration\\Middleware;
  23. use Sentry\\Laravel\\Integration;
  24. return Application::configure(basePath: dirname(__DIR__))
  25. ->withRouting(
  26. web: __DIR__.'/../routes/web.php',
  27. commands: __DIR__.'/../routes/console.php',
  28. health: '/up',
  29. )
  30. ->withMiddleware(function (Middleware $middleware) {
  31. //
  32. })
  33. ->withExceptions(function (Exceptions $exceptions) {
  34. Integration::handles($exceptions);
  35. })->create();`;
  36. const getConfigureSnippet = (params: Params) =>
  37. `SENTRY_LARAVEL_DSN=${params.dsn}${
  38. params.isPerformanceSelected
  39. ? `
  40. # Specify a fixed sample rate
  41. SENTRY_TRACES_SAMPLE_RATE=1.0`
  42. : ''
  43. }${
  44. params.isProfilingSelected
  45. ? `
  46. # Set a sampling rate for profiling - this is relative to traces_sample_rate
  47. SENTRY_PROFILES_SAMPLE_RATE=1.0`
  48. : ''
  49. }`;
  50. const getMetricsInstallSnippet = () => `
  51. composer install sentry/sentry-laravel
  52. composer update sentry/sentry-laravel -W`;
  53. const onboarding: OnboardingConfig = {
  54. introduction: () =>
  55. tct(
  56. 'This guide is for Laravel 11.0 an up. We also provide instructions for [otherVersionsLink:other versions] as well as [lumenSpecificLink:Lumen-specific instructions].',
  57. {
  58. otherVersionsLink: (
  59. <ExternalLink href="https://docs.sentry.io/platforms/php/guides/laravel/other-versions/" />
  60. ),
  61. lumenSpecificLink: (
  62. <ExternalLink href="https://docs.sentry.io/platforms/php/guides/laravel/other-versions/lumen/" />
  63. ),
  64. }
  65. ),
  66. install: (params: Params) => [
  67. {
  68. type: StepType.INSTALL,
  69. configurations: [
  70. {
  71. description: tct('Install the [code:sentry/sentry-laravel] package:', {
  72. code: <code />,
  73. }),
  74. language: 'bash',
  75. code: `composer require sentry/sentry-laravel`,
  76. },
  77. ...(params.isProfilingSelected
  78. ? [
  79. {
  80. description: t('Install the Excimer extension via PECL:'),
  81. language: 'bash',
  82. code: 'pecl install excimer',
  83. },
  84. {
  85. description: tct(
  86. "The Excimer PHP extension supports PHP 7.2 and up. Excimer requires Linux or macOS and doesn't support Windows. For additional ways to install Excimer, see [sentryPhpDocumentationLink: Sentry documentation].",
  87. {
  88. sentryPhpDocumentationLink: (
  89. <ExternalLink href="https://docs.sentry.io/platforms/php/profiling/#installation" />
  90. ),
  91. }
  92. ),
  93. },
  94. ]
  95. : []),
  96. {
  97. description: tct(
  98. 'Enable capturing unhandled exception to report to Sentry by making the following change to your [code:bootstrap/app.php]:',
  99. {
  100. code: <code />,
  101. }
  102. ),
  103. language: 'php',
  104. code: getExceptionHandlerSnippet(),
  105. },
  106. ],
  107. },
  108. ],
  109. configure: (params: Params) => [
  110. {
  111. type: StepType.CONFIGURE,
  112. configurations: [
  113. {
  114. description: t('Configure the Sentry DSN with this command:'),
  115. language: 'shell',
  116. code: `php artisan sentry:publish --dsn=${params.dsn}`,
  117. },
  118. {
  119. description: tct(
  120. 'It creates the config file ([sentryPHPCode:config/sentry.php]) and adds the [dsnCode:DSN] to your [envCode:.env] file where you can add further configuration options:',
  121. {sentryPHPCode: <code />, dsnCode: <code />, envCode: <code />}
  122. ),
  123. language: 'shell',
  124. code: getConfigureSnippet(params),
  125. },
  126. ],
  127. },
  128. ],
  129. verify: () => [
  130. {
  131. type: StepType.VERIFY,
  132. configurations: [
  133. {
  134. description: tct(
  135. 'You can test your configuration using the provided [code:sentry:test] artisan command:',
  136. {
  137. code: <code />,
  138. }
  139. ),
  140. language: 'shell',
  141. code: 'php artisan sentry:test',
  142. },
  143. ],
  144. },
  145. ],
  146. nextSteps: () => [],
  147. };
  148. const customMetricsOnboarding: OnboardingConfig = {
  149. install: () => [
  150. {
  151. type: StepType.INSTALL,
  152. description: tct(
  153. 'You need a minimum version [codeVersionLaravel:4.2.0] of the Laravel SDK and a minimum version [codeVersion:4.3.0] of the PHP SDK installed',
  154. {
  155. codeVersionLaravel: <code />,
  156. codeVersion: <code />,
  157. }
  158. ),
  159. configurations: [
  160. {
  161. language: 'bash',
  162. code: getMetricsInstallSnippet(),
  163. },
  164. ],
  165. },
  166. ],
  167. configure: () => [
  168. {
  169. type: StepType.CONFIGURE,
  170. description: tct(
  171. 'Once the SDK is installed or updated, you can enable code locations being emitted with your metrics in your [code:config/sentry.php] file:',
  172. {
  173. code: <code />,
  174. }
  175. ),
  176. configurations: [
  177. {
  178. code: [
  179. {
  180. label: 'PHP',
  181. value: 'php',
  182. language: 'php',
  183. code: `'attach_metric_code_locations' => true,`,
  184. },
  185. ],
  186. },
  187. ],
  188. },
  189. ],
  190. verify: () => [
  191. {
  192. type: StepType.VERIFY,
  193. description: tct(
  194. "Then you'll be able to add metrics as [codeCounters:counters], [codeSets:sets], [codeDistribution:distributions], and [codeGauge:gauges].",
  195. {
  196. codeCounters: <code />,
  197. codeSets: <code />,
  198. codeDistribution: <code />,
  199. codeGauge: <code />,
  200. codeNamespace: <code />,
  201. }
  202. ),
  203. configurations: [
  204. {
  205. description: metricTagsExplanation,
  206. },
  207. {
  208. description: t('Try out these examples:'),
  209. code: [
  210. {
  211. label: 'Counter',
  212. value: 'counter',
  213. language: 'php',
  214. code: exampleSnippets.php.counter,
  215. },
  216. {
  217. label: 'Distribution',
  218. value: 'distribution',
  219. language: 'php',
  220. code: exampleSnippets.php.distribution,
  221. },
  222. {
  223. label: 'Set',
  224. value: 'set',
  225. language: 'php',
  226. code: exampleSnippets.php.set,
  227. },
  228. {
  229. label: 'Gauge',
  230. value: 'gauge',
  231. language: 'php',
  232. code: exampleSnippets.php.gauge,
  233. },
  234. ],
  235. },
  236. {
  237. description: t(
  238. 'With a bit of delay you can see the data appear in the Sentry UI.'
  239. ),
  240. },
  241. {
  242. description: tct(
  243. 'Learn more about metrics and how to configure them, by reading the [docsLink:docs].',
  244. {
  245. docsLink: (
  246. <ExternalLink href="https://docs.sentry.io/platforms/php/guides/laravel/metrics/" />
  247. ),
  248. }
  249. ),
  250. },
  251. ],
  252. },
  253. ],
  254. };
  255. const crashReportOnboarding: OnboardingConfig = {
  256. introduction: () => getCrashReportModalIntroduction(),
  257. install: (params: Params) => [
  258. {
  259. type: StepType.INSTALL,
  260. configurations: [
  261. getCrashReportSDKInstallFirstStep(params),
  262. {
  263. description: tct(
  264. 'Next, create [code:resources/views/errors/500.blade.php], and embed the feedback code:',
  265. {code: <code />}
  266. ),
  267. code: [
  268. {
  269. label: 'HTML',
  270. value: 'html',
  271. language: 'html',
  272. code: `<div class="content">
  273. <div class="title">Something went wrong.</div>
  274. @if(app()->bound('sentry') && app('sentry')->getLastEventId())
  275. <div class="subtitle">Error ID: {{ app('sentry')->getLastEventId() }}</div>
  276. <script>
  277. Sentry.init({ dsn: '${params.dsn}' });
  278. Sentry.showReportDialog({
  279. eventId: '{{ app('sentry')->getLastEventId() }}'
  280. });
  281. </script>
  282. @endif
  283. </div>`,
  284. },
  285. ],
  286. },
  287. {
  288. description: tct(
  289. 'For Laravel 5 up to 5.4 there is some extra work needed. You need to open up [codeApp:App/Exceptions/Handler.php] and extend the [codeRender:render] method to make sure the 500 error is rendered as a view correctly, in 5.5+ this step is not required anymore.',
  290. {code: <code />}
  291. ),
  292. code: [
  293. {
  294. label: 'PHP',
  295. value: 'php',
  296. language: 'php',
  297. code: `<?php
  298. use Symfony\Component\HttpKernel\Exception\HttpException;
  299. class Handler extends ExceptionHandler
  300. {
  301. public function report(Exception $exception)
  302. {
  303. if (app()->bound('sentry') && $this->shouldReport($exception)) {
  304. app('sentry')->captureException($exception);
  305. }
  306. parent::report($exception);
  307. }
  308. // This method is ONLY needed for Laravel 5 up to 5.4.
  309. // You can skip this method if you are using Laravel 5.5+.
  310. public function render($request, Exception $exception)
  311. {
  312. // Convert all non-http exceptions to a proper 500 http exception
  313. // if we don't do this exceptions are shown as a default template
  314. // instead of our own view in resources/views/errors/500.blade.php
  315. if ($this->shouldReport($exception) && !$this->isHttpException($exception) && !config('app.debug')) {
  316. $exception = new HttpException(500, 'Whoops!');
  317. }
  318. return parent::render($request, $exception);
  319. }
  320. }`,
  321. },
  322. ],
  323. },
  324. ],
  325. },
  326. ],
  327. configure: () => [
  328. {
  329. type: StepType.CONFIGURE,
  330. description: getCrashReportModalConfigDescription({
  331. link: 'https://docs.sentry.io/platforms/php/guides/laravel/user-feedback/configuration/#crash-report-modal',
  332. }),
  333. },
  334. ],
  335. verify: () => [],
  336. nextSteps: () => [],
  337. };
  338. const docs: Docs = {
  339. onboarding,
  340. replayOnboardingJsLoader,
  341. customMetricsOnboarding,
  342. crashReportOnboarding,
  343. };
  344. export default docs;