asgi.tsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import {Fragment} from 'react';
  2. import ExternalLink from 'sentry/components/links/externalLink';
  3. import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
  4. import {
  5. type Docs,
  6. DocsPageLocation,
  7. type DocsParams,
  8. type OnboardingConfig,
  9. } from 'sentry/components/onboarding/gettingStartedDoc/types';
  10. import {
  11. AlternativeConfiguration,
  12. crashReportOnboardingPython,
  13. } from 'sentry/gettingStartedDocs/python/python';
  14. import {t, tct} from 'sentry/locale';
  15. type Params = DocsParams;
  16. const getInstallSnippet = () => `pip install --upgrade sentry-sdk`;
  17. const getSdkSetupSnippet = (params: Params) => `
  18. import sentry_sdk
  19. from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
  20. from myapp import asgi_app
  21. sentry_sdk.init(
  22. dsn="${params.dsn.public}",
  23. # Add data like request headers and IP for users,
  24. # see https://docs.sentry.io/platforms/python/data-management/data-collected/ for more info
  25. send_default_pii=True,${
  26. params.isPerformanceSelected
  27. ? `
  28. # Set traces_sample_rate to 1.0 to capture 100%
  29. # of transactions for tracing.
  30. traces_sample_rate=1.0,`
  31. : ''
  32. }${
  33. params.isProfilingSelected &&
  34. params.profilingOptions?.defaultProfilingMode !== 'continuous'
  35. ? `
  36. # Set profiles_sample_rate to 1.0 to profile 100%
  37. # of sampled transactions.
  38. # We recommend adjusting this value in production.
  39. profiles_sample_rate=1.0,`
  40. : params.isProfilingSelected &&
  41. params.profilingOptions?.defaultProfilingMode === 'continuous'
  42. ? `
  43. _experiments={
  44. # Set continuous_profiling_auto_start to True
  45. # to automatically start the profiler on when
  46. # possible.
  47. "continuous_profiling_auto_start": True,
  48. },`
  49. : ''
  50. }
  51. )
  52. asgi_app = SentryAsgiMiddleware(asgi_app)`;
  53. const getVerifySnippet = () => `
  54. import sentry_sdk
  55. from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
  56. from myapp import asgi_app
  57. sentry_sdk.init(...) # same as above
  58. def app(scope):
  59. async def get_body():
  60. return f"The number is: {1/0}" # raises an error!
  61. async def asgi(receive, send):
  62. await send(
  63. {
  64. "type": "http.response.start",
  65. "status": 200,
  66. "headers": [[b"content-type", b"text/plain"]],
  67. }
  68. )
  69. await send({"type": "http.response.body", "body": await get_body()})
  70. return asgi
  71. app = SentryAsgiMiddleware(app)`;
  72. const onboarding: OnboardingConfig = {
  73. introduction: () =>
  74. tct(
  75. 'The ASGI middleware can be used to instrument any bare bones ASGI application. If you have a ASGI based web framework (like FastAPI, Starlette, or others), please use the specific integration for the framework.',
  76. {
  77. link: <ExternalLink href="https://asgi.readthedocs.io/en/latest/" />,
  78. }
  79. ),
  80. install: (params: Params) => [
  81. {
  82. type: StepType.INSTALL,
  83. description: tct('Install [code:sentry-sdk] from PyPI:', {
  84. code: <code />,
  85. }),
  86. configurations: [
  87. {
  88. description:
  89. params.docsLocation === DocsPageLocation.PROFILING_PAGE
  90. ? tct(
  91. 'You need a minimum version [code:1.18.0] of the [code:sentry-python] SDK for the profiling feature.',
  92. {
  93. code: <code />,
  94. }
  95. )
  96. : undefined,
  97. language: 'bash',
  98. code: getInstallSnippet(),
  99. },
  100. ],
  101. },
  102. ],
  103. configure: (params: Params) => [
  104. {
  105. type: StepType.CONFIGURE,
  106. description: tct('Wrap your ASGI application with [code: SentryAsgiMiddleware]:', {
  107. code: <code />,
  108. }),
  109. configurations: [
  110. {
  111. language: 'python',
  112. code: getSdkSetupSnippet(params),
  113. },
  114. ],
  115. additionalInfo: (
  116. <Fragment>
  117. {params.isProfilingSelected &&
  118. params.profilingOptions?.defaultProfilingMode === 'continuous' && (
  119. <Fragment>
  120. <AlternativeConfiguration />
  121. <br />
  122. </Fragment>
  123. )}
  124. {t('The middleware supports both ASGI 2 and ASGI 3 transparently.')}
  125. </Fragment>
  126. ),
  127. },
  128. ],
  129. verify: () => [
  130. {
  131. type: StepType.VERIFY,
  132. description: t('To verify that everything is working trigger an error on purpose:'),
  133. configurations: [
  134. {
  135. language: 'python',
  136. code: getVerifySnippet(),
  137. },
  138. ],
  139. additionalInfo: (
  140. <span>
  141. <p>
  142. {tct(
  143. 'Run your ASGI app with uvicorn ([code:uvicorn main:app --port 8000]) and point your browser to [link:http://localhost:8000]. A transaction in the Performance section of Sentry will be created.',
  144. {
  145. code: <code />,
  146. link: <ExternalLink href="http://localhost:8000" />,
  147. }
  148. )}
  149. </p>
  150. <p>
  151. {t(
  152. 'Additionally, an error event will be sent to Sentry and will be connected to the transaction.'
  153. )}
  154. </p>
  155. <p>{t('It takes a couple of moments for the data to appear in Sentry.')}</p>
  156. </span>
  157. ),
  158. },
  159. ],
  160. };
  161. const docs: Docs = {
  162. onboarding,
  163. crashReportOnboarding: crashReportOnboardingPython,
  164. };
  165. export default docs;