Skip to content
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

Integrations not working for Bun #14202

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

Integrations not working for Bun #14202

doepnern opened this issue Nov 7, 2024 · 13 comments
Labels
Bug getsentry/sentry-javascript 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.

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Mar 31, 2025
onurtemizkan pushed a commit that referenced this issue Apr 3, 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

Alright. I gave it a shot on my local env and I saw it run in ESM mode. I will try to get it to run like this in the QA env but so far, I am not seeing any additional telemetry for the DB and so on. Perhaps I am doing something wrong. I am using ElysiaJS and I was able to connect Sentry to it using Elysia's OTEL plugin... The thing is I am only seeing data from http.server and not much else. Is there more I need to do?

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

s1gr1d commented Apr 4, 2025

In Node with ESM, the instrumentation file needs to be added with the CLI flag --import. This adds the file before the application starts and enables instrumentation for other libraries (DBs, caches etc). There are some docs on this in the Node docs: https://docs.sentry.io/platforms/javascript/guides/node/install/esm/

We still need to add docs for this in bun, but I think you can do the same with --preload in Bun (docs here and here).

Does this work?

@MatthewAry
Copy link

In Node with ESM, the instrumentation file needs to be added with the CLI flag --import. This adds the file before the application starts and enables instrumentation for other libraries (DBs, caches etc). There are some docs on this in the Node docs: docs.sentry.io/platforms/javascript/guides/node/install/esm

We still need to add docs for this in bun, but I think you can do the same with --preload in Bun (docs here and here).

Does this work?

As noted in my conversation with @AbhiPrasad I have already done that and I was able to get it to run now in ESM mode. I'm asking about the rest of the auto instrumentation such as postgres, or redis. I'm not seeing any data coming in from that stuff which I am using.

@getsantry getsantry bot moved this from Waiting for: Community to Waiting for: Product Owner in GitHub Issues with 👀 3 Apr 4, 2025
@s1gr1d
Copy link
Member

s1gr1d commented Apr 7, 2025

It could be that Bun does not work correctly with import-in-the-middle (which is needed for auto-instrumentation in ESM). For reference, there is an open PR for Bun: #15978

We still need to test it out to find the root cause.

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

No branches or pull requests

7 participants