Skip to content

Commit 4cf4fea

Browse files
authored
docs(bun): Add ESM/CJS and Bun-specific OTel docs (#14594)
## DESCRIBE YOUR PR This adds OTel documentation for bun. First, I added CJS/ESM snippets for all snippets to make it more inclusive. For Bun, the biggest difference are the imports (`@sentry/bun`) and this snippet: ```js integrations: (integrations) => integrations // Filter out the BunServer integration to avoid emitting spans from there .filter((i) => i.name !== "Http" && i.name !== "BunServer") // Add the httpIntegration again and disable emitting spans .concat(Sentry.httpIntegration({ spans: false })) ``` closes getsentry/sentry-javascript#16969 ## IS YOUR CHANGE URGENT? Help us prioritize incoming PRs by letting us know when the change needs to go live. - [ ] Urgent deadline (GA date, etc.): <!-- ENTER DATE HERE --> - [ ] Other deadline: <!-- ENTER DATE HERE --> - [ ] None: Not urgent, can wait up to 1 week+ ## SLA - Teamwork makes the dream work, so please add a reviewer to your PRs. - Please give the docs team up to 1 week to review your PR unless you've added an urgent due date to it. Thanks in advance for your help! ## PRE-MERGE CHECKLIST *Make sure you've checked the following before merging your changes:* - [ ] Checked Vercel preview for correctness, including links - [ ] PR was reviewed and approved by any necessary SMEs (subject matter experts) - [ ] PR was reviewed and approved by a member of the [Sentry docs team](https://github.com/orgs/getsentry/teams/docs)
1 parent d26afb1 commit 4cf4fea

File tree

9 files changed

+435
-113
lines changed

9 files changed

+435
-113
lines changed

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

Lines changed: 19 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ supported:
66
- javascript.node
77
- javascript.aws-lambda
88
- javascript.azure-functions
9+
- javascript.bun
910
- javascript.connect
1011
- javascript.express
1112
- javascript.fastify
@@ -65,49 +66,7 @@ In order for the Sentry SDK to work as expected, and for it to be in sync with O
6566

6667
The following code snippet shows how to set up Sentry for error monitoring only:
6768

68-
```javascript
69-
const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
70-
const Sentry = require("@sentry/node");
71-
const { SentryPropagator, SentrySampler } = require("@sentry/opentelemetry");
72-
const { registerInstrumentations } = require("@opentelemetry/instrumentation");
73-
74-
const sentryClient = Sentry.init({
75-
dsn: "___DSN___",
76-
skipOpenTelemetrySetup: true,
77-
78-
// Important: We do not define a tracesSampleRate here at all!
79-
// This leads to tracing being disabled
80-
81-
// Disable emitting of spans in the httpIntegration
82-
integrations: [Sentry.httpIntegration({ spans: false })],
83-
});
84-
85-
// Create and configure e.g. NodeTracerProvider
86-
const provider = new NodeTracerProvider({
87-
// This ensures trace propagation works as expected
88-
sampler: sentryClient ? new SentrySampler(sentryClient) : undefined,
89-
});
90-
91-
provider.addSpanProcessor(
92-
new BatchSpanProcessor(
93-
new OTLPTraceExporter({
94-
url: "http://OTLP-ENDPOINT.com/api",
95-
})
96-
)
97-
);
98-
99-
// Initialize the provider
100-
provider.register({
101-
propagator: new SentryPropagator(),
102-
contextManager: new Sentry.SentryContextManager(),
103-
});
104-
105-
registerInstrumentations({
106-
instrumentations: [
107-
// Add OTEL instrumentation here
108-
],
109-
});
110-
```
69+
<PlatformContent includePath="performance/opentelemetry-setup/error-monitoring-only" />
11170

11271
## Required Instrumentation
11372

@@ -145,13 +104,27 @@ _Available since SDK version 8.35.0_
145104

146105
You can add your own `@opentelemetry/instrumentation-http` instance in your OpenTelemetry setup. However, in this case, you need to disable span creation in Sentry's `httpIntegration`:
147106

148-
```javascript
149-
const sentryClient = Sentry.init({
107+
<PlatformSection notSupported={["javascript.bun"]}>
108+
```javascript
109+
const sentryClient = Sentry.init({
150110
dsn: "___DSN___",
151111
skipOpenTelemetrySetup: true,
152112
integrations: [Sentry.httpIntegration({ spans: false })],
113+
});
114+
```
115+
</PlatformSection>
116+
117+
<PlatformSection supported={["javascript.bun"]}>
118+
```javascript
119+
const sentryClient = Sentry.init({
120+
dsn: "___DSN___",
121+
skipOpenTelemetrySetup: true,
122+
integrations: (integrations) =>
123+
// Also filter out the BunServer integration to avoid emitting duplicated spans from Sentry AND your custom OTel instrumentation
124+
integrations.filter((i) => i.name !== "BunServer")
153125
});
154126
```
127+
</PlatformSection>
155128

156129
It's important that `httpIntegration` is still registered this way to ensure that the Sentry SDK can correctly isolate requests, for example when capturing errors.
157130

@@ -163,69 +136,7 @@ If tracing is disabled, the Node Fetch instrumentation will not emit any spans.
163136

164137
While you can use your own sampler, we recommend that you use the `SentrySampler`. This will ensure that the correct subset of traces will be sent to Sentry, based on your `tracesSampleRate`. It will also ensure that all other Sentry features like trace propagation work as expected. If you do need to use your own sampler, make sure to wrap your `SamplingResult` with our `wrapSamplingDecision` method like in the example below:
165138

166-
```javascript
167-
const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
168-
const Sentry = require("@sentry/node");
169-
const {
170-
SentrySpanProcessor,
171-
SentryPropagator,
172-
SentrySampler,
173-
wrapSamplingDecision,
174-
} = require("@sentry/opentelemetry");
175-
176-
// implements Sampler from "@opentelemetry/sdk-trace-node"
177-
class CustomSampler {
178-
shouldSample(context, _traceId, _spanName, _spanKind, attributes, _links) {
179-
const decision = yourDecisionLogic();
180-
181-
// wrap the result
182-
return wrapSamplingDecision({
183-
decision,
184-
context,
185-
spanAttributes: attributes,
186-
});
187-
}
188-
189-
toString() {
190-
return CustomSampler.name;
191-
}
192-
}
193-
194-
const sentryClient = Sentry.init({
195-
dsn: "___DSN___",
196-
skipOpenTelemetrySetup: true,
197-
198-
// By defining any sample rate,
199-
// tracing intergations will be added by default
200-
// omit this if you do not want any performance integrations to be added
201-
tracesSampleRate: 0,
202-
});
203-
204-
const provider = new NodeTracerProvider({
205-
sampler: new CustomSampler(),
206-
});
207-
208-
// ...rest of your setup
209-
210-
// Validate that the setup is correct
211-
Sentry.validateOpenTelemetrySetup();
212-
```
213-
214-
## ESM Loaders
215-
216-
If your application is running in ESM (`import`/`export` syntax), OpenTelemetry requires you to set up _ESM loader hooks_.
217-
218-
The Sentry SDK will automatically register ESM loader hooks by default.
219-
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.
220-
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):
221-
222-
```javascript
223-
Sentry.init({
224-
dsn: "___DSN___",
225-
skipOpenTelemetrySetup: true,
226-
registerEsmLoaderHooks: false,
227-
});
228-
```
139+
<PlatformContent includePath="performance/opentelemetry-setup/with-custom-sampler" />
229140

230141
<Alert title="Why is it recommended to register loader hooks yourself?">
231142

docs/platforms/javascript/common/opentelemetry/index.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ supported:
77
- javascript.node
88
- javascript.aws-lambda
99
- javascript.azure-functions
10+
- javascript.bun
1011
- javascript.connect
1112
- javascript.express
1213
- javascript.fastify

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

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ supported:
66
- javascript.node
77
- javascript.aws-lambda
88
- javascript.azure-functions
9+
- javascript.bun
910
- javascript.connect
1011
- javascript.express
1112
- javascript.fastify
@@ -32,7 +33,23 @@ Sentry supports OpenTelemetry APIs out of the box. Any spans started using OpenT
3233

3334
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:
3435

35-
```javascript {12-13}
36+
```javascript {tabTitle: ESM} {12-13}
37+
import * as Sentry from "@sentry/node";
38+
import {
39+
GenericPoolInstrumentation,
40+
} from "@opentelemetry/instrumentation-generic-pool";
41+
42+
Sentry.init({
43+
dsn: "___DSN___",
44+
45+
// The SentrySampler will use this to determine which traces to sample
46+
tracesSampleRate: 1.0,
47+
48+
// Add additional OpenTelemetry instrumentation:
49+
openTelemetryInstrumentations: [new GenericPoolInstrumentation()],
50+
});
51+
```
52+
```javascript {tabTitle: CJS} {12-13}
3653
const Sentry = require("@sentry/node");
3754
const {
3855
GenericPoolInstrumentation,
@@ -65,7 +82,16 @@ We recommend using `Sentry.startSpan()` and related APIs to create spans, but yo
6582

6683
You can access the tracer Sentry uses via `client.tracer` and then create spans with OpenTelemetry APIs, as shown below:
6784

68-
```javascript
85+
```javascript {tabTitle: ESM}
86+
import * as Sentry from "@sentry/node";
87+
88+
const tracer = Sentry.getClient()?.tracer;
89+
// Now you can use native APIs on the tracer:
90+
tracer.startActiveSpan("span name", () => {
91+
// measure something
92+
});
93+
```
94+
```javascript {tabTitle: CJS}
6995
const Sentry = require("@sentry/node");
7096

7197
const tracer = Sentry.getClient()?.tracer;
@@ -81,7 +107,12 @@ You can also use any other tracer. All OpenTelemetry spans will be picked up by
81107
82108
You can access the tracer provider set up by Sentry when using Sentry's default OpenTelemetry instrumentation.
83109
84-
```javascript
110+
```javascript {tabTitle: ESM}
111+
import * as Sentry from "@sentry/node";
112+
113+
const provider = Sentry.getClient()?.traceProvider;
114+
```
115+
```javascript {tabTitle: CJS}
85116
const Sentry = require("@sentry/node");
86117

87118
const provider = Sentry.getClient()?.traceProvider;
@@ -91,7 +122,20 @@ const provider = Sentry.getClient()?.traceProvider;
91122
92123
You can add additional span processors to the tracer provider set up by Sentry when using Sentry's default OpenTelemetry instrumentation.
93124
94-
```javascript
125+
```javascript {tabTitle: ESM}
126+
import * as Sentry from "@sentry/node";
127+
128+
Sentry.init({
129+
dsn: "___DSN___",
130+
131+
// The SentrySampler will use this to determine which traces to sample
132+
tracesSampleRate: 1.0,
133+
134+
// Add additional OpenTelemetry SpanProcessors:
135+
openTelemetrySpanProcessors: [new MySpanProcessor()],
136+
});
137+
```
138+
```javascript {tabTitle: CJS}
95139
const Sentry = require("@sentry/node");
96140

97141
Sentry.init({
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
```javascript
2+
import * as Sentry from "@sentry/bun";
3+
import { SentryContextManager } from "@sentry/node-core";
4+
import { SentryPropagator, SentrySampler } from "@sentry/opentelemetry";
5+
6+
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
7+
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
8+
import { OTLPTraceExporter } from "@opentelemetry/exporter-otlp-http";
9+
import { registerInstrumentations } from "@opentelemetry/instrumentation";
10+
11+
const sentryClient = Sentry.init({
12+
dsn: "___DSN___",
13+
// Skipping the OpenTelemetry setup automatically disables emitting spans in the httpIntegration with `spans: false`
14+
skipOpenTelemetrySetup: true,
15+
16+
// Important: We do not define a tracesSampleRate here at all!
17+
// This leads to tracing being disabled
18+
19+
integrations: (integrations) =>
20+
// Filter out the BunServer integration to avoid emitting spans from there
21+
integrations.filter((i) => i.name !== "BunServer")
22+
});
23+
24+
// Create and configure e.g. NodeTracerProvider
25+
const provider = new NodeTracerProvider({
26+
// This ensures trace propagation works as expected
27+
sampler: sentryClient ? new SentrySampler(sentryClient) : undefined,
28+
});
29+
30+
provider.addSpanProcessor(
31+
new BatchSpanProcessor(
32+
new OTLPTraceExporter({
33+
url: "http://OTLP-ENDPOINT.com/api",
34+
})
35+
)
36+
);
37+
38+
// Initialize the provider
39+
provider.register({
40+
propagator: new SentryPropagator(),
41+
contextManager: new SentryContextManager(),
42+
});
43+
44+
registerInstrumentations({
45+
instrumentations: [
46+
// Add OTEL instrumentation here
47+
],
48+
});
49+
```
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
```javascript {tabTitle: ESM}
2+
import * as Sentry from "@sentry/node";
3+
import { SentryPropagator, SentrySampler } from "@sentry/opentelemetry";
4+
5+
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
6+
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
7+
import { OTLPTraceExporter } from "@opentelemetry/exporter-otlp-http";
8+
import { registerInstrumentations } from "@opentelemetry/instrumentation";
9+
10+
const sentryClient = Sentry.init({
11+
dsn: "___DSN___",
12+
// Skipping the OpenTelemetry setup automatically disables emitting spans in the httpIntegration with `spans: false`
13+
skipOpenTelemetrySetup: true,
14+
15+
// Important: We do not define a tracesSampleRate here at all!
16+
// This leads to tracing being disabled
17+
});
18+
19+
// Create and configure e.g. NodeTracerProvider
20+
const provider = new NodeTracerProvider({
21+
// This ensures trace propagation works as expected
22+
sampler: sentryClient ? new SentrySampler(sentryClient) : undefined,
23+
});
24+
25+
provider.addSpanProcessor(
26+
new BatchSpanProcessor(
27+
new OTLPTraceExporter({
28+
url: "http://OTLP-ENDPOINT.com/api",
29+
})
30+
)
31+
);
32+
33+
// Initialize the provider
34+
provider.register({
35+
propagator: new SentryPropagator(),
36+
contextManager: new Sentry.SentryContextManager(),
37+
});
38+
39+
registerInstrumentations({
40+
instrumentations: [
41+
// Add OTEL instrumentation here
42+
],
43+
});
44+
```
45+
```javascript {tabTitle: CJS}
46+
const Sentry = require("@sentry/node");
47+
const { SentryPropagator, SentrySampler } = require("@sentry/opentelemetry");
48+
49+
const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
50+
const { BatchSpanProcessor } = require("@opentelemetry/sdk-trace-base");
51+
const { OTLPTraceExporter } = require("@opentelemetry/exporter-otlp-http");
52+
const { registerInstrumentations } = require("@opentelemetry/instrumentation");
53+
54+
const sentryClient = Sentry.init({
55+
dsn: "___DSN___",
56+
// Skipping the OpenTelemetry setup automatically disables emitting spans in the httpIntegration with `spans: false`
57+
skipOpenTelemetrySetup: true,
58+
59+
// Important: We do not define a tracesSampleRate here at all!
60+
// This leads to tracing being disabled
61+
});
62+
63+
// Create and configure e.g. NodeTracerProvider
64+
const provider = new NodeTracerProvider({
65+
// This ensures trace propagation works as expected
66+
sampler: sentryClient ? new SentrySampler(sentryClient) : undefined,
67+
});
68+
69+
provider.addSpanProcessor(
70+
new BatchSpanProcessor(
71+
new OTLPTraceExporter({
72+
url: "http://OTLP-ENDPOINT.com/api",
73+
})
74+
)
75+
);
76+
77+
// Initialize the provider
78+
provider.register({
79+
propagator: new SentryPropagator(),
80+
contextManager: new Sentry.SentryContextManager(),
81+
});
82+
83+
registerInstrumentations({
84+
instrumentations: [
85+
// Add OTEL instrumentation here
86+
],
87+
});
88+
```

0 commit comments

Comments
 (0)