Skip to content

Integrations not working for Bun #14202

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

Open
3 tasks done
doepnern opened this issue Nov 7, 2024 · 22 comments
Open
3 tasks done

Integrations not working for Bun #14202

doepnern opened this issue Nov 7, 2024 · 22 comments
Labels
Bug Package: bun Issues related to the Sentry Bun SDK

Comments

@doepnern
Copy link

doepnern commented Nov 7, 2024

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/bun

SDK Version

8.37.1

Framework Version

No response

Link to Sentry event

No response

Reproduction Example/SDK Setup

Hey,
which integrations should I expect to work in bun? So far only manual instrumentation seems to be working.
Is this expected behavior? If so, a few more notes on that would be appreciated in the documentation.

Bun

import * as Sentry from "@sentry/bun";

// Ensure to call this before importing any other modules!
Sentry.init({
	dsn: DSN,
	debug: true,
	// Add Performance Monitoring by setting tracesSampleRate
	// Set tracesSampleRate to 1.0 to capture 100% of transactions
	// We recommend adjusting this value in production
	tracesSampleRate: 1.0,
});
import "./instrument.ts";
import * as Sentry from "@sentry/bun";

await Sentry.startSpan(
	{
		op: "test",
		name: "My First Test Transaction in bun",
	},
	async () => {
		await fetch(`https://google.com`);
	},
);

const sleep = () => new Promise((res) => setTimeout(() => res("hi"), 3000));

await sleep();
throw new Error("I just crashed Bun");
`

Node
`
import * as Sentry from "@sentry/node";

// Ensure to call this before importing any other modules!
Sentry.init({
	dsn: DSN,
	debug: true,
	// Add Performance Monitoring by setting tracesSampleRate
	// Set tracesSampleRate to 1.0 to capture 100% of transactions
	// We recommend adjusting this value in production
	tracesSampleRate: 1.0,
});

Steps to Reproduce

https://github.com/doepnern/sentry-node-bun-comparison

Expected Result

Expected http instrumentation to work, according to docs (See result for node below)

https://docs.sentry.io/platforms/javascript/guides/bun/configuration/integrations/http/

Image

Actual Result

Image

error handling is noted as not working in the npm package page, so i guess that is to be expected

Image

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Nov 7, 2024
@github-actions github-actions bot added the Package: bun Issues related to the Sentry Bun SDK label Nov 7, 2024
@lforst
Copy link
Member

lforst commented Nov 7, 2024

@AbhiPrasad should fetch client instrumentation work for bun work?

@andreiborza
Copy link
Member

Hi @doepnern, thanks for filing this. Unfortunately this is still an issue upstream in bun, see oven-sh/bun#13165.

You should filter out the http integration for the time being.

import * as Sentry from '@sentry/bun';

Sentry.init({
  dsn: '__MY_DSN__',
  integrations: function (integrations) {
    // integrations will be all default integrations
    return integrations.filter(function (integration) {
      return integration.name !== "Http";
    });
  },
  tracesSampleRate: 1.0,
});

@MatthewAry
Copy link

From what I can tell, I'm supposed to get automatic instrumentation with PostgreSQL, Redis, and more. Yet I am not seeing the data for this stuff being received.

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Mar 25, 2025
@AbhiPrasad
Copy link
Member

@MatthewAry are you running your app with CJS or ESM? ESM might be causing issues here for instrumentation.

@MatthewAry
Copy link

@AbhiPrasad Well, it's Bun. And we use ESM for a long list of DX reasons. Do you have guidance on how to make this stuff work with ESM?

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Mar 25, 2025
@AbhiPrasad
Copy link
Member

ESM instrumentation gets complicated (I did a talk about this here), which is why I asked.

In our instructions for Node.js apps, we recommend using a --import flag to import instrumentation before running the rest of your code: https://docs.sentry.io/platforms/javascript/guides/node/install/esm/

The equivalent to this in Bun is --preload.

Let's try the following. First create a instrumentation.mjs file where your sentry instrumentation code lives:

import * as Sentry from "@sentry/bun";

// Ensure to call this before importing any other modules!
Sentry.init({
  dsn: "YOUR_DSN_HERE",

  // Add Tracing by setting tracesSampleRate
  // We recommend adjusting this value in production
  tracesSampleRate: 1.0,

  // enable debug logs so we see what instrumentation isn't getting initialized properly.
  debug: true,
});

Then could you run your app with bun run --preload ./instrument.mjs app.mjs, where app.mjs is your app entrypoint as appropriate? With preload and the debug logs we should be able to figure out what is going on.

@MatthewAry
Copy link

MatthewAry commented Mar 28, 2025

Okay. Was finally able to get around to this. I watched your video and I tried running it like you suggested. Here was my result:

  Sentry Logger [log]: Initializing Sentry: process: 78026, thread: main.
  Sentry Logger [log]: Integration installed: InboundFilters
  Sentry Logger [log]: Integration installed: FunctionToString
  Sentry Logger [log]: Integration installed: LinkedErrors
  Sentry Logger [log]: Integration installed: RequestData
  Sentry Logger [log]: Integration installed: Console
  Sentry Logger [log]: Integration installed: Http
  Sentry Logger [log]: Integration installed: NodeFetch
  Sentry Logger [log]: Integration installed: OnUncaughtException
  Sentry Logger [log]: Integration installed: OnUnhandledRejection
  Sentry Logger [log]: Integration installed: ContextLines
  Sentry Logger [log]: Integration installed: Context
  Sentry Logger [log]: Integration installed: Modules
  Sentry Logger [log]: Integration installed: BunServer
  Sentry Logger [log]: Integration installed: Express
  Sentry Logger [log]: Integration installed: Fastify
  Sentry Logger [log]: Integration installed: Graphql
  Sentry Logger [log]: Integration installed: Mongo
  Sentry Logger [log]: Integration installed: Mongoose
  Sentry Logger [log]: Integration installed: Mysql
  Sentry Logger [log]: Integration installed: Mysql2
  Sentry Logger [log]: Integration installed: Redis
  Sentry Logger [log]: Integration installed: Postgres
  Sentry Logger [log]: Integration installed: Hapi
  Sentry Logger [log]: Integration installed: Koa
  Sentry Logger [log]: Integration installed: Connect
  Sentry Logger [log]: Integration installed: Tedious
  Sentry Logger [log]: Integration installed: GenericPool
  Sentry Logger [log]: Integration installed: Kafka
  Sentry Logger [log]: Integration installed: Amqplib
  Sentry Logger [log]: Integration installed: LruMemoizer
  Sentry Logger [log]: Integration installed: VercelAI
  Sentry Logger [log]: Running in CommonJS mode.
  Sentry Logger [debug]: @opentelemetry/api: Registered a global for diag v1.9.0.
  Sentry Logger [debug]: @opentelemetry/api: Registered a global for trace v1.9.0.
  Sentry Logger [debug]: @opentelemetry/api: Registered a global for propagation v1.9.0.
  Sentry Logger [debug]: @opentelemetry/api: Registered a global for context v1.9.0.
  Sentry Logger [debug]: @opentelemetry_sentry-patched/instrumentation-http Applying instrumentation patch for nodejs core module on require hook {
    module: "http",
  }
  Sentry Logger [debug]: @sentry/instrumentation-http Applying instrumentation patch for nodejs core module on require hook {
    module: "http",
  }
  Sentry Logger [debug]: @opentelemetry_sentry-patched/instrumentation-http Applying instrumentation patch for nodejs core module on require hook {
    module: "https",
  }
  Sentry Logger [debug]: @sentry/instrumentation-http Applying instrumentation patch for nodejs core module on require hook {
    module: "https",
  }
  Sentry Logger [log]: [Tracing] Starting sampled root span
    op: < unknown op >
    name: Save FGA Options
    ID: aa007045a2ac1524
  Sentry Logger [log]: [Tracing] Finishing "< unknown op >" root span "Save FGA Options" with ID aa007045a2ac1524
  ...
  Sentry Logger [log]: SpanExporter exported 312 spans, 0 spans are waiting for their parent spans to finish
  Sentry Logger [error]: Skipped sending event because buffer is full.
  Sentry Logger [error]: Skipped sending event because buffer is full.
  Sentry Logger [error]: Skipped sending event because buffer is full.
  Sentry Logger [log]: Recording outcome: "queue_overflow:transaction"
  Sentry Logger [log]: Recording outcome: "queue_overflow:transaction"
  Sentry Logger [log]: Recording outcome: "queue_overflow:transaction"
  Sentry Logger [log]: Recording outcome: "queue_overflow:transaction"
  ...
  Sentry Logger [log]: Flushing client reports based on interval.
  Sentry Logger [log]: Flushing outcomes...
  Sentry Logger [log]: Sending outcomes: [
    {
      reason: "queue_overflow",
      category: "transaction",
      quantity: 242,
    }
  ]

I have truncated some of the redundant outputs. What's interesting to me is that it says that it's running in CommonJS mode (which doesn't seem to be in alignment with what you said in your presentation), and after that it says that it's skipping sending events because the buffer is full... So it's not able to drain the buffer and its not sending events? I'm investigating the buffer bit but I'm interested on your thoughts about it starting in CommonJS mode.

I did find this

export function maybeInitializeEsmLoader(): void {
const [nodeMajor = 0, nodeMinor = 0] = process.versions.node.split('.').map(Number);
// Register hook was added in v20.6.0 and v18.19.0
if (nodeMajor >= 22 || (nodeMajor === 20 && nodeMinor >= 6) || (nodeMajor === 18 && nodeMinor >= 19)) {
if (!GLOBAL_OBJ._sentryEsmLoaderHookRegistered) {
try {
const { addHookMessagePort } = createAddHookMessageChannel();
// @ts-expect-error register is available in these versions
moduleModule.register('import-in-the-middle/hook.mjs', import.meta.url, {
data: { addHookMessagePort, include: [] },
transferList: [addHookMessagePort],
});
} catch (error) {
logger.warn('Failed to register ESM hook', error);
}
}
} else {
consoleSandbox(() => {
// eslint-disable-next-line no-console
console.warn(
'[Sentry] You are using Node.js in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or upgrade your Node.js version.',
);
});
}
}
Which seems to not be built with Bun in mind. And also I see that this
export function isCjs(): boolean {
return typeof require !== 'undefined';
}
which is supposed to detect if it should run in CJS or not is probably not going to work on Bun because https://bun.sh/docs/runtime/modules#using-require Bun lets you use require in mjs and ts files.

You can confirm on your end but it seems to me that Sentry would only be able to work on Node with ESM right now because I think that Sentry's package for Bun is leaning too hard on the logic used for Node because Bun's Sentry Package ultimately uses the Node's init method

function _init(
_options: NodeOptions | undefined = {},
getDefaultIntegrationsImpl: (options: Options) => Integration[],
): NodeClient {
const options = getClientOptions(_options, getDefaultIntegrationsImpl);
if (options.debug === true) {
if (DEBUG_BUILD) {
logger.enable();
} else {
// use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped
consoleSandbox(() => {
// eslint-disable-next-line no-console
console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.');
});
}
}
if (!isCjs() && options.registerEsmLoaderHooks !== false) {
maybeInitializeEsmLoader();
}
setOpenTelemetryContextAsyncContextStrategy();
const scope = getCurrentScope();
scope.update(options.initialScope);
if (options.spotlight && !options.integrations.some(({ name }) => name === SPOTLIGHT_INTEGRATION_NAME)) {
options.integrations.push(
spotlightIntegration({
sidecarUrl: typeof options.spotlight === 'string' ? options.spotlight : undefined,
}),
);
}
const client = new NodeClient(options);
// The client is on the current scope, from where it generally is inherited
getCurrentScope().setClient(client);
client.init();
logger.log(`Running in ${isCjs() ? 'CommonJS' : 'ESM'} mode.`);
client.startClientReportTracking();
updateScopeFromEnvVariables();
// If users opt-out of this, they _have_ to set up OpenTelemetry themselves
// There is no way to use this SDK without OpenTelemetry!
if (!options.skipOpenTelemetrySetup) {
initOpenTelemetry(client, {
spanProcessors: options.openTelemetrySpanProcessors,
});
validateOpenTelemetrySetup();
}
enhanceDscWithOpenTelemetryRootSpanName(client);
setupEventContextTrace(client);
return client;
}
.

@s1gr1d
Copy link
Member

s1gr1d commented Mar 31, 2025

The log output looks good (except for the CJS log).

  1. initOtel.ts: Bun also provides process.node.version or where do you think this is not compatible with Bun?
  2. commonjs.ts: I created a PR to change the CJS check: fix(cjs): Use module instead of require for CJS check #15927

s1gr1d added a commit that referenced this issue Mar 31, 2025
As `require` is supported in ESM as well from [Node
20.19.0](https://nodejs.org/en/blog/release/v20.19.0) onwards, the check
does not work anymore. However, `module` is not available in ESM.

Also mentioned in this comment:
#14202 (comment)


[Node: Compatibility with
CommonJS](https://nodejs.org/docs/latest-v15.x/api/esm.html#esm_interoperability_with_commonjs)

[Bun: Using require](https://bun.sh/docs/runtime/modules#using-require)
@MatthewAry
Copy link

@s1gr1d

  1. Cool, didn't know that.
  2. Looking forward to the next release.

@MatthewAry
Copy link

Okay, well it would be nice to see this work before Sentry starts charging us for using the profiling feature after it becomes GA. I think that for bun projects, it might be appropriate to keep the billing turned off until it's for sure working.

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Apr 16, 2025
@MatthewAry
Copy link

So I'm seeing auto-telemetry working for Bun.serve but still not seeing any auto-telemetry working for anything else like PG, or Redis.

@Lms24
Copy link
Member

Lms24 commented Apr 17, 2025

Have you tried upgrading Bun and the Sentry SDK to the latest versions? The PR linked by Sigrid was merged and we adapted our SDK in the latest release.

it would be nice to see this work before Sentry starts charging us for using the profiling feature after it becomes GA

I haven't followed this conversation in detail but Profiling has GA'd quite a while ago. If you feel like we charged you for something incorrectly please contact support so that our support staff can refund you.

@MatthewAry
Copy link

@Lms24 Yeah, I tried it out. I am seeing that I am able to reliably get telemetry only from Bun.serve but nothing else. We're using Postgres and Redis, and we're seeing nothing from those sources.

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Apr 17, 2025
@Lms24
Copy link
Member

Lms24 commented Apr 22, 2025

Hi, sorry for the late reply (easter holidays and all...)!

We're using Postgres and Redis

Just to confirm, are you using the packages pg and redis (or ioredis)? Asking because there are some other package options out there that we/Otel don't instrument automatically.

Assuming yes, I think Sigrid is right that import-in-the-middle isn't applying the patches correctly. Which really could be related to a bunch of reasons. Full disclosure: bun is not a top priority for us and getting things working in ESM is already challenging in Node. I'll ask internally in the team if someone can take a look at this.

In the meantime: I see the last time you posted debug logs and your Sentry setup is quite a while ago. Did anything change in since then? We'd greatly appreciate a minimal reproduction or alternatively any updates in debug log output or setup. Thanks!

@MatthewAry
Copy link

We're using @neondatabase/serverless which uses pg under the hood. As for redis we're using ioredis.

While making a minimal reproduction I was able to get pg and @neondatabase/serverless to work but I have not been able to get ioredis to work.

I was able to track down the issue with how I was setting the release property in the Sentry.init call. I was calling a function which ran a script to get the Git SHA. Using the function some how broke part of the process for auto-telemetry. I have since changed how that works on my end and it's working now, but only for pg, pg-pool, http, https. Not for Redis.

Here is my minimal reproduction https://github.com/MatthewAry/sentry-bun

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Apr 22, 2025
@MatthewAry
Copy link

MatthewAry commented Apr 22, 2025

Update: I don't think query traces are working @neondatabase/serverless even though it uses pg under the hood. See https://github.com/neondatabase/serverless/blob/ae8237620fb6045b22504c5385a27568e2e82a85/src/pool.ts

I'm able to use vanilla pg with neon if I am willing to tolerate disconnection errors and lost performance benefits.

Update: There's a stale PR on Neon's driver to add OTEL support neondatabase/serverless#102

@s1gr1d
Copy link
Member

s1gr1d commented Apr 24, 2025

Thanks for the reproduction, we're taking a look!

s1gr1d added a commit that referenced this issue Apr 25, 2025
Adding Node 21 to the accepted version range for `module.register` as it
is already supported (https://nodejs.org/docs/v21.0.0/api/module.html).

This also causes the customization hook not to call register (maybe a
reason why some packages in issue
#14202 are not
instrumented):
https://github.com/getsentry/sentry-javascript/blob/59094afb6ab53ac33b87b83f70eea9d13e4c2291/packages/node/src/sdk/initOtel.ts#L45-L65


--- 
Additionally, the above mentioned issue
#14202 shows the
following warning although it's using v21:
```
[Sentry] You are using Node.js in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or upgrade your Node.js version.
```
@lforst
Copy link
Member

lforst commented Apr 25, 2025

In an internal chat Jarred Sumner mentioned that import-in-the-middle is not working with Bun and that it won't be for a while. He also mentioned that we could be using Bun.plugin (i think this: https://bun.sh/reference/bun/BunRegisterPlugin) with the onLoad hook. Note that this is also likely a lot of work and probably long ways out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Package: bun Issues related to the Sentry Bun SDK
Projects
Status: No status
Development

No branches or pull requests

8 participants