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

Auto-instrument @opentelemetry/sdk-trace-node #3248

Merged
merged 1 commit into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion integration-tests/opentelemetry.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ describe('opentelemetry', () => {
const timeout = 5000

before(async () => {
sandbox = await createSandbox()
sandbox = await createSandbox([
'@opentelemetry/api',
'@opentelemetry/sdk-node',
// Needed because sdk-node doesn't start a tracer without an exporter
'@opentelemetry/exporter-jaeger'
])
cwd = sandbox.folder
agent = await new FakeAgent().start()
})
Expand Down Expand Up @@ -102,4 +107,23 @@ describe('opentelemetry', () => {
assert.strictEqual(ddSpan.parent_id.toString(), otelSpan.span_id.toString())
})
})

it('should auto-instrument @opentelemetry/sdk-node', async () => {
proc = fork(join(cwd, 'opentelemetry/env-var.js'), {
cwd,
env: {
DD_TRACE_AGENT_PORT: agent.port
}
})
return check(agent, proc, timeout, ({ payload }) => {
// Should have a single trace with a single span
assert.strictEqual(payload.length, 1)
const [trace] = payload
assert.strictEqual(trace.length, 1)
const [span] = trace

// Should be the expected otel span
assert.strictEqual(span.name, 'otel-sub')
})
})
})
24 changes: 24 additions & 0 deletions integration-tests/opentelemetry/env-var.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict'

process.env.DD_TRACE_OTEL_ENABLED = '1'

require('dd-trace').init()

const opentelemetry = require('@opentelemetry/sdk-node')
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger')

const sdk = new opentelemetry.NodeSDK({
traceExporter: new JaegerExporter()
})

sdk.start()

const otelTracer = opentelemetry.api.trace.getTracer(
'my-service-tracer'
)

otelTracer.startActiveSpan('otel-sub', otelSpan => {
setImmediate(() => {
otelSpan.end()
})
})
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"@datadog/pprof": "^2.2.1",
"@datadog/sketches-js": "^2.1.0",
"@opentelemetry/api": "^1.0.0",
"@opentelemetry/core": "<1.4.0",
"@opentelemetry/core": "^1.14.0",
"crypto-randomuuid": "^1.0.0",
"diagnostics_channel": "^1.1.0",
"ignore": "^5.2.0",
Expand Down
1 change: 1 addition & 0 deletions packages/datadog-instrumentations/src/helpers/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module.exports = {
'@koa/router': () => require('../koa'),
'@node-redis/client': () => require('../redis'),
'@opensearch-project/opensearch': () => require('../opensearch'),
'@opentelemetry/sdk-trace-node': () => require('../otel-sdk-trace'),
'@redis/client': () => require('../redis'),
'amqp10': () => require('../amqp10'),
'amqplib': () => require('../amqplib'),
Expand Down
18 changes: 18 additions & 0 deletions packages/datadog-instrumentations/src/otel-sdk-trace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict'

const { addHook } = require('./helpers/instrument')
const shimmer = require('../../datadog-shimmer')
const tracer = require('../../dd-trace')

if (process.env.DD_TRACE_OTEL_ENABLED) {
addHook({
name: '@opentelemetry/sdk-trace-node',
file: 'build/src/NodeTracerProvider.js',
versions: ['*']
}, (mod) => {
shimmer.wrap(mod, 'NodeTracerProvider', () => {
return tracer.TracerProvider
})
return mod
})
}
4 changes: 4 additions & 0 deletions packages/dd-trace/src/noop/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ class Tracer {
this.appsec.setUser(user)
return this
}

get TracerProvider () {
return require('../opentelemetry/tracer_provider')
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra bug fix to allow accessing TracerProvider before doing tracer.init(...).

}

module.exports = Tracer
2 changes: 1 addition & 1 deletion packages/dd-trace/src/opentelemetry/context_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class ContextManager {
bind (context, target) {
const self = this
return function (...args) {
return self.with(context, target, this, args)
return self.with(context, target, this, ...args)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And another bug fix to ensure arguments are passed through bind properly.

}
}

Expand Down
18 changes: 9 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -681,17 +681,17 @@
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f"
integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==

"@opentelemetry/core@<1.4.0":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.3.1.tgz#6eef5c5efca9a4cd7daa0cd4c7ff28ca2317c8d7"
integrity sha512-k7lOC86N7WIyUZsUuSKZfFIrUtINtlauMGQsC1r7jNmcr0vVJGqK1ROBvt7WWMxLbpMnt1q2pXJO8tKu0b9auA==
"@opentelemetry/core@^1.14.0":
version "1.14.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.14.0.tgz#64e876b29cb736c984d54164cd47433f513eafd3"
integrity sha512-MnMZ+sxsnlzloeuXL2nm5QcNczt/iO82UOeQQDHhV83F2fP3sgntW2evvtoxJki0MBLxEsh5ADD7PR/Hn5uzjw==
dependencies:
"@opentelemetry/semantic-conventions" "1.3.1"
"@opentelemetry/semantic-conventions" "1.14.0"

"@opentelemetry/semantic-conventions@1.3.1":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.3.1.tgz#ba07b864a3c955f061aa30ea3ef7f4ae4449794a"
integrity sha512-wU5J8rUoo32oSef/rFpOT1HIjLjAv3qIDHkw1QIhODV3OpAVHi5oVzlouozg9obUmZKtbZ0qUe/m7FP0y0yBzA==
"@opentelemetry/semantic-conventions@1.14.0":
version "1.14.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.14.0.tgz#6a729b7f372ce30f77a3f217c09bc216f863fccb"
integrity sha512-rJfCY8rCWz3cb4KI6pEofnytvMPuj3YLQwoscCCYZ5DkdiPjo15IQ0US7+mjcWy9H3fcZIzf2pbJZ7ck/h4tug==

"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
version "1.1.2"
Expand Down