Skip to content

Commit d9bdc79

Browse files
authored
Guide towards v9 for ESM OTEL setups (#11974)
1 parent ee0ba5d commit d9bdc79

File tree

3 files changed

+74
-22
lines changed

3 files changed

+74
-22
lines changed

docs/platforms/javascript/common/install/esm.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ Sentry.init({
7575
});
7676
```
7777

78+
{/* TODO(v9): This will become the default behavior and registerEsmLoaderHooks will no longer accept an object. So I guess we should remove this section when v9 ships. */}
79+
7880
If you are starting Sentry via `--import`, you can instruct `import-in-the-middle`
7981
to only wrap packages that Sentry specifically instruments. To do this, you can
8082
set the `onlyIncludeInstrumentedModules` to `true`:

docs/platforms/javascript/common/opentelemetry/custom-setup.mdx

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ notSupported:
2323
sidebar_order: 0
2424
---
2525

26+
<Note>
27+
28+
Use this guide when you already have a completely custom OpenTelemetry setup or when you intend to add a custom OpenTelemetry setup next to the Sentry SDK.
29+
30+
If you are looking to simply add individual OpenTelemetry instrumentation to your Sentry setup, you should read <PlatformLink to="/opentelemetry/using-opentelemetry-apis/#adding-additional-opentelemetry-instrumentation">Adding Additional OpenTelemetry Instrumentation</PlatformLink> instead.
31+
32+
</Note>
33+
2634
To use an existing OpenTelemetry setup, set `skipOpenTelemetrySetup: true` in your `init({})` config, then set up all the components that Sentry needs yourself. Finish by installing `@sentry/opentelemetry` and adding the following:
2735

2836
```javascript
@@ -71,7 +79,6 @@ Make sure that all [Required OpenTelemetry Instrumentation](./#required-instrume
7179

7280
If you have a custom OpenTelemetry setup and only want to use Sentry for error monitoring, you can skip adding the `SentrySpanProcessor`. You'll still need to add the `SentryContextManager`, `SentryPropagator`, and `SentrySampler` to your setup even if you don't want to send any tracing data to Sentry. Read on to learn why this is needed.
7381

74-
7582
In order for the Sentry SDK to work as expected, and for it to be in sync with OpenTelemetry, we need a few components to be in place.
7683

7784
**Components needed for Sentry to work correctly:**
@@ -86,7 +93,13 @@ In order for the Sentry SDK to work as expected, and for it to be in sync with O
8693
- **SentrySpanProcessor**: Ensures that spans are correctly sent to Sentry.
8794

8895
<Note>
89-
Trace propagation is needed for Sentry to automatically connect services together. (For example, if you want to connect the frontend and backend, or different backend services.) This makes it possible to see related errors across services. <PlatformLink to="/tracing/trace-propagation">Learn more about Trace Propagation.</PlatformLink>
96+
Trace propagation is needed for Sentry to automatically connect services
97+
together. (For example, if you want to connect the frontend and backend, or
98+
different backend services.) This makes it possible to see related errors
99+
across services.{" "}
100+
<PlatformLink to="/tracing/trace-propagation">
101+
Learn more about Trace Propagation.
102+
</PlatformLink>
90103
</Note>
91104

92105
## Required Instrumentation
@@ -95,13 +108,24 @@ By default, Sentry will register OpenTelemetry instrumentation to automatically
95108

96109
If tracing is not enabled (no `tracesSampleRate` is defined in the SDK configuration), only a minimal amount of OpenTelemetry instrumentation will be registered. This includes the following:
97110

111+
{/* prettier-ignore-start */}
112+
98113
- <PlatformLink to="/configuration/integrations/http/">httpIntegration</PlatformLink> registers [@opentelemetry/instrumentation-http](https://www.npmjs.com/package/@opentelemetry/instrumentation-http)
99114
- <PlatformLink to="/configuration/integrations/nodefetch/">nativeNodeFetchIntegration</PlatformLink> registers [opentelemetry-instrumentation-fetch-node](https://www.npmjs.com/package/opentelemetry-instrumentation-fetch-node)
100115

101-
<PlatformSection notSupported={['javascript.aws-lambda', 'javascript.gcp-functions']}>
116+
{/* prettier-ignore-end */}
117+
118+
<PlatformSection
119+
notSupported={["javascript.aws-lambda", "javascript.gcp-functions"]}
120+
>
102121
<Note>
103-
If tracing is not enabled, performance instrumentations will not be registered but they will still be included in the bundle. If you
104-
want to reduce the bundle size or used dependencies, you can also <PlatformLink to="/configuration/tree-shaking/#setting-up-sentry-without-performance-integrations">Set up Sentry without Performance Integrations</PlatformLink>.
122+
If tracing is not enabled, performance instrumentations will not be
123+
registered but they will still be included in the bundle. If you want to
124+
reduce the bundle size or used dependencies, you can also{" "}
125+
<PlatformLink to="/configuration/tree-shaking/#setting-up-sentry-without-performance-integrations">
126+
Set up Sentry without Performance Integrations
127+
</PlatformLink>
128+
.
105129
</Note>
106130
</PlatformSection>
107131

@@ -140,7 +164,7 @@ const {
140164
SentrySpanProcessor,
141165
SentryPropagator,
142166
SentrySampler,
143-
wrapSamplingDecision
167+
wrapSamplingDecision,
144168
} = require("@sentry/opentelemetry");
145169

146170
// implements Sampler from "@opentelemetry/sdk-trace-node"
@@ -180,11 +204,14 @@ const provider = new NodeTracerProvider({
180204
// Validate that the setup is correct
181205
Sentry.validateOpenTelemetrySetup();
182206
```
207+
183208
## ESM Loaders
184209

185-
If your application is running in ESM (`import`/`export` syntax), OpenTelemetry requires a [special setup](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md) to work correctly.
186-
The Sentry SDK will automatically detect if your application is running in ESM mode and by default [register a loader hook](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm) itself.
187-
If you are also registering a loader hook, you need to disable Sentry's loader hook:
210+
If your application is running in ESM (`import`/`export` syntax), OpenTelemetry requires you to set up _ESM loader hooks_.
211+
212+
The Sentry SDK will automatically register ESM loader hooks by default.
213+
However, if you have your own OpenTelemetry setup, it is recommended to configure the Sentry SDK to not register these hooks and instead register them yourself.
214+
You can do so by setting `registerEsmLoaderHooks` to `false` and [setting up ESM loader hooks](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm):
188215

189216
```javascript
190217
Sentry.init({
@@ -193,15 +220,30 @@ Sentry.init({
193220
});
194221
```
195222

196-
<Note>
223+
<Alert level="info" title="Why is it recommended to register loader hooks yourself?">
197224

198-
Registering loader hooks multiple times might result in duplicated spans being created.
199-
[More details.](https://github.com/getsentry/sentry-javascript/issues/14065#issuecomment-2435546961)
225+
It is recommended registering your own ESM loader hooks when you have a complete custom OpenTelemetry setup, first and foremost because it makes the most sense architecturally.
226+
You likely went through the effort to set up OpenTelemetry by itself and now you want to add Sentry to your application without messing with your OpenTelemetry setup.
200227

201-
</Note>
228+
Additionally, there are a few pitfalls that can very simply be avoided by registering your own hooks:
229+
230+
- Registering loader hooks multiple times might result in duplicated spans being created. [More details.](https://github.com/getsentry/sentry-javascript/issues/14065#issuecomment-2435546961)
231+
- OpenTelemetry instrumentation in ESM is very sensitive as to _when_ it is added relative to _when_ the loader hooks are registered.
232+
The control over this should stay with the owner of the OpenTelemetry setup and not the Sentry SDK.
233+
234+
</Alert>
202235

203-
Alternatively, you can also use Sentry's loader hook and remove your own loader hook registration code.
204-
In this case, ensure that you initialize the Sentry SDK in its own file and load this file prior to your application via `node --import instrument.mjs your-app.mjs`.
205-
<PlatformSection supported={['javascript.node']}>
206-
<PlatformLink to="/install">Learn more about ESM installation methods.</PlatformLink>
236+
<PlatformSection
237+
notSupported={[
238+
"javascript.nextjs",
239+
"javascript.aws-lambda",
240+
"javascript.nuxt",
241+
"javascript.solidstart",
242+
]}
243+
>
244+
<PlatformCategorySection supported={["server", "serverles"]}>
245+
<PlatformLink to="/install">
246+
Learn more about ESM installation methods.
247+
</PlatformLink>
248+
</PlatformCategorySection>
207249
</PlatformSection>

docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Sentry supports OpenTelemetry APIs out of the box. Any spans started using OpenT
2929

3030
While the Sentry SDK includes some OpenTelemetry instrumentation out of the box, you may want to add additional instrumentation to your application. This can be done by registering the instrumentation through OpenTelemetry like the example below:
3131

32-
```javascript
32+
```javascript {12-13}
3333
const Sentry = require("@sentry/node");
3434
const {
3535
GenericPoolInstrumentation,
@@ -40,13 +40,21 @@ Sentry.init({
4040

4141
// The SentrySampler will use this to determine which traces to sample
4242
tracesSampleRate: 1.0,
43-
});
4443

45-
// Afterwards, you can add additional instrumentation:
46-
Sentry.addOpenTelemetryInstrumentation(new GenericPoolInstrumentation());
44+
// Add additional OpenTelemetry instrumentation:
45+
openTelemetryInstrumentations: [new GenericPoolInstrumentation()],
46+
});
4747
```
4848

49-
Any instrumentation added like this or via `registerInstrumentations()` from `@opentelemetry/instrumentation` will be picked up by Sentry.
49+
<Note>
50+
It is possible to add instrumentations via `registerInstrumentations()` from
51+
`@opentelemetry/instrumentation`. However, with ESM (`import`/`export` syntax)
52+
you need to be careful to do so before importing any modules that should be
53+
instrumented.
54+
55+
As a rule of thumb, `registerInstrumentations()` should be called right after, and in the same context as registering <PlatformLink to="/opentelemetry/custom-setup/#esm-loaders">ESM Loaders</PlatformLink>.
56+
57+
</Note>
5058

5159
## Using an OpenTelemetry Tracer
5260

0 commit comments

Comments
 (0)