-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
docs: Add docs about creating a new SDK #12560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
# Creating a new SDK | ||
|
||
While each SDK (e.g. `@sentry/react` or `@sentry/nextjs`) is somewhat unique, we try to follow some general themes when | ||
creating a new SDK. | ||
|
||
## Types of SDKs | ||
|
||
Broadly speaking, there are three types of SDKs: | ||
|
||
1. Browser SDKs (e.g. `@sentry/react` or `@sentry/angular`) | ||
2. Server SDKs (e.g. `@sentry/bun` or `@sentry/node`) | ||
3. Meta SDKs (e.g. `@sentry/nextjs` or `@sentry/sveltekit`) - which cover both Browser & Server | ||
|
||
Depending on what type of SDK you are creating, you'll have to include different things. | ||
|
||
## General Guidelines | ||
|
||
As a rule of thumb, we should follow these two ideas: | ||
|
||
1. Whenever possible, instrumentation should work without (or with as little as possible) user configuration. | ||
2. Instrumentation should follow common patterns for a specific platform. No config is always preferred, but if config | ||
is unavoidable, it should feel as native as possible to users of the given framework. | ||
|
||
## 1. Browser SDKs | ||
|
||
A purely browser SDK generally should cover the following things: | ||
|
||
### 1a. Error Monitoring | ||
|
||
We have global error handlers out of the box. However, in many frameworks there are ways for users to capture errors | ||
too, which may lead to them not bubble up to our global handlers. Generally, the goal is that all errors are captured by | ||
Sentry. | ||
|
||
Either we should use some hook (e.g. `app.on('error')`) to capture exceptions, or provide composables (e.g. an error | ||
boundary component in React) that users can use in their app to ensure all errors are captured by Sentry. | ||
|
||
### 1b. Performance Monitoring | ||
|
||
#### Routing Instrumentation | ||
|
||
At a minimum, each browser SDK should have **Routing Instrumentation**. | ||
|
||
While we have a default `browserTracingIntegration`, this has no access to a router, and is thus only based on URLs. We | ||
should strive to provide a custom `browserTracingIntegration` for SDKs that can leverage the router & routing | ||
information. | ||
|
||
Ideally, this means that we can emit pageload & navigation spans with parametrized route names instead of full URLs. | ||
mydea marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Some of the following concepts may be relevant to your SDK: | ||
|
||
- **Redirects**: If possible, we want to skip redirects. This means that if a user navigates to `/`, and this redirects | ||
the user internally to `/dashboard`, we only want to capture a single `/` navigation/pageload. | ||
- **Route Params**: Routes should be parametrized, which means that instead of `/users/123` we want to capture | ||
`/users/:id` or simmilar. | ||
- **Query Params**: Query params should generally be removed from the route. | ||
|
||
#### Component Tracking | ||
|
||
Additionally, depending on the framework we may also have **Component Tracking**. We may track the duration of component | ||
renders and similar things. These are stretch goals, though, and do not need to be part of an MVP. | ||
|
||
## 2. Server SDKs | ||
|
||
A purely server SDK generally should cover the following things: | ||
|
||
### 2a. Error Monitoring | ||
|
||
We have global error handlers out of the box. However, in many frameworks there are ways for users to capture errors | ||
too, which may lead to them not bubbling up to our global handlers. Generally, the goal is that all errors are captured | ||
by Sentry. | ||
|
||
Either we should use some hook (e.g. `app.on('error')`) to capture exceptions, or provide composables (e.g. | ||
`setupFastifyErrorHandler(app)`) that user can call. | ||
|
||
### 2b. Performance Monitoring | ||
|
||
#### Routing Instrumentation | ||
|
||
At a minimum, each Node SDK should have **Routing Instrumentation**. | ||
|
||
Most SDKs that build on top of `@sentry/node` should automatically have basic `http.server` spans emitted for incoming | ||
requests by the `httpIntegration`. However, these spans do not contain any routing information (e.g. a `http.route` | ||
attribute). A server SDK should make sure to add route information to these spans. | ||
|
||
If there are things that should be captured in spans that are not covered by `httpIntegration`, we may need to write our | ||
own instrumentation to capture `http.server` spans. | ||
|
||
Some of the following concepts may be relevant to your SDK: | ||
|
||
- **Route Params**: Routes should be parametrized, which means that instead of `/users/123` we want to capture | ||
`/users/:id` or simmilar. | ||
- **Query Params**: Query params should generally be removed from the route. | ||
|
||
#### Middleware Tracking | ||
|
||
Additionally, Node SDKs may also do **Middleware Tracking**. If possible, we may want to instrument middlewares, and | ||
create spans for them. These are stretch goals, though, and do not need to be part of an MVP. | ||
|
||
### 2c. OPTIONAL: Additional features | ||
|
||
We may also want to instrument additional features, if applicable, including: | ||
|
||
- Automatic cron instrumentation | ||
- [Cache module](https://docs.sentry.io/product/insights/caches/) - See | ||
[Instrument Caches](https://docs.sentry.io/platforms/javascript/guides/connect/tracing/instrumentation/custom-instrumentation/caches-module/) | ||
- [Queue module](https://docs.sentry.io/product/insights/queue-monitoring/) - See | ||
[Instrument Queues](https://docs.sentry.io/platforms/javascript/guides/connect/tracing/instrumentation/custom-instrumentation/queues-module/) | ||
|
||
## 3. Meta SDKs | ||
|
||
Meta SDKs should contain both the things pointed out in 1. and 2, _PLUS_: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should include a note about source maps uploading and multiple JS runtimes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added notes on this! |
||
|
||
### 3a. Connected Traces | ||
|
||
Traces from SSR (server side) should be continued in the client side (browser). Usually this means that we have to | ||
inject the trace data as `<meta>` tags into the rendered HTML pages. If possible, we should do that automatically. If | ||
there is no way to do that automatically, we should provide a utility for users to do it themselves. | ||
|
||
### 3b. Instrumented Server Components / API Routes / etc. | ||
|
||
Depending on the framework, we should instrument all the pieces that exist in this framework. This includes capturing | ||
errors & spans for things like: | ||
|
||
- Server Components | ||
- API Routes | ||
- Layouts | ||
- etc. | ||
|
||
When possible, we should auto-capture this. If not possible, we should provide utilities for users to do this | ||
themselves. | ||
|
||
### 3c. Bundler Integration / Source Maps | ||
|
||
When possible, Meta SDKs should integrate with the used bundler. For example, SvelteKit uses Vite, so we should | ||
automatically set up `@sentry/vite-plugin` for the user. At a minimum, we want to enable source maps upload for the meta | ||
SDK, but this may also include automated release creation and other bundler features. | ||
|
||
We _should not_ expose the bundler plugin config directly, because this means that we cannot bump the underlying bundler | ||
plugin version in a major way (because the bundler plugin config becomes public API of the meta SDK). Instead, we should | ||
provide an abstraction layer of options that we expose on top of that. | ||
|
||
### 3d. Alternate JS Runtimes | ||
|
||
We generally want to support Node runtimes for the server. However, sometimes there may be alternate runtimes that may | ||
be supported, e.g. Cloudflare Workers or Vercel Edge Functions. We generally do not need to support these in an MVP, but | ||
may decide to support them later. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.