|
| 1 | +# Creating a new SDK |
| 2 | + |
| 3 | +While each SDK (e.g. `@sentry/react` or `@sentry/nextjs`) is somewhat unique, we try to follow some general themes when |
| 4 | +creating a new SDK. |
| 5 | + |
| 6 | +## Types of SDKs |
| 7 | + |
| 8 | +Broadly speaking, there are three types of SDKs: |
| 9 | + |
| 10 | +1. Browser SDKs (e.g. `@sentry/react` or `@sentry/angular`) |
| 11 | +2. Server SDKs (e.g. `@sentry/bun` or `@sentry/node`) |
| 12 | +3. Meta SDKs (e.g. `@sentry/nextjs` or `@sentry/sveltekit`) - which cover both Browser & Server |
| 13 | + |
| 14 | +Depending on what type of SDK you are creating, you'll have to include different things. |
| 15 | + |
| 16 | +## General Guidelines |
| 17 | + |
| 18 | +As a rule of thumb, we should follow these two ideas: |
| 19 | + |
| 20 | +1. Whenever possible, instrumentation should work without (or with as little as possible) user configuration. |
| 21 | +2. Instrumentation should follow common patterns for a specific platform. No config is always preferred, but if config |
| 22 | + is unavoidable, it should feel as native as possible to users of the given framework. |
| 23 | + |
| 24 | +## 1. Browser SDKs |
| 25 | + |
| 26 | +A purely browser SDK generally should cover the following things: |
| 27 | + |
| 28 | +### 1a. Error Monitoring |
| 29 | + |
| 30 | +We have global error handlers out of the box. However, in many frameworks there are ways for users to capture errors |
| 31 | +too, which may lead to them not bubble up to our global handlers. Generally, the goal is that all errors are captured by |
| 32 | +Sentry. |
| 33 | + |
| 34 | +Either we should use some hook (e.g. `app.on('error')`) to capture exceptions, or provide composables (e.g. an error |
| 35 | +boundary component in React) that users can use in their app to ensure all errors are captured by Sentry. |
| 36 | + |
| 37 | +### 1b. Performance Monitoring |
| 38 | + |
| 39 | +#### Routing Instrumentation |
| 40 | + |
| 41 | +At a minimum, each browser SDK should have **Routing Instrumentation**. |
| 42 | + |
| 43 | +While we have a default `browserTracingIntegration`, this has no access to a router, and is thus only based on URLs. We |
| 44 | +should strive to provide a custom `browserTracingIntegration` for SDKs that can leverage the router & routing |
| 45 | +information. |
| 46 | + |
| 47 | +Ideally, this means that we can emit pageload & navigation spans with parametrized route names instead of full URLs. |
| 48 | + |
| 49 | +Some of the following concepts may be relevant to your SDK: |
| 50 | + |
| 51 | +- **Redirects**: If possible, we want to skip redirects. This means that if a user navigates to `/`, and this redirects |
| 52 | + the user internally to `/dashboard`, we only want to capture a single `/` navigation/pageload. |
| 53 | +- **Route Params**: Routes should be parametrized, which means that instead of `/users/123` we want to capture |
| 54 | + `/users/:id` or simmilar. |
| 55 | +- **Query Params**: Query params should generally be removed from the route. |
| 56 | + |
| 57 | +#### Component Tracking |
| 58 | + |
| 59 | +Additionally, depending on the framework we may also have **Component Tracking**. We may track the duration of component |
| 60 | +renders and similar things. These are stretch goals, though, and do not need to be part of an MVP. |
| 61 | + |
| 62 | +## 2. Server SDKs |
| 63 | + |
| 64 | +A purely server SDK generally should cover the following things: |
| 65 | + |
| 66 | +### 2a. Error Monitoring |
| 67 | + |
| 68 | +We have global error handlers out of the box. However, in many frameworks there are ways for users to capture errors |
| 69 | +too, which may lead to them not bubbling up to our global handlers. Generally, the goal is that all errors are captured |
| 70 | +by Sentry. |
| 71 | + |
| 72 | +Either we should use some hook (e.g. `app.on('error')`) to capture exceptions, or provide composables (e.g. |
| 73 | +`setupFastifyErrorHandler(app)`) that user can call. |
| 74 | + |
| 75 | +### 2b. Performance Monitoring |
| 76 | + |
| 77 | +#### Routing Instrumentation |
| 78 | + |
| 79 | +At a minimum, each Node SDK should have **Routing Instrumentation**. |
| 80 | + |
| 81 | +Most SDKs that build on top of `@sentry/node` should automatically have basic `http.server` spans emitted for incoming |
| 82 | +requests by the `httpIntegration`. However, these spans do not contain any routing information (e.g. a `http.route` |
| 83 | +attribute). A server SDK should make sure to add route information to these spans. |
| 84 | + |
| 85 | +If there are things that should be captured in spans that are not covered by `httpIntegration`, we may need to write our |
| 86 | +own instrumentation to capture `http.server` spans. |
| 87 | + |
| 88 | +Some of the following concepts may be relevant to your SDK: |
| 89 | + |
| 90 | +- **Route Params**: Routes should be parametrized, which means that instead of `/users/123` we want to capture |
| 91 | + `/users/:id` or simmilar. |
| 92 | +- **Query Params**: Query params should generally be removed from the route. |
| 93 | + |
| 94 | +#### Middleware Tracking |
| 95 | + |
| 96 | +Additionally, Node SDKs may also do **Middleware Tracking**. If possible, we may want to instrument middlewares, and |
| 97 | +create spans for them. These are stretch goals, though, and do not need to be part of an MVP. |
| 98 | + |
| 99 | +### 2c. OPTIONAL: Additional features |
| 100 | + |
| 101 | +We may also want to instrument additional features, if applicable, including: |
| 102 | + |
| 103 | +- Automatic cron instrumentation |
| 104 | +- [Cache module](https://docs.sentry.io/product/insights/caches/) - See |
| 105 | + [Instrument Caches](https://docs.sentry.io/platforms/javascript/guides/connect/tracing/instrumentation/custom-instrumentation/caches-module/) |
| 106 | +- [Queue module](https://docs.sentry.io/product/insights/queue-monitoring/) - See |
| 107 | + [Instrument Queues](https://docs.sentry.io/platforms/javascript/guides/connect/tracing/instrumentation/custom-instrumentation/queues-module/) |
| 108 | + |
| 109 | +## 3. Meta SDKs |
| 110 | + |
| 111 | +Meta SDKs should contain both the things pointed out in 1. and 2, _PLUS_: |
| 112 | + |
| 113 | +### 3a. Connected Traces |
| 114 | + |
| 115 | +Traces from SSR (server side) should be continued in the client side (browser). Usually this means that we have to |
| 116 | +inject the trace data as `<meta>` tags into the rendered HTML pages. If possible, we should do that automatically. If |
| 117 | +there is no way to do that automatically, we should provide a utility for users to do it themselves. |
| 118 | + |
| 119 | +### 3b. Instrumented Server Components / API Routes / etc. |
| 120 | + |
| 121 | +Depending on the framework, we should instrument all the pieces that exist in this framework. This includes capturing |
| 122 | +errors & spans for things like: |
| 123 | + |
| 124 | +- Server Components |
| 125 | +- API Routes |
| 126 | +- Layouts |
| 127 | +- etc. |
| 128 | + |
| 129 | +When possible, we should auto-capture this. If not possible, we should provide utilities for users to do this |
| 130 | +themselves. |
| 131 | + |
| 132 | +### 3c. Bundler Integration / Source Maps |
| 133 | + |
| 134 | +When possible, Meta SDKs should integrate with the used bundler. For example, SvelteKit uses Vite, so we should |
| 135 | +automatically set up `@sentry/vite-plugin` for the user. At a minimum, we want to enable source maps upload for the meta |
| 136 | +SDK, but this may also include automated release creation and other bundler features. |
| 137 | + |
| 138 | +We _should not_ expose the bundler plugin config directly, because this means that we cannot bump the underlying bundler |
| 139 | +plugin version in a major way (because the bundler plugin config becomes public API of the meta SDK). Instead, we should |
| 140 | +provide an abstraction layer of options that we expose on top of that. |
| 141 | + |
| 142 | +### 3d. Alternate JS Runtimes |
| 143 | + |
| 144 | +We generally want to support Node runtimes for the server. However, sometimes there may be alternate runtimes that may |
| 145 | +be supported, e.g. Cloudflare Workers or Vercel Edge Functions. We generally do not need to support these in an MVP, but |
| 146 | +may decide to support them later. |
0 commit comments