dd-trace-js icon indicating copy to clipboard operation
dd-trace-js copied to clipboard

Feature Request: Bun Support

Open diavrank opened this issue 2 years ago • 5 comments

Hi, I'm trying to run my app with Bun but I'm getting this error and it seems the root cause is the package of dd-trace. I know this is not your responsibility to fix this kind of issues, however, I wonder if there's any chance you take a look in case you can support the Bun project by fixing the problem from your side or giving feedback about what is the incompatibility issue with this library and Bun.

Expected behaviour

Start the Nestjs server successfully with Bun.

NPM script:

"start": "NODE_ENV=localdev nest start --watch --exec "bun run"",

Actual behaviour

It's throwing the following error when starting a Nest.js app:

[2:20:07 AM] Starting compilation in watch mode...

[2:20:24 AM] Found 0 errors. Watching for file changes.



error: Cannot find module "./hooks" from "[object Object]"

Steps to reproduce

  1. Create a Nestjs app
  2. Install the dependency ddt-trace with Bun 1.0.8
  3. Execute bun start command:

Have the start script as: "start": "NODE_ENV=localdev nest start --watch --exec "bun run"",

Environment

  • Operation system: Mac OS Sonoma
  • Node.js version: v18.16.1 (But it was run with Bun 1.0.8)
  • Tracer version: ^4.12.0" (Additionally, "nestjs-ddtrace": "^3.0.4",)
  • Agent version: what is this?
  • Relevant library versions: Bun 1.0.8

diavrank avatar Oct 28 '23 08:10 diavrank

Btw, I also reported the same issue in Bun repo https://github.com/oven-sh/bun/issues/6374

diavrank avatar Oct 28 '23 08:10 diavrank

For anyone looking for a way to enable DD tracing in a Bun runtime - there's a (hacky) way to do so (see gist https://gist.github.com/Koka/f1801289b526eeb5853894cc4e3e747d)

Short summary - I had to monkey patch dogstatsd.CustomMetrics to avoid sending metrics through UDP (not supported by Bun runtime yet) and add a shim BlockList to node net module (blocklist is not supported by Bun runtime yet and shim is built in but detection doesn't play well with Bun)

Using this technique you can run functional APM tracing without any metrics being sent, and without any integrations, so you have to call tracer.trace manually

Koka avatar Mar 12 '24 13:03 Koka

dd-trace should work in Bun as of Bun v1.1.6 (current: Bun v1.1.10)

image

Relevant PRs:

  • https://github.com/oven-sh/bun/pull/10568
  • https://github.com/oven-sh/bun/pull/7271

We manually tested it works when using Express and CommonJS. I don't think it supports tracing ESM imports, as we haven't implemented the Node.js loader API (though we do support a module loader API which works both with CommonJS & ESM without extra work to support both)

Jarred-Sumner avatar May 29 '24 00:05 Jarred-Sumner

Is there an issue for tracking support for tracing ESM imports?

hpx7 avatar May 30 '24 02:05 hpx7

dd-trace should work in Bun as of Bun v1.1.6 (current: Bun v1.1.10)

image

Relevant PRs:

We manually tested it works when using Express and CommonJS. I don't think it supports tracing ESM imports, as we haven't implemented the Node.js loader API (though we do support a module loader API which works both with CommonJS & ESM without extra work to support both)

Is there an example for this integration somewhere you could share please?

I followed the different options from the official Datadog documentation here, but no luck so far.

chin2km avatar Aug 01 '24 15:08 chin2km

any updates here?

rburgst avatar Nov 08 '24 06:11 rburgst

i got most of it working however, it appears that incoming http headers from a node based service are not being picked up, so in my APM traces I dont see the connection from node service -> bun service I am running elysia.js (https://elysiajs.com/) via bun. I can confirm that the x-datadog-* headers are being sent by the node server: Image

rburgst avatar Nov 20 '24 17:11 rburgst

Hello!

I tried to set up an app using Elysiajs in Bun too, and noticed that at least one plugin isn't working: the tcp plugin. When I start my application, the tracer in debug mode is logging this:

64 | function onError (err) {
65 |   const { formatted, cause } = getErrorLog(err)
66 | 
67 |   // calling twice logger.error() because Error cause is only available in nodejs v16.9.0
68 |   // TODO: replace it with Error(message, { cause }) when cause has broad support
69 |   if (formatted) withNoop(() => logger.error(new Error(formatted)))
                                                      ^
error: Error in plugin handler:
      at /myproject/node_modules/dd-trace/packages/dd-trace/src/log/writer.js:69:50
      at withNoop (/myproject/node_modules/dd-trace/packages/dd-trace/src/log/writer.js:25:1)
      at onError (/myproject/node_modules/dd-trace/packages/dd-trace/src/log/writer.js:82:7)
      at publish (node:diagnostics_channel:79:10)
      at error (/myproject/node_modules/dd-trace/packages/dd-trace/src/log/index.js:82:20)
      at wrappedHandler (/myproject/node_modules/dd-trace/packages/dd-trace/src/plugins/plugin.js:104:5)
      at /myproject/node_modules/dd-trace/packages/dd-trace/src/plugins/plugin.js:21:42
      at publish (node:diagnostics_channel:79:10)
      at /myproject/node_modules/dd-trace/packages/datadog-instrumentations/src/net.js:118:18
      at runInAsyncScope (node:async_hooks:128:18)

 9 | 
10 |   constructor (...args) {
11 |     super(...args)
12 | 
13 |     this.addTraceSub('connection', ({ socket }) => {
14 |       const span = this.activeSpan
                             ^
TypeError: undefined is not an object (evaluating 'this.activeSpan.addTags')
      at /myproject/node_modules/dd-trace/packages/datadog-plugin-net/src/tcp.js:14:25
      at wrappedHandler (/myproject/node_modules/dd-trace/packages/dd-trace/src/plugins/plugin.js:99:44)
      at /myproject/node_modules/dd-trace/packages/dd-trace/src/plugins/plugin.js:21:42
      at publish (node:diagnostics_channel:79:10)
      at /myproject/node_modules/dd-trace/packages/datadog-instrumentations/src/net.js:118:18
      at runInAsyncScope (node:async_hooks:128:18)
      at onceWrapper (node:events:164:21)
      at emit (node:events:56:48)
      at runInAsyncScope (node:async_hooks:128:18)
      at open (node:net:73:9)

Disabling plugin: undefined

I tried to debug a little, and noticed that the activeSpan that should be stored in an AsyncLocalStorage is lost between the start of a span and the end. This might be because of this issue on bun side: https://github.com/oven-sh/bun/issues/6393

Other than this issue, nearly no data is actually sent to the agent. My APM service does appear in the fleet automation page, linked to the correct agent handling it. But then I get a 404 error page when I try to open the service page.

Thanks!

na-ji avatar Nov 26 '24 17:11 na-ji

@na-ji how do I run the tracer in debug?

rburgst avatar Nov 29 '24 10:11 rburgst

@na-ji how do I run the tracer in debug?

You need to run your instrumented app with this env variable DD_TRACE_DEBUG=true:

https://docs.datadoghq.com/tracing/troubleshooting/tracer_debug_logs/#manual-debug-log-collection

na-ji avatar Nov 29 '24 16:11 na-ji

ok, I managed to get dd-trace to work (so so) in bun, however it messes with exceptions being logged, see https://github.com/rburgst/bun-dd-trace and https://github.com/oven-sh/bun/issues/15486, basically I get the following exception when remote fetch calls fail:

[07:12:33.795] ERROR (10977): error during upstream request {}
    err: {
      "type": "TypeError",
      "message": "|this| is not an object",
      "stack":
          TypeError: |this| is not an object
              at reject (native:1:11)
              at processTicksAndRejections (native:7:39)
    }

rburgst avatar Dec 16 '24 06:12 rburgst

Noting here that if you use dd-trace/init with the runtimeMetrics option set to true, this will use the @datadog/native-metrics NAPI module which uses libuv and V8 functions which we currently do not support

You will see an error like dyld[89513]: missing symbol called (on macOS for example)

There is a list of the libuv / V8 C++ APIs which are supported here: https://github.com/oven-sh/bun/issues/4290

zackradisic avatar Mar 25 '25 21:03 zackradisic

For anyone else who got here because of the missing symbol or segfault errors, to be very explicit on getting past that:

You need to disable profiling AND runtimeMetrics which are the specific code branches that causes errors. This can be configured through the tracer.init and/or through env vars DD_PROFILING_ENABLED=false and DD_RUNTIME_METRICS_ENABLED=false

tracer.init({
  logInjection: true,
  port: 8126,
  sampleRate: 0.5
  profiling: false,
  runtimeMetrics: false,
});

seslly avatar Aug 18 '25 22:08 seslly