quickStartEntries.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. import {Fragment} from 'react';
  2. import merge from 'lodash/merge';
  3. import {CodeSnippet} from 'sentry/components/codeSnippet';
  4. import ExternalLink from 'sentry/components/links/externalLink';
  5. import {t, tct} from 'sentry/locale';
  6. export interface QuickStartProps {
  7. dsnKey?: string;
  8. orgId?: string;
  9. orgSlug?: string;
  10. projectId?: string;
  11. publicKey?: string;
  12. slug?: string;
  13. }
  14. const VALUE_DEFAULTS = {
  15. dsnKey: '<my-dsn-key>',
  16. orgId: '<my-organziation-id>',
  17. orgSlug: '<my-organization-slug>',
  18. projectId: '<my-project-id>',
  19. publicKey: '<my-dsn-public-key>',
  20. slug: '<my-monitor-slug>',
  21. };
  22. function withDefaultProps(props: QuickStartProps): Required<QuickStartProps> {
  23. return merge(VALUE_DEFAULTS, props);
  24. }
  25. export function PythonCronQuickStart(props: QuickStartProps) {
  26. const {slug} = withDefaultProps(props);
  27. const code = `import sentry_sdk
  28. from sentry_sdk.crons import monitor
  29. # Add this decorator to instrument your python function
  30. @monitor(monitor_slug='${slug}')
  31. def tell_the_world(msg):
  32. print(msg)`;
  33. return (
  34. <Fragment>
  35. <div>
  36. {tct(
  37. '[installLink:Install and configure] the Sentry Python SDK (min v1.17.0), then instrument your monitor:',
  38. {
  39. installLink: <ExternalLink href="https://docs.sentry.io/platforms/python/" />,
  40. }
  41. )}
  42. </div>
  43. <CodeSnippet language="python">{code}</CodeSnippet>
  44. </Fragment>
  45. );
  46. }
  47. export function PythonCeleryCronQuickStart(props: QuickStartProps) {
  48. const {slug, dsnKey} = withDefaultProps(props);
  49. const setupCode = `import sentry_sdk
  50. from sentry_sdk.crons import monitor
  51. from sentry_sdk.integrations.celery import CeleryIntegration
  52. # @signals.celeryd_init.connect
  53. @signals.beat_init.connect
  54. def init_sentry(**kwargs):
  55. sentry_sdk.init(
  56. dsn='${dsnKey}',
  57. integrations=[CeleryIntegration()],
  58. )
  59. `;
  60. const linkTaskCode = `@app.task
  61. @monitor(monitor_slug='${slug}')
  62. def tell_the_world(msg):
  63. print(msg)
  64. `;
  65. return (
  66. <Fragment>
  67. <div>
  68. {tct(
  69. '[installLink:Install and configure] the Sentry Python SDK (min v1.17.0), then initialize Sentry either in [celerydInit:celeryd_init] or [beatInit:beat_init] signal:',
  70. {
  71. celerydInit: <code />,
  72. beatInit: <code />,
  73. installLink: (
  74. <ExternalLink href="https://docs.sentry.io/platforms/python/guides/celery/" />
  75. ),
  76. }
  77. )}
  78. </div>
  79. <CodeSnippet language="python">{setupCode}</CodeSnippet>
  80. <div>{t('Link your Celery task to your Monitor:')}</div>
  81. <CodeSnippet language="python">{linkTaskCode}</CodeSnippet>
  82. </Fragment>
  83. );
  84. }
  85. export function CLICronQuickStart(props: QuickStartProps) {
  86. const {slug, dsnKey} = withDefaultProps(props);
  87. const script = `# Example for a Python script:
  88. export SENTRY_DSN=${dsnKey}
  89. sentry-cli monitors run ${slug} -- python path/to/file`;
  90. return (
  91. <Fragment>
  92. <div>
  93. {tct(
  94. 'Make sure to [installLink:install the Sentry CLI] (min v2.16.1), then instrument your monitor:',
  95. {
  96. installLink: (
  97. <ExternalLink href="https://docs.sentry.io/product/cli/installation/" />
  98. ),
  99. }
  100. )}
  101. </div>
  102. <CodeSnippet language="bash">{script}</CodeSnippet>
  103. </Fragment>
  104. );
  105. }
  106. export function CurlCronQuickStart(props: QuickStartProps) {
  107. const {projectId, orgId, slug, publicKey} = withDefaultProps(props);
  108. const checkInSuccessCode = `SENTRY_INGEST="https://o${orgId}.ingest.sentry.io"
  109. SENTRY_CRONS="\${SENTRY_INGEST}/api/${projectId}/cron/${slug}/${publicKey}/"
  110. # 🟡 Notify Sentry your job is running:
  111. curl "\${SENTRY_CRONS}?status=in_progress"
  112. # Execute your scheduled task here...
  113. # 🟢 Notify Sentry your job has completed successfully:
  114. curl "\${SENTRY_CRONS}?status=ok"`;
  115. const checkInFailCode = `# 🔴 Notify Sentry your job has failed:
  116. curl "\${SENTRY_CRONS}?status=error"`;
  117. return (
  118. <Fragment>
  119. <CodeSnippet language="bash">{checkInSuccessCode}</CodeSnippet>
  120. <div>{t('To notify Sentry if your job execution fails')}</div>
  121. <CodeSnippet language="bash">{checkInFailCode}</CodeSnippet>
  122. </Fragment>
  123. );
  124. }
  125. export function PHPCronQuickStart(props: QuickStartProps) {
  126. const {slug} = withDefaultProps(props);
  127. const checkInSuccessCode = `// 🟡 Notify Sentry your job is running:
  128. $event = Event::createCheckIn();
  129. $checkIn = new CheckIn(
  130. monitorSlug: '${slug}',
  131. status: CheckInStatus::inProgress(),
  132. );
  133. $event->setCheckIn($checkIn);
  134. SentrySdk::getCurrentHub()->captureEvent($event);
  135. // Execute your scheduled task here...
  136. // 🟢 Notify Sentry your job has completed successfully:
  137. $event = Event::createCheckIn();
  138. $event->setCheckIn(new CheckIn(
  139. id: $checkIn->getId(),
  140. monitorSlug: '${slug}',
  141. status: CheckInStatus::ok(),
  142. ));
  143. SentrySdk::getCurrentHub()->captureEvent($event);`;
  144. const checkInFailCode = `// 🔴 Notify Sentry your job has failed:
  145. $event = Event::createCheckIn();
  146. $event->setCheckIn(new CheckIn(
  147. id: $checkIn->getId(),
  148. monitorSlug: '${slug}',
  149. status: CheckInStatus::error(),
  150. ));
  151. SentrySdk::getCurrentHub()->captureEvent($event);`;
  152. return (
  153. <Fragment>
  154. <div>
  155. {tct(
  156. '[installLink:Install and configure] the Sentry PHP SDK (min v3.16.0), then instrument your monitor:',
  157. {
  158. installLink: <ExternalLink href="https://docs.sentry.io/platforms/php/" />,
  159. }
  160. )}
  161. </div>
  162. <CodeSnippet language="php">{checkInSuccessCode}</CodeSnippet>
  163. <div>{t('To notify Sentry if your job execution fails')}</div>
  164. <CodeSnippet language="php">{checkInFailCode}</CodeSnippet>
  165. </Fragment>
  166. );
  167. }
  168. export function PHPLaravelCronQuickStart(props: QuickStartProps) {
  169. const {slug} = withDefaultProps(props);
  170. const code = `protected function schedule(Schedule $schedule)
  171. {
  172. $schedule->command('emails:send')
  173. ->everyHour()
  174. ->sentryMonitor('${slug}'); // add this line
  175. }`;
  176. return (
  177. <Fragment>
  178. <div>
  179. {tct(
  180. '[installLink:Install and configure] the Sentry PHP Laravel SDK (min v3.3.1), then add the [sentryMonitor:sentryMonitor()] call to your scheduled tasks defined in your [kernel:app/Console/Kernel.php] file:',
  181. {
  182. sentryMonitor: <code />,
  183. kernel: <code />,
  184. installLink: (
  185. <ExternalLink href="https://docs.sentry.io/platforms/php/guides/laravel/" />
  186. ),
  187. }
  188. )}
  189. </div>
  190. <CodeSnippet language="php">{code}</CodeSnippet>
  191. </Fragment>
  192. );
  193. }
  194. export function NodeJSCronQuickStart(props: QuickStartProps) {
  195. const {slug} = withDefaultProps(props);
  196. const checkInSuccessCode = `// 🟡 Notify Sentry your job is running:
  197. const checkInId = Sentry.captureCheckIn({
  198. monitorSlug: "${slug}",
  199. status: "in_progress",
  200. });
  201. // Execute your scheduled task here...
  202. // 🟢 Notify Sentry your job has completed successfully:
  203. Sentry.captureCheckIn({
  204. checkInId,
  205. monitorSlug: "${slug}",
  206. status: "ok",
  207. });`;
  208. const checkInFailCode = `// 🔴 Notify Sentry your job has failed:
  209. Sentry.captureCheckIn({
  210. checkInId,
  211. monitorSlug: "${slug}",
  212. status: "error",
  213. });`;
  214. return (
  215. <Fragment>
  216. <div>
  217. {tct(
  218. '[installLink:Install and configure] the Sentry Node SDK (min v7.52), then instrument your monitor:',
  219. {
  220. installLink: <ExternalLink href="https://docs.sentry.io/platforms/node/" />,
  221. }
  222. )}
  223. </div>
  224. <CodeSnippet language="javascript">{checkInSuccessCode}</CodeSnippet>
  225. <div>{t('To notify Sentry if your job execution fails')}</div>
  226. <CodeSnippet language="javascript">{checkInFailCode}</CodeSnippet>
  227. </Fragment>
  228. );
  229. }
  230. export function CeleryBeatAutoDiscovery(props: QuickStartProps) {
  231. const {dsnKey} = props;
  232. const code = `# tasks.py
  233. from celery import signals
  234. import sentry_sdk
  235. from sentry_sdk.integrations.celery import CeleryIntegration
  236. @signals.celeryd_init.connect
  237. def init_sentry(**kwargs):
  238. sentry_sdk.init(
  239. dsn='${dsnKey ?? '<PROJECT DSN>'}',
  240. integrations=[CeleryIntegration(monitor_beat_tasks=True)], # 👈
  241. environment="local.dev.grace",
  242. release="v1.0",
  243. )
  244. `;
  245. return (
  246. <Fragment>
  247. <div>
  248. {tct(
  249. 'Use the [additionalDocs: Celery integration] to monitor your Celery periodic tasks. Initialize Sentry in the celeryd_init or beat_init signal.',
  250. {
  251. additionalDocs: (
  252. <ExternalLink href="https://docs.sentry.io/platforms/python/guides/celery/crons/#celery-beat-auto-discovery" />
  253. ),
  254. }
  255. )}
  256. </div>
  257. <div>{t('Make sure to set monitor_beat_tasks=True in CeleryIntegration:')}</div>
  258. <CodeSnippet language="python">{code}</CodeSnippet>
  259. </Fragment>
  260. );
  261. }
  262. export function PHPUpsertPlatformGuide() {
  263. const scheduleCode = `// Create a crontab schedule object (every 10 minutes)
  264. $monitorSchedule = \Sentry\MonitorSchedule::crontab('*/10 * * * *');
  265. // Or create an interval schedule object (every 10 minutes)
  266. $monitorSchedule = \Sentry\MonitorSchedule::interval(10, MonitorScheduleUnit::minute());`;
  267. const upsertCode = `// Create a config object
  268. $monitorConfig = new \Sentry\MonitorConfig(
  269. $monitorSchedule,
  270. checkinMargin: 5, // Optional check-in margin in minutes
  271. maxRuntime: 15, // Optional max runtime in minutes
  272. timezone: 'Europe/Vienna', // Optional timezone
  273. );
  274. // 🟡 Notify Sentry your job is running:
  275. $checkInId = \Sentry\captureCheckIn(
  276. slug: '<monitor-slug>',
  277. status: CheckInStatus::inProgress(),
  278. monitorConfig: $monitorConfig,
  279. );
  280. // Execute your scheduled task here...
  281. // 🟢 Notify Sentry your job has completed successfully:
  282. \Sentry\captureCheckIn(
  283. slug: '<monitor-slug>',
  284. status: CheckInStatus::inProgress(),
  285. checkInId: $checkInId,
  286. );`;
  287. return (
  288. <Fragment>
  289. <div>
  290. {tct(
  291. 'You can use the [additionalDocs: PHP SDK] to create and update your Monitors programmatically with code rather than creating them manually.',
  292. {
  293. additionalDocs: (
  294. <ExternalLink href="https://docs.sentry.io/platforms/php/crons/#upserting-cron-monitors" />
  295. ),
  296. }
  297. )}
  298. </div>
  299. <CodeSnippet language="php">{scheduleCode}</CodeSnippet>
  300. <CodeSnippet language="php">{upsertCode}</CodeSnippet>
  301. </Fragment>
  302. );
  303. }
  304. export function LaravelUpsertPlatformGuide() {
  305. const basicConfigCode = `protected function schedule(Schedule $schedule)
  306. {
  307. $schedule->command('emails:send')
  308. ->everyHour()
  309. ->sentryMonitor(); // add this line
  310. }`;
  311. const advancedConfigCode = `protected function schedule(Schedule $schedule)
  312. {
  313. $schedule->command('emails:send')
  314. ->everyHour()
  315. ->sentryMonitor(
  316. // Specify the slug of the job monitor in case of duplicate commands or if the monitor was created in the UI
  317. monitorSlug: null,
  318. // Check-in margin in minutes
  319. checkInMargin: 5,
  320. // Max runtime in minutes
  321. maxRuntime: 15,
  322. // In case you want to configure the job monitor exclusively in the UI, you can turn off sending the monitor config with the check-in.
  323. // Passing a monitor-slug is required in this case.
  324. updateMonitorConfig: false,
  325. )
  326. }`;
  327. return (
  328. <Fragment>
  329. <div>
  330. {tct('Use the [additionalDocs: Laravel SDK] to monitor your scheduled task.', {
  331. additionalDocs: (
  332. <ExternalLink href="https://docs.sentry.io/platforms/php/guides/laravel/crons/#job-monitoring" />
  333. ),
  334. })}
  335. </div>
  336. <div>
  337. {t(
  338. 'To set up, add the "sentryMonitor()" macro to your scheduled tasks defined in your "app/Console/Kernel.php" file:'
  339. )}
  340. </div>
  341. <CodeSnippet language="php">{basicConfigCode}</CodeSnippet>
  342. <div>
  343. {t(
  344. 'By default, the Laravel SDK will infer various parameters of your scheduled task. For greater control, we expose some optional parameters on the sentryMonitor() macro.'
  345. )}
  346. </div>
  347. <CodeSnippet language="php">{advancedConfigCode}</CodeSnippet>
  348. </Fragment>
  349. );
  350. }
  351. export function NodeJsUpsertPlatformGuide() {
  352. const upsertCode = `const checkInId = Sentry.captureCheckIn(
  353. {
  354. monitorSlug: '<monitor-slug>',
  355. status: 'in_progress',
  356. },
  357. {
  358. schedule: { // Specify your schedule options here
  359. type: 'crontab',
  360. value: '* * * * *',
  361. },
  362. checkinMargin: 1,
  363. maxRuntime: 1,
  364. timezone: 'America/Los_Angeles',
  365. });
  366. Sentry.captureCheckIn({
  367. checkInId,
  368. monitorSlug: '<monitor-slug>',
  369. status: 'ok',
  370. });
  371. `;
  372. return (
  373. <Fragment>
  374. <div>
  375. {tct(
  376. 'Use the [additionalDocs:Node SDK] to create and update your Monitors programmatically with code rather than creating them manually.',
  377. {
  378. additionalDocs: (
  379. <ExternalLink href="https://docs.sentry.io/platforms/node/crons/" />
  380. ),
  381. }
  382. )}
  383. </div>
  384. <CodeSnippet language="javascript">{upsertCode}</CodeSnippet>
  385. </Fragment>
  386. );
  387. }