sentry-plugin.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import { SentryModule } from '@sentry/nestjs/setup';
  2. import { PluginCommonModule, VendurePlugin } from '@vendure/core';
  3. import { SentryAdminTestResolver } from './api/admin-test.resolver';
  4. import { testApiExtensions } from './api/api-extensions';
  5. import { ErrorTestService } from './api/error-test.service';
  6. import { SENTRY_PLUGIN_OPTIONS } from './constants';
  7. import { SentryErrorHandlerStrategy } from './sentry-error-handler-strategy';
  8. import { SentryService } from './sentry.service';
  9. import { SentryPluginOptions } from './types';
  10. const SentryOptionsProvider = {
  11. provide: SENTRY_PLUGIN_OPTIONS,
  12. useFactory: () => SentryPlugin.options,
  13. };
  14. /**
  15. * @description
  16. * This plugin integrates the [Sentry](https://sentry.io) error tracking & performance monitoring
  17. * service with your Vendure server. In addition to capturing errors, it also provides built-in
  18. * support for [tracing](https://docs.sentry.io/product/sentry-basics/concepts/tracing/) as well as
  19. * enriching your Sentry events with additional context about the request.
  20. *
  21. * :::info
  22. * This documentation applies from v3.5.0 of the plugin, which works differently to previous
  23. * versions. Documentation for prior versions can
  24. * be found [here](https://github.com/vendure-ecommerce/vendure/blob/1bb9cf8ca1584bce026ccc82f33f866b766ef47d/packages/sentry-plugin/src/sentry-plugin.ts).
  25. * :::
  26. *
  27. * ## Pre-requisites
  28. *
  29. * This plugin depends on access to Sentry, which can be self-hosted or used as a cloud service.
  30. *
  31. * If using the hosted SaaS option, you must have a Sentry account and a project set up ([sign up here](https://sentry.io/signup/)). When setting up your project,
  32. * select the "Node.js" platform and no framework.
  33. *
  34. * Once set up, you will be given a [Data Source Name (DSN)](https://docs.sentry.io/product/sentry-basics/concepts/dsn-explainer/)
  35. * which you will need to provide to the plugin.
  36. *
  37. * ## Installation
  38. *
  39. * ```sh
  40. * npm install --save \@vendure/sentry-plugin
  41. * ```
  42. *
  43. * ## Environment Variables
  44. *
  45. * The following environment variables are used to control how the Sentry
  46. * integration behaves:
  47. *
  48. * - `SENTRY_DSN`: (required) Sentry Data Source Name
  49. * - `SENTRY_TRACES_SAMPLE_RATE`: Number between 0 and 1
  50. * - `SENTRY_PROFILES_SAMPLE_RATE`: Number between 0 and 1
  51. * - `SENTRY_ENABLE_LOGS`: Boolean. Captures calls to the console API as logs in Sentry. Default `false`
  52. * - `SENTRY_CAPTURE_LOG_LEVELS`: 'debug' | 'info' | 'warn' | 'error' | 'log' | 'assert' | 'trace'
  53. *
  54. * ## Configuration
  55. *
  56. * Setting up the Sentry plugin requires two steps:
  57. *
  58. * ### Step 1: Preload the Sentry instrument file
  59. *
  60. * Make sure the `SENTRY_DSN` environment variable is defined.
  61. *
  62. * The Sentry SDK must be initialized before your application starts. This is done by preloading
  63. * the instrument file when starting your Vendure server:
  64. *
  65. * ```sh
  66. * node --import \@vendure/sentry-plugin/instrument ./dist/index.js
  67. * ```
  68. *
  69. * Or if using TypeScript directly with tsx:
  70. *
  71. * ```sh
  72. * tsx --import \@vendure/sentry-plugin/instrument ./src/index.ts
  73. * ```
  74. *
  75. * ### Step 2: Add the SentryPlugin to your Vendure config
  76. *
  77. * ```ts
  78. * import { VendureConfig } from '\@vendure/core';
  79. * import { SentryPlugin } from '\@vendure/sentry-plugin';
  80. *
  81. * export const config: VendureConfig = {
  82. * // ...
  83. * plugins: [
  84. * // ...
  85. * // highlight-start
  86. * SentryPlugin.init({
  87. * // Optional configuration
  88. * includeErrorTestMutation: true,
  89. * }),
  90. * // highlight-end
  91. * ],
  92. * };
  93. *```
  94. *
  95. * ## Tracing
  96. *
  97. * This plugin includes built-in support for [tracing](https://docs.sentry.io/product/sentry-basics/concepts/tracing/), which allows you to see the performance of your.
  98. * To enable tracing, preload the instrument file as described in [Step 1](#step-1-preload-the-sentry-instrument-file).
  99. * This ensures that the Sentry SDK is initialized before any other code is executed.
  100. *
  101. * You can also set the `tracesSampleRate` and `profilesSampleRate` options to control the sample rate for
  102. * tracing and profiling, with the following environment variables:
  103. *
  104. * - `SENTRY_TRACES_SAMPLE_RATE`
  105. * - `SENTRY_PROFILES_SAMPLE_RATE`
  106. *
  107. * The sample rate for tracing should be between 0 and 1. The sample rate for profiling should be between 0 and 1.
  108. *
  109. * By default, both are set to `undefined`, which means that tracing and profiling are disabled.
  110. *
  111. * ## Instrumenting your own code
  112. *
  113. * You may want to add your own custom spans to your code. To do so, you can use the `Sentry` object
  114. * from the `\@sentry/node` package. For example:
  115. *
  116. * ```ts
  117. * import * as Sentry from "\@sentry/node";
  118. *
  119. * export class MyService {
  120. * async myMethod() {
  121. * Sentry.setContext('My Custom Context,{
  122. * key: 'value',
  123. * });
  124. * }
  125. * }
  126. * ```
  127. *
  128. * ## Error test mutation
  129. *
  130. * To test whether your Sentry configuration is working correctly, you can set the `includeErrorTestMutation` option to `true`. This will add a mutation to the Admin API
  131. * which will throw an error of the type specified in the `errorType` argument. For example:
  132. *
  133. * ```graphql
  134. * mutation CreateTestError {
  135. * createTestError(errorType: DATABASE_ERROR)
  136. * }
  137. * ```
  138. *
  139. * You should then be able to see the error in your Sentry dashboard (it may take a couple of minutes to appear).
  140. *
  141. * @docsCategory core plugins/SentryPlugin
  142. */
  143. @VendurePlugin({
  144. imports: [PluginCommonModule],
  145. providers: [SentryOptionsProvider, SentryService, ErrorTestService],
  146. configuration: config => {
  147. config.systemOptions.errorHandlers.push(new SentryErrorHandlerStrategy());
  148. config.plugins.push(SentryModule.forRoot());
  149. return config;
  150. },
  151. adminApiExtensions: {
  152. schema: () => (SentryPlugin.options.includeErrorTestMutation ? testApiExtensions : undefined),
  153. resolvers: () => (SentryPlugin.options.includeErrorTestMutation ? [SentryAdminTestResolver] : []),
  154. },
  155. exports: [SentryService],
  156. compatibility: '^3.0.0',
  157. })
  158. export class SentryPlugin {
  159. static options: SentryPluginOptions = {} as any;
  160. static init(options?: SentryPluginOptions) {
  161. this.options = options ?? {};
  162. return this;
  163. }
  164. }