dd-trace 5.0.0-pre-03f1a68 → 5.0.0-pre-e2df7ec
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/datadog-instrumentations/src/child-process.js +4 -5
- package/packages/datadog-instrumentations/src/crypto.js +2 -1
- package/packages/datadog-instrumentations/src/dns.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +7 -2
- package/packages/datadog-instrumentations/src/helpers/instrument.js +8 -3
- package/packages/datadog-instrumentations/src/helpers/register.js +18 -2
- package/packages/datadog-instrumentations/src/http/client.js +2 -2
- package/packages/datadog-instrumentations/src/http/server.js +7 -4
- package/packages/datadog-instrumentations/src/http2/client.js +3 -1
- package/packages/datadog-instrumentations/src/http2/server.js +3 -1
- package/packages/datadog-instrumentations/src/net.js +10 -2
- package/packages/dd-trace/src/config.js +19 -0
- package/packages/dd-trace/src/plugins/index.js +5 -0
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -0
- package/packages/dd-trace/src/profiling/profilers/events.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/shared.js +1 -1
- package/packages/dd-trace/src/telemetry/index.js +15 -0
package/package.json
CHANGED
|
@@ -9,11 +9,10 @@ const shimmer = require('../../datadog-shimmer')
|
|
|
9
9
|
const childProcessChannel = channel('datadog:child_process:execution:start')
|
|
10
10
|
const execMethods = ['exec', 'execFile', 'fork', 'spawn', 'execFileSync', 'execSync', 'spawnSync']
|
|
11
11
|
const names = ['child_process', 'node:child_process']
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
})
|
|
12
|
+
|
|
13
|
+
addHook({ name: names }, childProcess => {
|
|
14
|
+
shimmer.massWrap(childProcess, execMethods, wrapChildProcessMethod())
|
|
15
|
+
return childProcess
|
|
17
16
|
})
|
|
18
17
|
|
|
19
18
|
function wrapChildProcessMethod () {
|
|
@@ -11,8 +11,9 @@ const cryptoCipherCh = channel('datadog:crypto:cipher:start')
|
|
|
11
11
|
|
|
12
12
|
const hashMethods = ['createHash', 'createHmac', 'createSign', 'createVerify', 'sign', 'verify']
|
|
13
13
|
const cipherMethods = ['createCipheriv', 'createDecipheriv']
|
|
14
|
+
const names = ['crypto', 'node:crypto']
|
|
14
15
|
|
|
15
|
-
addHook({ name:
|
|
16
|
+
addHook({ name: names }, crypto => {
|
|
16
17
|
shimmer.massWrap(crypto, hashMethods, wrapCryptoMethod(cryptoHashCh))
|
|
17
18
|
shimmer.massWrap(crypto, cipherMethods, wrapCryptoMethod(cryptoCipherCh))
|
|
18
19
|
return crypto
|
|
@@ -18,8 +18,9 @@ const rrtypes = {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const rrtypeMap = new WeakMap()
|
|
21
|
+
const names = ['dns', 'node:dns']
|
|
21
22
|
|
|
22
|
-
addHook({ name:
|
|
23
|
+
addHook({ name: names }, dns => {
|
|
23
24
|
dns.lookup = wrap('apm:dns:lookup', dns.lookup, 2)
|
|
24
25
|
dns.lookupService = wrap('apm:dns:lookup_service', dns.lookupService, 3)
|
|
25
26
|
dns.resolve = wrap('apm:dns:resolve', dns.resolve, 2)
|
|
@@ -31,7 +31,6 @@ module.exports = {
|
|
|
31
31
|
'bunyan': () => require('../bunyan'),
|
|
32
32
|
'cassandra-driver': () => require('../cassandra-driver'),
|
|
33
33
|
'child_process': () => require('../child-process'),
|
|
34
|
-
'node:child_process': () => require('../child-process'),
|
|
35
34
|
'connect': () => require('../connect'),
|
|
36
35
|
'cookie': () => require('../cookie'),
|
|
37
36
|
'cookie-parser': () => require('../cookie-parser'),
|
|
@@ -45,7 +44,6 @@ module.exports = {
|
|
|
45
44
|
'fastify': () => require('../fastify'),
|
|
46
45
|
'find-my-way': () => require('../find-my-way'),
|
|
47
46
|
'fs': () => require('../fs'),
|
|
48
|
-
'node:fs': () => require('../fs'),
|
|
49
47
|
'generic-pool': () => require('../generic-pool'),
|
|
50
48
|
'graphql': () => require('../graphql'),
|
|
51
49
|
'grpc': () => require('../grpc'),
|
|
@@ -79,6 +77,13 @@ module.exports = {
|
|
|
79
77
|
'mysql2': () => require('../mysql2'),
|
|
80
78
|
'net': () => require('../net'),
|
|
81
79
|
'next': () => require('../next'),
|
|
80
|
+
'node:child_process': () => require('../child-process'),
|
|
81
|
+
'node:crypto': () => require('../crypto'),
|
|
82
|
+
'node:dns': () => require('../dns'),
|
|
83
|
+
'node:http': () => require('../http'),
|
|
84
|
+
'node:http2': () => require('../http2'),
|
|
85
|
+
'node:https': () => require('../http'),
|
|
86
|
+
'node:net': () => require('../net'),
|
|
82
87
|
'oracledb': () => require('../oracledb'),
|
|
83
88
|
'openai': () => require('../openai'),
|
|
84
89
|
'paperplane': () => require('../paperplane'),
|
|
@@ -21,11 +21,16 @@ exports.channel = function (name) {
|
|
|
21
21
|
* @param Function hook
|
|
22
22
|
*/
|
|
23
23
|
exports.addHook = function addHook ({ name, versions, file }, hook) {
|
|
24
|
-
if (
|
|
25
|
-
|
|
24
|
+
if (typeof name === 'string') {
|
|
25
|
+
name = [name]
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
for (const val of name) {
|
|
29
|
+
if (!instrumentations[val]) {
|
|
30
|
+
instrumentations[val] = []
|
|
31
|
+
}
|
|
32
|
+
instrumentations[val].push({ name: val, versions, file, hook })
|
|
33
|
+
}
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
// AsyncResource.bind exists and binds `this` properly only from 17.8.0 and up.
|
|
@@ -24,6 +24,7 @@ if (!disabledInstrumentations.has('fetch')) {
|
|
|
24
24
|
require('../fetch')
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
const HOOK_SYMBOL = Symbol('hookExportsMap')
|
|
27
28
|
// TODO: make this more efficient
|
|
28
29
|
|
|
29
30
|
for (const packageName of names) {
|
|
@@ -42,14 +43,29 @@ for (const packageName of names) {
|
|
|
42
43
|
for (const { name, file, versions, hook } of instrumentations[packageName]) {
|
|
43
44
|
const fullFilename = filename(name, file)
|
|
44
45
|
|
|
46
|
+
// Create a WeakMap associated with the hook function so that patches on the same moduleExport only happens once
|
|
47
|
+
// for example by instrumenting both dns and node:dns double the spans would be created
|
|
48
|
+
// since they both patch the same moduleExport, this WeakMap is used to mitigate that
|
|
49
|
+
if (!hook[HOOK_SYMBOL]) {
|
|
50
|
+
hook[HOOK_SYMBOL] = new WeakMap()
|
|
51
|
+
}
|
|
52
|
+
|
|
45
53
|
if (moduleName === fullFilename) {
|
|
46
54
|
const version = moduleVersion || getVersion(moduleBaseDir)
|
|
47
55
|
|
|
48
56
|
if (matchVersion(version, versions)) {
|
|
57
|
+
// Check if the hook already has a set moduleExport
|
|
58
|
+
if (hook[HOOK_SYMBOL].has(moduleExports)) {
|
|
59
|
+
return moduleExports
|
|
60
|
+
}
|
|
61
|
+
|
|
49
62
|
try {
|
|
50
63
|
loadChannel.publish({ name, version, file })
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
// Send the name and version of the module back to the callback because now addHook
|
|
65
|
+
// takes in an array of names so by passing the name the callback will know which module name is being used
|
|
66
|
+
moduleExports = hook(moduleExports, version, name)
|
|
67
|
+
// Set the moduleExports in the hooks weakmap
|
|
68
|
+
hook[HOOK_SYMBOL].set(moduleExports, name)
|
|
53
69
|
} catch (e) {
|
|
54
70
|
log.error(e)
|
|
55
71
|
}
|
|
@@ -14,9 +14,9 @@ const endChannel = channel('apm:http:client:request:end')
|
|
|
14
14
|
const asyncStartChannel = channel('apm:http:client:request:asyncStart')
|
|
15
15
|
const errorChannel = channel('apm:http:client:request:error')
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const names = ['http', 'https', 'node:http', 'node:https']
|
|
18
18
|
|
|
19
|
-
addHook({ name:
|
|
19
|
+
addHook({ name: names }, hookFn)
|
|
20
20
|
|
|
21
21
|
function hookFn (http) {
|
|
22
22
|
patch(http, 'request')
|
|
@@ -15,14 +15,17 @@ const finishSetHeaderCh = channel('datadog:http:server:response:set-header:finis
|
|
|
15
15
|
|
|
16
16
|
const requestFinishedSet = new WeakSet()
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const httpNames = ['http', 'node:http']
|
|
19
|
+
const httpsNames = ['https', 'node:https']
|
|
20
|
+
|
|
21
|
+
addHook({ name: httpNames }, http => {
|
|
22
|
+
shimmer.wrap(http.ServerResponse.prototype, 'emit', wrapResponseEmit)
|
|
20
23
|
shimmer.wrap(http.Server.prototype, 'emit', wrapEmit)
|
|
21
24
|
return http
|
|
22
25
|
})
|
|
23
26
|
|
|
24
|
-
addHook({ name:
|
|
25
|
-
|
|
27
|
+
addHook({ name: httpsNames }, http => {
|
|
28
|
+
// http.ServerResponse not present on https
|
|
26
29
|
shimmer.wrap(http.Server.prototype, 'emit', wrapEmit)
|
|
27
30
|
return http
|
|
28
31
|
})
|
|
@@ -10,6 +10,8 @@ const asyncStartChannel = channel('apm:http2:client:request:asyncStart')
|
|
|
10
10
|
const asyncEndChannel = channel('apm:http2:client:request:asyncEnd')
|
|
11
11
|
const errorChannel = channel('apm:http2:client:request:error')
|
|
12
12
|
|
|
13
|
+
const names = ['http2', 'node:http2']
|
|
14
|
+
|
|
13
15
|
function createWrapEmit (ctx) {
|
|
14
16
|
return function wrapEmit (emit) {
|
|
15
17
|
return function (event, arg1) {
|
|
@@ -66,7 +68,7 @@ function wrapConnect (connect) {
|
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
addHook({ name:
|
|
71
|
+
addHook({ name: names }, http2 => {
|
|
70
72
|
shimmer.wrap(http2, 'connect', wrapConnect)
|
|
71
73
|
|
|
72
74
|
return http2
|
|
@@ -14,7 +14,9 @@ const startServerCh = channel('apm:http2:server:request:start')
|
|
|
14
14
|
const errorServerCh = channel('apm:http2:server:request:error')
|
|
15
15
|
const finishServerCh = channel('apm:http2:server:request:finish')
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const names = ['http2', 'node:http2']
|
|
18
|
+
|
|
19
|
+
addHook({ name: names }, http2 => {
|
|
18
20
|
shimmer.wrap(http2, 'createSecureServer', wrapCreateServer)
|
|
19
21
|
shimmer.wrap(http2, 'createServer', wrapCreateServer)
|
|
20
22
|
return http2
|
|
@@ -17,8 +17,16 @@ const errorTCPCh = channel('apm:net:tcp:error')
|
|
|
17
17
|
|
|
18
18
|
const connectionCh = channel(`apm:net:tcp:connection`)
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
const names = ['net', 'node:net']
|
|
21
|
+
|
|
22
|
+
addHook({ name: names }, (net, version, name) => {
|
|
23
|
+
// explicitly require dns so that net gets an instrumented instance
|
|
24
|
+
// so that we don't miss the dns calls
|
|
25
|
+
if (name === 'net') {
|
|
26
|
+
require('dns')
|
|
27
|
+
} else {
|
|
28
|
+
require('node:dns')
|
|
29
|
+
}
|
|
22
30
|
|
|
23
31
|
shimmer.wrap(net.Socket.prototype, 'connect', connect => function () {
|
|
24
32
|
if (!startICPCh.hasSubscribers || !startTCPCh.hasSubscribers) {
|
|
@@ -522,6 +522,19 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
522
522
|
0
|
|
523
523
|
)
|
|
524
524
|
|
|
525
|
+
const DD_INSTRUMENTATION_INSTALL_ID = coalesce(
|
|
526
|
+
process.env.DD_INSTRUMENTATION_INSTALL_ID,
|
|
527
|
+
null
|
|
528
|
+
)
|
|
529
|
+
const DD_INSTRUMENTATION_INSTALL_TIME = coalesce(
|
|
530
|
+
process.env.DD_INSTRUMENTATION_INSTALL_TIME,
|
|
531
|
+
null
|
|
532
|
+
)
|
|
533
|
+
const DD_INSTRUMENTATION_INSTALL_TYPE = coalesce(
|
|
534
|
+
process.env.DD_INSTRUMENTATION_INSTALL_TYPE,
|
|
535
|
+
null
|
|
536
|
+
)
|
|
537
|
+
|
|
525
538
|
const ingestion = options.ingestion || {}
|
|
526
539
|
const dogstatsd = coalesce(options.dogstatsd, {})
|
|
527
540
|
const sampler = {
|
|
@@ -671,6 +684,12 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
671
684
|
|
|
672
685
|
this.spanLeakDebug = Number(DD_TRACE_SPAN_LEAK_DEBUG)
|
|
673
686
|
|
|
687
|
+
this.installSignature = {
|
|
688
|
+
id: DD_INSTRUMENTATION_INSTALL_ID,
|
|
689
|
+
time: DD_INSTRUMENTATION_INSTALL_TIME,
|
|
690
|
+
type: DD_INSTRUMENTATION_INSTALL_TYPE
|
|
691
|
+
}
|
|
692
|
+
|
|
674
693
|
this._applyDefaults()
|
|
675
694
|
this._applyEnvironment()
|
|
676
695
|
this._applyOptions(options)
|
|
@@ -59,6 +59,11 @@ module.exports = {
|
|
|
59
59
|
get 'mysql2' () { return require('../../../datadog-plugin-mysql2/src') },
|
|
60
60
|
get 'net' () { return require('../../../datadog-plugin-net/src') },
|
|
61
61
|
get 'next' () { return require('../../../datadog-plugin-next/src') },
|
|
62
|
+
get 'node:dns' () { return require('../../../datadog-plugin-dns/src') },
|
|
63
|
+
get 'node:http' () { return require('../../../datadog-plugin-http/src') },
|
|
64
|
+
get 'node:http2' () { return require('../../../datadog-plugin-http2/src') },
|
|
65
|
+
get 'node:https' () { return require('../../../datadog-plugin-http/src') },
|
|
66
|
+
get 'node:net' () { return require('../../../datadog-plugin-net/src') },
|
|
62
67
|
get 'oracledb' () { return require('../../../datadog-plugin-oracledb/src') },
|
|
63
68
|
get 'openai' () { return require('../../../datadog-plugin-openai/src') },
|
|
64
69
|
get 'paperplane' () { return require('../../../datadog-plugin-paperplane/src') },
|
|
@@ -75,6 +75,7 @@ class AgentExporter {
|
|
|
75
75
|
['tags[]', 'language:javascript'],
|
|
76
76
|
['tags[]', 'runtime:nodejs'],
|
|
77
77
|
['tags[]', `runtime_version:${process.version}`],
|
|
78
|
+
['tags[]', `process_id:${process.pid}`],
|
|
78
79
|
['tags[]', `profiler_version:${version}`],
|
|
79
80
|
['tags[]', 'format:pprof'],
|
|
80
81
|
...Object.entries(tags).map(([key, value]) => ['tags[]', `${key}:${value}`])
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { performance, constants, PerformanceObserver } = require('
|
|
1
|
+
const { performance, constants, PerformanceObserver } = require('perf_hooks')
|
|
2
2
|
const { END_TIMESTAMP_LABEL } = require('./shared')
|
|
3
3
|
const semver = require('semver')
|
|
4
4
|
const { Function, Label, Line, Location, Profile, Sample, StringTable, ValueType } = require('pprof-format')
|
|
@@ -112,11 +112,26 @@ function flatten (input, result = [], prefix = [], traversedObjects = null) {
|
|
|
112
112
|
return result
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
function getInstallSignature (config) {
|
|
116
|
+
const { installSignature: sig } = config
|
|
117
|
+
if (sig && (sig.id || sig.time || sig.type)) {
|
|
118
|
+
return {
|
|
119
|
+
install_id: sig.id,
|
|
120
|
+
install_time: sig.time,
|
|
121
|
+
install_type: sig.type
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
115
126
|
function appStarted (config) {
|
|
116
127
|
const app = {
|
|
117
128
|
products: getProducts(config),
|
|
118
129
|
configuration: flatten(config)
|
|
119
130
|
}
|
|
131
|
+
const installSignature = getInstallSignature(config)
|
|
132
|
+
if (installSignature) {
|
|
133
|
+
app.install_signature = installSignature
|
|
134
|
+
}
|
|
120
135
|
// TODO: add app.error with correct error codes
|
|
121
136
|
// if (errors.agentError) {
|
|
122
137
|
// app.error = errors.agentError
|