spring.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. import {Fragment} from 'react';
  2. import ExternalLink from 'sentry/components/links/externalLink';
  3. import Link from 'sentry/components/links/link';
  4. import {Layout, LayoutProps} from 'sentry/components/onboarding/gettingStartedDoc/layout';
  5. import {ModuleProps} from 'sentry/components/onboarding/gettingStartedDoc/sdkDocumentation';
  6. import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
  7. import {t, tct} from 'sentry/locale';
  8. interface StepsParams {
  9. dsn: string;
  10. organizationSlug?: string;
  11. projectSlug?: string;
  12. sourcePackageRegistries?: ModuleProps['sourcePackageRegistries'];
  13. }
  14. // Configuration Start
  15. const introduction = (
  16. <p>
  17. {tct(
  18. "Sentry's integration with Spring supports Spring Framework 5.1.2 and above. If you're on an older version, use [legacyIntegrationLink:our legacy integration].",
  19. {
  20. legacyIntegrationLink: (
  21. <ExternalLink href="https://docs.sentry.io/platforms/java/guides/spring/legacy/" />
  22. ),
  23. }
  24. )}
  25. </p>
  26. );
  27. export const steps = ({
  28. dsn,
  29. sourcePackageRegistries,
  30. projectSlug,
  31. organizationSlug,
  32. }: StepsParams): LayoutProps['steps'] => [
  33. {
  34. type: StepType.INSTALL,
  35. description: t(
  36. "Install Sentry's integration with Spring using either Maven or Gradle:"
  37. ),
  38. configurations: [
  39. {
  40. description: (
  41. <p>
  42. {tct(
  43. 'To see source context in Sentry, you have to generate an auth token by visiting the [link:Organization Auth Tokens] settings. You can then set the token as an environment variable that is used by the build plugins.',
  44. {
  45. link: <Link to="/settings/auth-tokens/" />,
  46. }
  47. )}
  48. </p>
  49. ),
  50. language: 'bash',
  51. code: `
  52. SENTRY_AUTH_TOKEN=___ORG_AUTH_TOKEN___
  53. `,
  54. },
  55. {
  56. description: <h5>{t('Gradle')}</h5>,
  57. configurations: [
  58. {
  59. description: (
  60. <p>
  61. {tct(
  62. 'The [link:Sentry Gradle Plugin] automatically installs the Sentry SDK as well as available integrations for your dependencies. Add the following to your [code:build.gradle] file:',
  63. {
  64. code: <code />,
  65. link: (
  66. <ExternalLink href="https://github.com/getsentry/sentry-android-gradle-plugin" />
  67. ),
  68. }
  69. )}
  70. </p>
  71. ),
  72. language: 'groovy',
  73. code: `
  74. buildscript {
  75. repositories {
  76. mavenCentral()
  77. }
  78. }
  79. plugins {
  80. id "io.sentry.jvm.gradle" version "${
  81. sourcePackageRegistries?.isLoading
  82. ? t('\u2026loading')
  83. : sourcePackageRegistries?.data?.['sentry.java.android.gradle-plugin']?.version ??
  84. '3.12.0'
  85. }"
  86. }
  87. sentry {
  88. // Generates a JVM (Java, Kotlin, etc.) source bundle and uploads your source code to Sentry.
  89. // This enables source context, allowing you to see your source
  90. // code as part of your stack traces in Sentry.
  91. includeSourceContext = true
  92. org = "${organizationSlug}"
  93. projectName = "${projectSlug}"
  94. authToken = System.getenv("SENTRY_AUTH_TOKEN")
  95. }
  96. `,
  97. },
  98. ],
  99. },
  100. {
  101. description: <h5>{t('Maven')}</h5>,
  102. additionalInfo: (
  103. <p>
  104. {tct(
  105. "There are two variants of Sentry available for Spring. If you're using Spring 5, use [sentrySpringLink:sentry-spring]. If you're using Spring 6, use [sentrySpringJakartaLink:sentry-spring-jakarta] instead.",
  106. {
  107. sentrySpringLink: (
  108. <ExternalLink href="https://github.com/getsentry/sentry-java/tree/master/sentry-spring" />
  109. ),
  110. sentrySpringJakartaLink: (
  111. <ExternalLink href="https://github.com/getsentry/sentry-java/tree/master/sentry-spring-jakarta" />
  112. ),
  113. }
  114. )}
  115. </p>
  116. ),
  117. configurations: [
  118. {
  119. language: 'xml',
  120. partialLoading: sourcePackageRegistries?.isLoading,
  121. description: <strong>{t('Spring 5')}</strong>,
  122. code: `
  123. <dependency>
  124. <groupId>io.sentry</groupId>
  125. <artifactId>sentry-spring</artifactId>
  126. <version>${
  127. sourcePackageRegistries?.isLoading
  128. ? t('\u2026loading')
  129. : sourcePackageRegistries?.data?.['sentry.java.spring']?.version ?? '6.28.0'
  130. }</version>
  131. </dependency>
  132. `,
  133. },
  134. {
  135. language: 'xml',
  136. partialLoading: sourcePackageRegistries?.isLoading,
  137. description: <strong>{t('Spring 6')}</strong>,
  138. code: `
  139. <dependency>
  140. <groupId>io.sentry</groupId>
  141. <artifactId>sentry-spring-jakarta</artifactId>
  142. <version>${
  143. sourcePackageRegistries?.isLoading
  144. ? t('\u2026loading')
  145. : sourcePackageRegistries?.data?.['sentry.java.spring.jakarta']?.version ?? '6.28.0'
  146. }</version>
  147. </dependency>
  148. `,
  149. },
  150. ],
  151. },
  152. ],
  153. },
  154. {
  155. type: StepType.CONFIGURE,
  156. description: (
  157. <Fragment>
  158. {t("Configure Sentry as soon as possible in your application's lifecycle:")}
  159. <p>
  160. {tct(
  161. 'The [codeSentrySpring:sentry-spring] and [codeSentrySpringJakarta:sentry-spring-jakarta] libraries provide an [codeEnableSentry:@EnableSentry] annotation that registers all required Spring beans. [codeEnableSentry:@EnableSentry] can be placed on any class annotated with [configurationLink:@Configuration] including the main entry class in Spring Boot applications annotated with [springBootApplicationLink:@SpringBootApplication].',
  162. {
  163. codeSentrySpring: <code />,
  164. codeSentrySpringJakarta: <code />,
  165. codeEnableSentry: <code />,
  166. configurationLink: (
  167. <ExternalLink href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html" />
  168. ),
  169. springBootApplicationLink: (
  170. <ExternalLink href="https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/SpringBootApplication.html" />
  171. ),
  172. }
  173. )}
  174. </p>
  175. </Fragment>
  176. ),
  177. configurations: [
  178. {
  179. description: <h5>{t('Java')}</h5>,
  180. configurations: [
  181. {
  182. language: 'java',
  183. description: <strong>{t('Spring 5')}</strong>,
  184. code: `
  185. import io.sentry.spring.EnableSentry;
  186. @EnableSentry(dsn = "${dsn}")
  187. @Configuration
  188. class SentryConfiguration {
  189. }
  190. `,
  191. },
  192. {
  193. language: 'java',
  194. description: <strong>{t('Spring 6')}</strong>,
  195. code: `
  196. import io.sentry.spring.jakarta.EnableSentry;
  197. @EnableSentry(dsn = "${dsn}")
  198. @Configuration
  199. class SentryConfiguration {
  200. }
  201. `,
  202. },
  203. ],
  204. },
  205. {
  206. description: <h5>{t('Kotlin')}</h5>,
  207. configurations: [
  208. {
  209. language: 'java',
  210. description: <strong>{t('Spring 5')}</strong>,
  211. code: `
  212. import io.sentry.spring.EnableSentry
  213. import org.springframework.core.Ordered
  214. @EnableSentry(
  215. dsn = "${dsn}",
  216. exceptionResolverOrder = Ordered.LOWEST_PRECEDENCE
  217. )
  218. `,
  219. },
  220. {
  221. language: 'java',
  222. description: <strong>{t('Spring 6')}</strong>,
  223. code: `
  224. import io.sentry.spring.jakarta.EnableSentry
  225. import org.springframework.core.Ordered
  226. @EnableSentry(
  227. dsn = "${dsn}",
  228. exceptionResolverOrder = Ordered.LOWEST_PRECEDENCE
  229. )
  230. `,
  231. },
  232. ],
  233. },
  234. {
  235. description: <h5>{t('Source Context')}</h5>,
  236. configurations: [
  237. {
  238. language: 'xml',
  239. partialLoading: sourcePackageRegistries?.isLoading,
  240. description: t(
  241. 'To upload your source code to Sentry so it can be shown in stack traces, use our Maven plugin.'
  242. ),
  243. code: `
  244. <build>
  245. <plugins>
  246. <plugin>
  247. <groupId>io.sentry</groupId>
  248. <artifactId>sentry-maven-plugin</artifactId>
  249. <version>${
  250. sourcePackageRegistries?.isLoading
  251. ? t('\u2026loading')
  252. : sourcePackageRegistries?.data?.['sentry.java.mavenplugin']?.version ?? '0.0.4'
  253. }</version>
  254. <configuration>
  255. <!-- for showing output of sentry-cli -->
  256. <debugSentryCli>true</debugSentryCli>
  257. <org>${organizationSlug}</org>
  258. <project>${projectSlug}</project>
  259. <!-- in case you're self hosting, provide the URL here -->
  260. <!--<url>http://localhost:8000/</url>-->
  261. <!-- provide your auth token via SENTRY_AUTH_TOKEN environment variable -->
  262. <authToken>\${env.SENTRY_AUTH_TOKEN}</authToken>
  263. </configuration>
  264. <executions>
  265. <execution>
  266. <phase>generate-resources</phase>
  267. <goals>
  268. <goal>uploadSourceBundle</goal>
  269. </goals>
  270. </execution>
  271. </executions>
  272. </plugin>
  273. </plugins>
  274. ...
  275. `,
  276. },
  277. ],
  278. },
  279. ],
  280. },
  281. {
  282. type: StepType.VERIFY,
  283. description: t(
  284. 'Last, create an intentional error, so you can test that everything is working:'
  285. ),
  286. configurations: [
  287. {
  288. description: <h5>Java</h5>,
  289. language: 'java',
  290. code: `
  291. import java.lang.Exception;
  292. import io.sentry.Sentry;
  293. try {
  294. throw new Exception("This is a test.");
  295. } catch (Exception e) {
  296. Sentry.captureException(e);
  297. }
  298. `,
  299. },
  300. {
  301. description: <h5>Kotlin</h5>,
  302. language: 'java',
  303. code: `
  304. import java.lang.Exception
  305. import io.sentry.Sentry
  306. try {
  307. throw Exception("This is a test.")
  308. } catch (e: Exception) {
  309. Sentry.captureException(e)
  310. }
  311. `,
  312. },
  313. ],
  314. additionalInfo: (
  315. <Fragment>
  316. <p>
  317. {t(
  318. "If you're new to Sentry, use the email alert to access your account and complete a product tour."
  319. )}
  320. </p>
  321. <p>
  322. {t(
  323. "If you're an existing user and have disabled alerts, you won't receive this email."
  324. )}
  325. </p>
  326. </Fragment>
  327. ),
  328. },
  329. {
  330. title: t('Other build tools'),
  331. additionalInfo: (
  332. <p>
  333. {tct(
  334. 'For other dependency managers see the [mavenRepositorySpring5Link:central Maven repository (Spring 5)] and [mavenRepositorySpring6Link:central Maven repository (Spring 6)].',
  335. {
  336. mavenRepositorySpring5Link: (
  337. <ExternalLink
  338. href={`https://central.sonatype.com/artifact/io.sentry/sentry-spring/${
  339. sourcePackageRegistries?.data?.['sentry.java.spring']?.version ??
  340. '6.28.0'
  341. }`}
  342. />
  343. ),
  344. mavenRepositorySpring6Link: (
  345. <ExternalLink
  346. href={`https://central.sonatype.com/artifact/io.sentry/sentry-spring-jakarta/${
  347. sourcePackageRegistries?.data?.['sentry.java.spring.jakarta']
  348. ?.version ?? '6.28.0'
  349. }`}
  350. />
  351. ),
  352. }
  353. )}
  354. </p>
  355. ),
  356. },
  357. ];
  358. export const nextSteps = [
  359. {
  360. id: 'examples',
  361. name: t('Examples'),
  362. description: t('Check out our sample applications.'),
  363. link: 'https://github.com/getsentry/sentry-java/tree/main/sentry-samples',
  364. },
  365. {
  366. id: 'performance-monitoring',
  367. name: t('Performance Monitoring'),
  368. description: t(
  369. 'Stay ahead of latency issues and trace every slow transaction to a poor-performing API call or database query.'
  370. ),
  371. link: 'https://docs.sentry.io/platforms/java/guides/spring/performance/',
  372. },
  373. ];
  374. // Configuration End
  375. export function GettingStartedWithSpring({
  376. dsn,
  377. sourcePackageRegistries,
  378. projectSlug,
  379. organization,
  380. ...props
  381. }: ModuleProps) {
  382. const nextStepDocs = [...nextSteps];
  383. return (
  384. <Layout
  385. steps={steps({
  386. dsn,
  387. sourcePackageRegistries,
  388. projectSlug: projectSlug ?? '___PROJECT_SLUG___',
  389. organizationSlug: organization?.slug ?? '___ORG_SLUG___',
  390. })}
  391. nextSteps={nextStepDocs}
  392. introduction={introduction}
  393. projectSlug={projectSlug}
  394. {...props}
  395. />
  396. );
  397. }
  398. export default GettingStartedWithSpring;