spring.tsx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. import {Fragment} from 'react';
  2. import ExternalLink from 'sentry/components/links/externalLink';
  3. import Link from 'sentry/components/links/link';
  4. import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
  5. import type {
  6. BasePlatformOptions,
  7. Docs,
  8. DocsParams,
  9. OnboardingConfig,
  10. } from 'sentry/components/onboarding/gettingStartedDoc/types';
  11. import {feedbackOnboardingCrashApiJava} from 'sentry/gettingStartedDocs/java/java';
  12. import {
  13. feedbackOnboardingJsLoader,
  14. replayOnboardingJsLoader,
  15. } from 'sentry/gettingStartedDocs/javascript/jsLoader/jsLoader';
  16. import {t, tct} from 'sentry/locale';
  17. import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion';
  18. export enum SpringVersion {
  19. V5 = 'v5',
  20. V6 = 'v6',
  21. }
  22. export enum PackageManager {
  23. GRADLE = 'gradle',
  24. MAVEN = 'maven',
  25. }
  26. export enum YesNo {
  27. YES = 'yes',
  28. NO = 'no',
  29. }
  30. const platformOptions = {
  31. springVersion: {
  32. label: t('Spring Version'),
  33. items: [
  34. {
  35. label: t('Spring 6'),
  36. value: SpringVersion.V6,
  37. },
  38. {
  39. label: t('Spring 5'),
  40. value: SpringVersion.V5,
  41. },
  42. ],
  43. },
  44. packageManager: {
  45. label: t('Package Manager'),
  46. items: [
  47. {
  48. label: t('Gradle'),
  49. value: PackageManager.GRADLE,
  50. },
  51. {
  52. label: t('Maven'),
  53. value: PackageManager.MAVEN,
  54. },
  55. ],
  56. },
  57. opentelemetry: {
  58. label: t('OpenTelemetry'),
  59. items: [
  60. {
  61. label: t('With OpenTelemetry'),
  62. value: YesNo.YES,
  63. },
  64. {
  65. label: t('Without OpenTelemetry'),
  66. value: YesNo.NO,
  67. },
  68. ],
  69. },
  70. } satisfies BasePlatformOptions;
  71. type PlatformOptions = typeof platformOptions;
  72. type Params = DocsParams<PlatformOptions>;
  73. const getGradleInstallSnippet = (params: Params) => `
  74. buildscript {
  75. repositories {
  76. mavenCentral()
  77. }
  78. }
  79. plugins {
  80. id "io.sentry.jvm.gradle" version "${getPackageVersion(
  81. params,
  82. 'sentry.java.android.gradle-plugin',
  83. '3.12.0'
  84. )}"
  85. }
  86. sentry {
  87. // Generates a JVM (Java, Kotlin, etc.) source bundle and uploads your source code to Sentry.
  88. // This enables source context, allowing you to see your source
  89. // code as part of your stack traces in Sentry.
  90. includeSourceContext = true
  91. org = "${params.organization.slug}"
  92. projectName = "${params.projectSlug}"
  93. authToken = System.getenv("SENTRY_AUTH_TOKEN")
  94. }`;
  95. const getMavenInstallSnippet = (params: Params) => `
  96. <build>
  97. <plugins>
  98. <plugin>
  99. <groupId>io.sentry</groupId>
  100. <artifactId>sentry-maven-plugin</artifactId>
  101. <version>${
  102. params.sourcePackageRegistries?.isLoading
  103. ? t('\u2026loading')
  104. : params.sourcePackageRegistries?.data?.['sentry.java.maven-plugin']?.version ??
  105. '0.0.4'
  106. }</version>
  107. <extensions>true</extensions>
  108. <configuration>
  109. <!-- for showing output of sentry-cli -->
  110. <debugSentryCli>true</debugSentryCli>
  111. <org>${params.organization.slug}</org>
  112. <project>${params.projectSlug}</project>
  113. <!-- in case you're self hosting, provide the URL here -->
  114. <!--<url>http://localhost:8000/</url>-->
  115. <!-- provide your auth token via SENTRY_AUTH_TOKEN environment variable -->
  116. <authToken>\${env.SENTRY_AUTH_TOKEN}</authToken>
  117. </configuration>
  118. <executions>
  119. <execution>
  120. <goals>
  121. <!--
  122. Generates a JVM (Java, Kotlin, etc.) source bundle and uploads your source code to Sentry.
  123. This enables source context, allowing you to see your source
  124. code as part of your stack traces in Sentry.
  125. -->
  126. <goal>uploadSourceBundle</goal>
  127. </goals>
  128. </execution>
  129. </executions>
  130. </plugin>
  131. </plugins>
  132. ...
  133. </build>`;
  134. const getOpenTelemetryRunSnippet = (params: Params) => `
  135. SENTRY_AUTO_INIT=false java -javaagent:sentry-opentelemetry-agent-${getPackageVersion(params, 'sentry.java.opentelemetry-agent', '8.0.0')}.jar -jar your-application.jar
  136. `;
  137. const getOpenTelemetryApplicationServerSnippet = (params: Params) => `
  138. JAVA_OPTS="$\{JAVA_OPTS} -javaagent:/somewhere/sentry-opentelemetry-agent-${getPackageVersion(params, 'sentry.java.opentelemetry-agent', '8.0.0')}.jar"
  139. `;
  140. const getJavaConfigSnippet = (params: Params) => `
  141. import io.sentry.spring${
  142. params.platformOptions.springVersion === SpringVersion.V6 ? '.jakarta' : ''
  143. }.EnableSentry;
  144. @EnableSentry(
  145. dsn = "${params.dsn.public}",
  146. // Add data like request headers and IP for users,
  147. // see https://docs.sentry.io/platforms/java/guides/spring/data-management/data-collected/ for more info
  148. sendDefaultPii = true
  149. )
  150. @Configuration
  151. class SentryConfiguration {
  152. }`;
  153. const getKotlinConfigSnippet = (params: Params) => `
  154. import io.sentry.spring${
  155. params.platformOptions.springVersion === SpringVersion.V6 ? '.jakarta' : ''
  156. }.EnableSentry
  157. import org.springframework.core.Ordered
  158. @EnableSentry(
  159. dsn = "${params.dsn.public}",
  160. // Add data like request headers and IP for users,
  161. // see https://docs.sentry.io/platforms/java/guides/spring/data-management/data-collected/ for more info
  162. sendDefaultPii = true,
  163. exceptionResolverOrder = Ordered.LOWEST_PRECEDENCE
  164. )`;
  165. const getJavaVerifySnippet = () => `
  166. import java.lang.Exception;
  167. import io.sentry.Sentry;
  168. try {
  169. throw new Exception("This is a test.");
  170. } catch (Exception e) {
  171. Sentry.captureException(e);
  172. }`;
  173. const getKotlinVerifySnippet = () => `
  174. import java.lang.Exception
  175. import io.sentry.Sentry
  176. try {
  177. throw Exception("This is a test.")
  178. } catch (e: Exception) {
  179. Sentry.captureException(e)
  180. }`;
  181. const getSentryPropertiesSnippet = (params: Params) =>
  182. `${
  183. params.isPerformanceSelected
  184. ? `
  185. traces-sample-rate=1.0`
  186. : ''
  187. }`;
  188. const onboarding: OnboardingConfig<PlatformOptions> = {
  189. introduction: () =>
  190. tct(
  191. "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].",
  192. {
  193. legacyIntegrationLink: (
  194. <ExternalLink href="https://docs.sentry.io/platforms/java/guides/spring/legacy/" />
  195. ),
  196. }
  197. ),
  198. install: (params: Params) => [
  199. {
  200. type: StepType.INSTALL,
  201. description: t(
  202. "Install Sentry's integration with Spring using %s:",
  203. params.platformOptions.packageManager === PackageManager.GRADLE
  204. ? 'Gradle'
  205. : 'Maven'
  206. ),
  207. configurations: [
  208. {
  209. description: (
  210. <p>
  211. {tct(
  212. '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.',
  213. {
  214. link: <Link to="/settings/auth-tokens/" />,
  215. }
  216. )}
  217. </p>
  218. ),
  219. language: 'bash',
  220. code: 'SENTRY_AUTH_TOKEN=___ORG_AUTH_TOKEN___',
  221. },
  222. ...(params.platformOptions.packageManager === PackageManager.GRADLE
  223. ? [
  224. {
  225. description: (
  226. <p>
  227. {tct(
  228. '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:',
  229. {
  230. code: <code />,
  231. link: (
  232. <ExternalLink href="https://github.com/getsentry/sentry-android-gradle-plugin" />
  233. ),
  234. }
  235. )}
  236. </p>
  237. ),
  238. language: 'groovy',
  239. code: getGradleInstallSnippet(params),
  240. },
  241. ]
  242. : []),
  243. ...(params.platformOptions.packageManager === PackageManager.MAVEN
  244. ? [
  245. {
  246. language: 'xml',
  247. description: (
  248. <p>
  249. {tct(
  250. 'The [link:Sentry Maven Plugin] automatically installs the Sentry SDK as well as available integrations for your dependencies. Add the following to your [code:pom.xml] file:',
  251. {
  252. code: <code />,
  253. link: (
  254. <ExternalLink href="https://github.com/getsentry/sentry-maven-plugin" />
  255. ),
  256. }
  257. )}
  258. </p>
  259. ),
  260. code: getMavenInstallSnippet(params),
  261. },
  262. ]
  263. : []),
  264. ...(params.platformOptions.opentelemetry === YesNo.YES
  265. ? [
  266. {
  267. description: tct(
  268. "When running your application, please add our [code:sentry-opentelemetry-agent] to the [code:java] command. In case you are using an application server to run your [code:.WAR] file, please add it to the [code:JAVA_OPTS] of your application server. You can download the latest version of the [code:sentry-opentelemetry-agent.jar] from [linkMC:MavenCentral]. It's also available as a [code:ZIP] containing the [code:JAR] used on this page on [linkGH:GitHub].",
  269. {
  270. code: <code />,
  271. linkMC: (
  272. <ExternalLink href="https://search.maven.org/artifact/io.sentry/sentry-opentelemetry-agent" />
  273. ),
  274. linkGH: (
  275. <ExternalLink href="https://github.com/getsentry/sentry-java/releases/" />
  276. ),
  277. }
  278. ),
  279. language: 'bash',
  280. code: getOpenTelemetryRunSnippet(params),
  281. },
  282. ]
  283. : []),
  284. ...(params.platformOptions.opentelemetry === YesNo.YES
  285. ? [
  286. {
  287. description: t(
  288. 'In case of an application server, adding the Agent might look more like the following:'
  289. ),
  290. language: 'bash',
  291. code: getOpenTelemetryApplicationServerSnippet(params),
  292. },
  293. ]
  294. : []),
  295. ],
  296. additionalInfo: (
  297. <p>
  298. {tct(
  299. 'If you prefer to manually upload your source code to Sentry, please refer to [link:Manually Uploading Source Context].',
  300. {
  301. link: (
  302. <ExternalLink href="https://docs.sentry.io/platforms/java/source-context/#manually-uploading-source-context" />
  303. ),
  304. }
  305. )}
  306. </p>
  307. ),
  308. },
  309. ],
  310. configure: (params: Params) => [
  311. {
  312. type: StepType.CONFIGURE,
  313. description: (
  314. <Fragment>
  315. {t("Configure Sentry as soon as possible in your application's lifecycle:")}
  316. <p>
  317. {tct(
  318. 'The [libraryName] library provides 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].',
  319. {
  320. libraryName: (
  321. <code>
  322. {params.platformOptions.springVersion === SpringVersion.V5
  323. ? 'sentry-spring'
  324. : 'sentry-spring-jakarta'}
  325. </code>
  326. ),
  327. codeEnableSentry: <code />,
  328. configurationLink: (
  329. <ExternalLink href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html" />
  330. ),
  331. springBootApplicationLink: (
  332. <ExternalLink href="https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/SpringBootApplication.html" />
  333. ),
  334. }
  335. )}
  336. </p>
  337. </Fragment>
  338. ),
  339. configurations: [
  340. {
  341. description: <h5>{t('Java')}</h5>,
  342. configurations: [
  343. {
  344. language: 'java',
  345. code: [
  346. {
  347. language: 'java',
  348. label: 'Java',
  349. value: 'java',
  350. code: getJavaConfigSnippet(params),
  351. },
  352. {
  353. language: 'kotlin',
  354. label: 'Kotlin',
  355. value: 'kotlin',
  356. code: getKotlinConfigSnippet(params),
  357. },
  358. ],
  359. },
  360. ],
  361. },
  362. ...(params.isPerformanceSelected
  363. ? [
  364. {
  365. type: StepType.CONFIGURE,
  366. description: tct(
  367. 'Add a [code:sentry.properties] file to enable Performance:',
  368. {
  369. code: <code />,
  370. }
  371. ),
  372. configurations: [
  373. {
  374. language: 'java',
  375. code: getSentryPropertiesSnippet(params),
  376. },
  377. ],
  378. },
  379. ]
  380. : []),
  381. ],
  382. },
  383. ],
  384. verify: () => [
  385. {
  386. type: StepType.VERIFY,
  387. description: t(
  388. 'Last, create an intentional error, so you can test that everything is working:'
  389. ),
  390. configurations: [
  391. {
  392. code: [
  393. {
  394. language: 'java',
  395. label: 'Java',
  396. value: 'java',
  397. code: getJavaVerifySnippet(),
  398. },
  399. {
  400. language: 'kotlin',
  401. label: 'Kotlin',
  402. value: 'kotlin',
  403. code: getKotlinVerifySnippet(),
  404. },
  405. ],
  406. },
  407. ],
  408. additionalInfo: (
  409. <Fragment>
  410. <p>
  411. {t(
  412. "If you're new to Sentry, use the email alert to access your account and complete a product tour."
  413. )}
  414. </p>
  415. <p>
  416. {t(
  417. "If you're an existing user and have disabled alerts, you won't receive this email."
  418. )}
  419. </p>
  420. </Fragment>
  421. ),
  422. },
  423. ],
  424. nextSteps: () => [
  425. {
  426. id: 'examples',
  427. name: t('Examples'),
  428. description: t('Check out our sample applications.'),
  429. link: 'https://github.com/getsentry/sentry-java/tree/main/sentry-samples',
  430. },
  431. ],
  432. };
  433. const docs: Docs<PlatformOptions> = {
  434. onboarding,
  435. platformOptions,
  436. crashReportOnboarding: feedbackOnboardingCrashApiJava,
  437. replayOnboardingJsLoader,
  438. feedbackOnboardingJsLoader,
  439. };
  440. export default docs;