dd-trace 4.4.0 → 4.6.0
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/LICENSE-3rdparty.csv +4 -3
- package/package.json +4 -4
- package/packages/datadog-instrumentations/src/aws-sdk.js +5 -0
- package/packages/datadog-instrumentations/src/cassandra-driver.js +6 -3
- package/packages/datadog-instrumentations/src/elasticsearch.js +39 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/kafkajs.js +13 -4
- package/packages/datadog-instrumentations/src/opensearch.js +2 -1
- package/packages/datadog-instrumentations/src/redis.js +48 -5
- package/packages/datadog-plugin-aws-sdk/src/base.js +3 -3
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -0
- package/packages/datadog-plugin-cassandra-driver/src/index.js +4 -4
- package/packages/datadog-plugin-grpc/src/client.js +8 -2
- package/packages/datadog-plugin-grpc/src/server.js +2 -2
- package/packages/datadog-plugin-kafkajs/src/consumer.js +6 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +14 -2
- package/packages/datadog-plugin-mongodb-core/src/index.js +13 -2
- package/packages/datadog-plugin-openai/src/index.js +9 -2
- package/packages/datadog-plugin-openai/src/services.js +14 -10
- package/packages/datadog-plugin-oracledb/src/index.js +1 -0
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -5
- package/packages/dd-trace/src/config.js +11 -0
- package/packages/dd-trace/src/data_streams_context.js +15 -0
- package/packages/dd-trace/src/datastreams/pathway.js +58 -0
- package/packages/dd-trace/src/datastreams/processor.js +194 -0
- package/packages/dd-trace/src/datastreams/writer.js +66 -0
- package/packages/dd-trace/src/dogstatsd.js +14 -1
- package/packages/dd-trace/src/metrics.js +2 -2
- package/packages/dd-trace/src/plugin_manager.js +6 -1
- package/packages/dd-trace/src/plugins/database.js +2 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/outbound.js +2 -1
- package/packages/dd-trace/src/plugins/tracing.js +3 -0
- package/packages/dd-trace/src/plugins/util/git.js +37 -5
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +36 -2
- package/packages/dd-trace/src/profiling/config.js +32 -5
- package/packages/dd-trace/src/service-naming/index.js +13 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +9 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +8 -0
- package/packages/dd-trace/src/telemetry/metrics.js +76 -20
- package/packages/dd-trace/src/tracer.js +19 -1
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -11,6 +11,7 @@ require,crypto-randomuuid,MIT,Copyright 2021 Node.js Foundation and contributors
|
|
|
11
11
|
require,diagnostics_channel,MIT,Copyright 2021 Simon D.
|
|
12
12
|
require,ignore,MIT,Copyright 2013 Kael Zhang and contributors
|
|
13
13
|
require,import-in-the-middle,Apache license 2.0,Copyright 2021 Datadog Inc.
|
|
14
|
+
require,int64-buffer,MIT,Copyright 2015-2016 Yusuke Kawasaki
|
|
14
15
|
require,ipaddr.js,MIT,Copyright 2011-2017 whitequark
|
|
15
16
|
require,istanbul-lib-coverage,BSD-3-Clause,Copyright 2012-2015 Yahoo! Inc.
|
|
16
17
|
require,koalas,MIT,Copyright 2013-2017 Brian Woodward
|
|
@@ -22,6 +23,7 @@ require,lodash.uniq,MIT,Copyright JS Foundation and other contributors
|
|
|
22
23
|
require,lru-cache,ISC,Copyright (c) 2010-2022 Isaac Z. Schlueter and Contributors
|
|
23
24
|
require,methods,MIT,Copyright 2013-2014 TJ Holowaychuk
|
|
24
25
|
require,module-details-from-path,MIT,Copyright 2016 Thomas Watson Steen
|
|
26
|
+
require,msgpack-lite,MIT,Copyright 2015 Yusuke Kawasaki
|
|
25
27
|
require,node-abort-controller,MIT,Copyright (c) 2019 Steve Faulkner
|
|
26
28
|
require,opentracing,MIT,Copyright 2016 Resonance Labs Inc
|
|
27
29
|
require,path-to-regexp,MIT,Copyright 2014 Blake Embrey
|
|
@@ -51,13 +53,11 @@ dev,express,MIT,Copyright 2009-2014 TJ Holowaychuk 2013-2014 Roman Shtylman 2014
|
|
|
51
53
|
dev,get-port,MIT,Copyright Sindre Sorhus
|
|
52
54
|
dev,glob,ISC,Copyright Isaac Z. Schlueter and Contributors
|
|
53
55
|
dev,graphql,MIT,Copyright 2015 Facebook Inc.
|
|
54
|
-
dev,int64-buffer,MIT,Copyright 2015-2016 Yusuke Kawasaki
|
|
55
56
|
dev,jszip,MIT,Copyright 2015-2016 Stuart Knightley and contributors
|
|
56
57
|
dev,knex,MIT,Copyright (c) 2013-present Tim Griesser
|
|
57
58
|
dev,mkdirp,MIT,Copyright 2010 James Halliday
|
|
58
59
|
dev,mocha,MIT,Copyright 2011-2018 JS Foundation and contributors https://js.foundation
|
|
59
60
|
dev,multer,MIT,Copyright 2014 Hage Yaapa
|
|
60
|
-
dev,msgpack-lite,MIT,Copyright 2015 Yusuke Kawasaki
|
|
61
61
|
dev,nock,MIT,Copyright 2017 Pedro Teixeira and other contributors
|
|
62
62
|
dev,nyc,ISC,Copyright 2015 Contributors
|
|
63
63
|
dev,pprof-format,MIT,Copyright 2022 Stephen Belanger
|
|
@@ -67,5 +67,6 @@ dev,sinon,BSD-3-Clause,Copyright 2010-2017 Christian Johansen
|
|
|
67
67
|
dev,sinon-chai,WTFPL and BSD-2-Clause,Copyright 2004 Sam Hocevar 2012–2017 Domenic Denicola
|
|
68
68
|
dev,tap,ISC,Copyright 2011-2022 Isaac Z. Schlueter and Contributors
|
|
69
69
|
dev,tape,MIT,Copyright James Halliday
|
|
70
|
-
file,aws-lambda-nodejs-runtime-interface-client,Apache 2.0,Copyright 2019 Amazon.com
|
|
70
|
+
file,aws-lambda-nodejs-runtime-interface-client,Apache 2.0,Copyright 2019 Amazon.com Inc. or its affiliates. All Rights Reserved.
|
|
71
71
|
file,profile.proto,Apache license 2.0,Copyright 2016 Google Inc.
|
|
72
|
+
file,is-git-url,MIT,Copyright (c) 2017 Jon Schlinkert.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"test:appsec:ci": "nyc --no-clean --include \"packages/dd-trace/src/appsec/**/*.js\" --exclude \"packages/dd-trace/test/appsec/**/*.plugin.spec.js\" -- npm run test:appsec",
|
|
20
20
|
"test:appsec:plugins": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/dd-trace/test/appsec/**/*.@($(echo $PLUGINS)).plugin.spec.js\"",
|
|
21
21
|
"test:appsec:plugins:ci": "yarn services && nyc --no-clean --include \"packages/dd-trace/test/appsec/**/*.@($(echo $PLUGINS)).plugin.spec.js\" -- npm run test:appsec:plugins",
|
|
22
|
-
"test:trace:core": "tap packages/dd-trace/test/*.spec.js \"packages/dd-trace/test/{ci-visibility,
|
|
22
|
+
"test:trace:core": "tap packages/dd-trace/test/*.spec.js \"packages/dd-trace/test/{ci-visibility,encode,exporters,opentelemetry,opentracing,plugins,service-naming,telemetry}/**/*.spec.js\"",
|
|
23
23
|
"test:trace:core:ci": "npm run test:trace:core -- --coverage --nyc-arg=--include=\"packages/dd-trace/src/**/*.js\"",
|
|
24
24
|
"test:instrumentations": "mocha --colors -r 'packages/dd-trace/test/setup/mocha.js' 'packages/datadog-instrumentations/test/**/*.spec.js'",
|
|
25
25
|
"test:instrumentations:ci": "nyc --no-clean --include 'packages/datadog-instrumentations/src/**/*.js' -- npm run test:instrumentations",
|
|
@@ -78,6 +78,7 @@
|
|
|
78
78
|
"diagnostics_channel": "^1.1.0",
|
|
79
79
|
"ignore": "^5.2.0",
|
|
80
80
|
"import-in-the-middle": "^1.3.5",
|
|
81
|
+
"int64-buffer": "^0.1.9",
|
|
81
82
|
"ipaddr.js": "^2.0.1",
|
|
82
83
|
"istanbul-lib-coverage": "3.2.0",
|
|
83
84
|
"koalas": "^1.0.2",
|
|
@@ -89,6 +90,7 @@
|
|
|
89
90
|
"lru-cache": "^7.14.0",
|
|
90
91
|
"methods": "^1.1.2",
|
|
91
92
|
"module-details-from-path": "^1.0.3",
|
|
93
|
+
"msgpack-lite": "^0.1.26",
|
|
92
94
|
"node-abort-controller": "^3.0.1",
|
|
93
95
|
"opentracing": ">=0.12.1",
|
|
94
96
|
"path-to-regexp": "^0.1.2",
|
|
@@ -120,12 +122,10 @@
|
|
|
120
122
|
"get-port": "^3.2.0",
|
|
121
123
|
"glob": "^7.1.6",
|
|
122
124
|
"graphql": "0.13.2",
|
|
123
|
-
"int64-buffer": "^0.1.9",
|
|
124
125
|
"jszip": "^3.5.0",
|
|
125
126
|
"knex": "^2.4.2",
|
|
126
127
|
"mkdirp": "^0.5.1",
|
|
127
128
|
"mocha": "8",
|
|
128
|
-
"msgpack-lite": "^0.1.26",
|
|
129
129
|
"multer": "^1.4.5-lts.1",
|
|
130
130
|
"nock": "^11.3.3",
|
|
131
131
|
"nyc": "^15.1.0",
|
|
@@ -166,6 +166,11 @@ function getChannelSuffix (name) {
|
|
|
166
166
|
].includes(name) ? name : 'default'
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
+
addHook({ name: '@smithy/smithy-client', versions: ['>=1.0.3'] }, smithy => {
|
|
170
|
+
shimmer.wrap(smithy.Client.prototype, 'send', wrapSmithySend)
|
|
171
|
+
return smithy
|
|
172
|
+
})
|
|
173
|
+
|
|
169
174
|
addHook({ name: '@aws-sdk/smithy-client', versions: ['>=3'] }, smithy => {
|
|
170
175
|
shimmer.wrap(smithy.Client.prototype, 'send', wrapSmithySend)
|
|
171
176
|
return smithy
|
|
@@ -28,7 +28,8 @@ addHook({ name: 'cassandra-driver', versions: ['>=3.0.0'] }, cassandra => {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
return asyncResource.runInAsyncScope(() => {
|
|
31
|
-
|
|
31
|
+
const contactPoints = this.options && this.options.contactPoints
|
|
32
|
+
startCh.publish({ keyspace: this.keyspace, query: queries, contactPoints })
|
|
32
33
|
try {
|
|
33
34
|
const res = batch.apply(this, arguments)
|
|
34
35
|
if (typeof res === 'function' || !res) {
|
|
@@ -56,7 +57,8 @@ addHook({ name: 'cassandra-driver', versions: ['>=4.4'] }, cassandra => {
|
|
|
56
57
|
}
|
|
57
58
|
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
58
59
|
return asyncResource.runInAsyncScope(() => {
|
|
59
|
-
|
|
60
|
+
const contactPoints = this.options && this.options.contactPoints
|
|
61
|
+
startCh.publish({ keyspace: this.keyspace, query, contactPoints })
|
|
60
62
|
const promise = _execute.apply(this, arguments)
|
|
61
63
|
|
|
62
64
|
const promiseAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
@@ -88,7 +90,8 @@ addHook({ name: 'cassandra-driver', versions: ['3 - 4.3'] }, cassandra => {
|
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
return asyncResource.runInAsyncScope(() => {
|
|
91
|
-
|
|
93
|
+
const contactPoints = this.options && this.options.contactPoints
|
|
94
|
+
startCh.publish({ keyspace: this.keyspace, query, contactPoints })
|
|
92
95
|
|
|
93
96
|
const lastIndex = arguments.length - 1
|
|
94
97
|
let cb = arguments[lastIndex]
|
|
@@ -9,11 +9,13 @@ const shimmer = require('../../datadog-shimmer')
|
|
|
9
9
|
|
|
10
10
|
addHook({ name: '@elastic/transport', file: 'lib/Transport.js', versions: ['>=8'] }, (exports) => {
|
|
11
11
|
shimmer.wrap(exports.default.prototype, 'request', createWrapRequest('elasticsearch'))
|
|
12
|
+
shimmer.wrap(exports.default.prototype, 'getConnection', createWrapGetConnection('elasticsearch'))
|
|
12
13
|
return exports
|
|
13
14
|
})
|
|
14
15
|
|
|
15
16
|
addHook({ name: '@elastic/elasticsearch', file: 'lib/Transport.js', versions: ['>=5.6.16 <8', '>=8'] }, Transport => {
|
|
16
17
|
shimmer.wrap(Transport.prototype, 'request', createWrapRequest('elasticsearch'))
|
|
18
|
+
shimmer.wrap(Transport.prototype, 'getConnection', createWrapGetConnection('elasticsearch'))
|
|
17
19
|
return Transport
|
|
18
20
|
})
|
|
19
21
|
|
|
@@ -22,6 +24,42 @@ addHook({ name: 'elasticsearch', file: 'src/lib/transport.js', versions: ['>=10'
|
|
|
22
24
|
return Transport
|
|
23
25
|
})
|
|
24
26
|
|
|
27
|
+
addHook({ name: 'elasticsearch', file: 'src/lib/connection_pool.js', versions: ['>=10'] }, ConnectionPool => {
|
|
28
|
+
shimmer.wrap(ConnectionPool.prototype, 'select', createWrapSelect('elasticsearch'))
|
|
29
|
+
return ConnectionPool
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
function createWrapGetConnection (name) {
|
|
33
|
+
const connectCh = channel(`apm:${name}:query:connect`)
|
|
34
|
+
return function wrapRequest (request) {
|
|
35
|
+
return function () {
|
|
36
|
+
const connection = request.apply(this, arguments)
|
|
37
|
+
if (connectCh.hasSubscribers && connection && connection.url) {
|
|
38
|
+
connectCh.publish(connection.url)
|
|
39
|
+
}
|
|
40
|
+
return connection
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function createWrapSelect () {
|
|
46
|
+
const connectCh = channel('apm:elasticsearch:query:connect')
|
|
47
|
+
return function wrapRequest (request) {
|
|
48
|
+
return function () {
|
|
49
|
+
if (arguments.length === 1) {
|
|
50
|
+
const cb = arguments[0]
|
|
51
|
+
arguments[0] = function (err, connection) {
|
|
52
|
+
if (connectCh.hasSubscribers && connection && connection.host) {
|
|
53
|
+
connectCh.publish({ hostname: connection.host.host, port: connection.host.port })
|
|
54
|
+
}
|
|
55
|
+
cb(err, connection)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return request.apply(this, arguments)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
25
63
|
function createWrapRequest (name) {
|
|
26
64
|
const startCh = channel(`apm:${name}:query:start`)
|
|
27
65
|
const finishCh = channel(`apm:${name}:query:finish`)
|
|
@@ -83,4 +121,4 @@ function createWrapRequest (name) {
|
|
|
83
121
|
}
|
|
84
122
|
}
|
|
85
123
|
|
|
86
|
-
module.exports = { createWrapRequest }
|
|
124
|
+
module.exports = { createWrapRequest, createWrapGetConnection }
|
|
@@ -16,6 +16,7 @@ module.exports = {
|
|
|
16
16
|
'@opensearch-project/opensearch': () => require('../opensearch'),
|
|
17
17
|
'@opentelemetry/sdk-trace-node': () => require('../otel-sdk-trace'),
|
|
18
18
|
'@redis/client': () => require('../redis'),
|
|
19
|
+
'@smithy/smithy-client': () => require('../aws-sdk'),
|
|
19
20
|
'amqp10': () => require('../amqp10'),
|
|
20
21
|
'amqplib': () => require('../amqplib'),
|
|
21
22
|
'aws-sdk': () => require('../aws-sdk'),
|
|
@@ -16,10 +16,19 @@ const consumerFinishCh = channel('apm:kafkajs:consume:finish')
|
|
|
16
16
|
const consumerErrorCh = channel('apm:kafkajs:consume:error')
|
|
17
17
|
|
|
18
18
|
addHook({ name: 'kafkajs', versions: ['>=1.4'] }, (obj) => {
|
|
19
|
-
|
|
19
|
+
class Kafka extends obj.Kafka {
|
|
20
|
+
constructor (options) {
|
|
21
|
+
super(options)
|
|
22
|
+
this._brokers = (options.brokers && typeof options.brokers !== 'function')
|
|
23
|
+
? options.brokers.join(',') : undefined
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
obj.Kafka = Kafka
|
|
27
|
+
|
|
20
28
|
shimmer.wrap(Kafka.prototype, 'producer', createProducer => function () {
|
|
21
29
|
const producer = createProducer.apply(this, arguments)
|
|
22
30
|
const send = producer.send
|
|
31
|
+
const bootstrapServers = this._brokers
|
|
23
32
|
|
|
24
33
|
producer.send = function () {
|
|
25
34
|
const innerAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
@@ -36,7 +45,7 @@ addHook({ name: 'kafkajs', versions: ['>=1.4'] }, (obj) => {
|
|
|
36
45
|
message.headers = message.headers || {}
|
|
37
46
|
}
|
|
38
47
|
}
|
|
39
|
-
producerStartCh.publish({ topic, messages })
|
|
48
|
+
producerStartCh.publish({ topic, messages, bootstrapServers })
|
|
40
49
|
|
|
41
50
|
const result = send.apply(this, arguments)
|
|
42
51
|
|
|
@@ -69,6 +78,7 @@ addHook({ name: 'kafkajs', versions: ['>=1.4'] }, (obj) => {
|
|
|
69
78
|
const consumer = createConsumer.apply(this, arguments)
|
|
70
79
|
const run = consumer.run
|
|
71
80
|
|
|
81
|
+
const groupId = arguments[0].groupId
|
|
72
82
|
consumer.run = function ({ eachMessage, ...runArgs }) {
|
|
73
83
|
if (typeof eachMessage !== 'function') return run({ eachMessage, ...runArgs })
|
|
74
84
|
|
|
@@ -77,10 +87,9 @@ addHook({ name: 'kafkajs', versions: ['>=1.4'] }, (obj) => {
|
|
|
77
87
|
const innerAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
78
88
|
return innerAsyncResource.runInAsyncScope(() => {
|
|
79
89
|
const { topic, partition, message } = eachMessageArgs[0]
|
|
80
|
-
consumerStartCh.publish({ topic, partition, message })
|
|
90
|
+
consumerStartCh.publish({ topic, partition, message, groupId })
|
|
81
91
|
try {
|
|
82
92
|
const result = eachMessage.apply(this, eachMessageArgs)
|
|
83
|
-
|
|
84
93
|
if (result && typeof result.then === 'function') {
|
|
85
94
|
result.then(
|
|
86
95
|
innerAsyncResource.bind(() => consumerFinishCh.publish(undefined)),
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
const { addHook } = require('./helpers/instrument')
|
|
4
4
|
const shimmer = require('../../datadog-shimmer')
|
|
5
|
-
const { createWrapRequest } = require('./elasticsearch')
|
|
5
|
+
const { createWrapRequest, createWrapGetConnection } = require('./elasticsearch')
|
|
6
6
|
|
|
7
7
|
addHook({ name: '@opensearch-project/opensearch', file: 'lib/Transport.js', versions: ['>=1'] }, Transport => {
|
|
8
8
|
shimmer.wrap(Transport.prototype, 'request', createWrapRequest('opensearch'))
|
|
9
|
+
shimmer.wrap(Transport.prototype, 'getConnection', createWrapGetConnection('opensearch'))
|
|
9
10
|
return Transport
|
|
10
11
|
})
|
|
@@ -11,6 +11,8 @@ const startCh = channel('apm:redis:command:start')
|
|
|
11
11
|
const finishCh = channel('apm:redis:command:finish')
|
|
12
12
|
const errorCh = channel('apm:redis:command:error')
|
|
13
13
|
|
|
14
|
+
let createClientUrl
|
|
15
|
+
|
|
14
16
|
function wrapAddCommand (addCommand) {
|
|
15
17
|
return function (command) {
|
|
16
18
|
if (!startCh.hasSubscribers) {
|
|
@@ -22,7 +24,7 @@ function wrapAddCommand (addCommand) {
|
|
|
22
24
|
|
|
23
25
|
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
24
26
|
return asyncResource.runInAsyncScope(() => {
|
|
25
|
-
start(this, name, args)
|
|
27
|
+
start(this, name, args, this._url)
|
|
26
28
|
|
|
27
29
|
const res = addCommand.apply(this, arguments)
|
|
28
30
|
const onResolve = asyncResource.bind(() => finish(finishCh, errorCh))
|
|
@@ -35,12 +37,53 @@ function wrapAddCommand (addCommand) {
|
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
function wrapCommandQueueClass (cls) {
|
|
41
|
+
const ret = class RedisCommandQueue extends cls {
|
|
42
|
+
constructor () {
|
|
43
|
+
super(arguments)
|
|
44
|
+
if (createClientUrl) {
|
|
45
|
+
try {
|
|
46
|
+
const parsed = new URL(createClientUrl)
|
|
47
|
+
if (parsed) {
|
|
48
|
+
this._url = { host: parsed.hostname, port: +parsed.port || 6379 }
|
|
49
|
+
}
|
|
50
|
+
} catch (error) {
|
|
51
|
+
// ignore
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
this._url = this._url || { host: 'localhost', port: 6379 }
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return ret
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function wrapCreateClient (request) {
|
|
61
|
+
return function (opts) {
|
|
62
|
+
createClientUrl = opts && opts.url
|
|
63
|
+
const ret = request.apply(this, arguments)
|
|
64
|
+
createClientUrl = undefined
|
|
65
|
+
return ret
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
addHook({ name: '@node-redis/client', file: 'dist/lib/client/commands-queue.js', versions: ['>=1'] }, redis => {
|
|
70
|
+
redis.default = wrapCommandQueueClass(redis.default)
|
|
39
71
|
shimmer.wrap(redis.default.prototype, 'addCommand', wrapAddCommand)
|
|
40
72
|
return redis
|
|
41
73
|
})
|
|
42
74
|
|
|
43
|
-
addHook({ name: '@node-redis/client', file: 'dist/lib/client/
|
|
75
|
+
addHook({ name: '@node-redis/client', file: 'dist/lib/client/index.js', versions: ['>=1'] }, redis => {
|
|
76
|
+
shimmer.wrap(redis.default, 'create', wrapCreateClient)
|
|
77
|
+
return redis
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
addHook({ name: '@redis/client', file: 'dist/lib/client/index.js', versions: ['>=1.1'] }, redis => {
|
|
81
|
+
shimmer.wrap(redis.default, 'create', wrapCreateClient)
|
|
82
|
+
return redis
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
addHook({ name: '@redis/client', file: 'dist/lib/client/commands-queue.js', versions: ['>=1.1'] }, redis => {
|
|
86
|
+
redis.default = wrapCommandQueueClass(redis.default)
|
|
44
87
|
shimmer.wrap(redis.default.prototype, 'addCommand', wrapAddCommand)
|
|
45
88
|
return redis
|
|
46
89
|
})
|
|
@@ -106,9 +149,9 @@ addHook({ name: 'redis', versions: ['>=0.12 <2.6'] }, redis => {
|
|
|
106
149
|
return redis
|
|
107
150
|
})
|
|
108
151
|
|
|
109
|
-
function start (client, command, args) {
|
|
152
|
+
function start (client, command, args, url = {}) {
|
|
110
153
|
const db = client.selected_db
|
|
111
|
-
const connectionOptions = client.connection_options || client.connection_option || client.connectionOption ||
|
|
154
|
+
const connectionOptions = client.connection_options || client.connection_option || client.connectionOption || url
|
|
112
155
|
startCh.publish({ db, command, args, connectionOptions })
|
|
113
156
|
}
|
|
114
157
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
|
|
4
|
-
const
|
|
4
|
+
const ClientPlugin = require('../../dd-trace/src/plugins/client')
|
|
5
5
|
const { storage } = require('../../datadog-core')
|
|
6
6
|
const { isTrue } = require('../../dd-trace/src/util')
|
|
7
7
|
|
|
8
|
-
class BaseAwsSdkPlugin extends
|
|
8
|
+
class BaseAwsSdkPlugin extends ClientPlugin {
|
|
9
9
|
static get id () { return 'aws' }
|
|
10
10
|
|
|
11
11
|
get serviceIdentifier () {
|
|
@@ -116,7 +116,7 @@ class BaseAwsSdkPlugin extends Plugin {
|
|
|
116
116
|
this.config.hooks.request(span, response)
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
super.finish()
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
configure (config) {
|
|
@@ -3,6 +3,7 @@ const log = require('../../../dd-trace/src/log')
|
|
|
3
3
|
const BaseAwsSdkPlugin = require('../base')
|
|
4
4
|
class Kinesis extends BaseAwsSdkPlugin {
|
|
5
5
|
static get id () { return 'kinesis' }
|
|
6
|
+
static get peerServicePrecursors () { return ['streamname'] }
|
|
6
7
|
|
|
7
8
|
generateTags (params, operation, response) {
|
|
8
9
|
if (!params || !params.StreamName) return {}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { CLIENT_PORT_KEY } = require('../../dd-trace/src/constants')
|
|
4
3
|
const DatabasePlugin = require('../../dd-trace/src/plugins/database')
|
|
4
|
+
const CASSANDRA_CONTACT_POINTS_KEY = 'db.cassandra.contact.points'
|
|
5
5
|
|
|
6
6
|
class CassandraDriverPlugin extends DatabasePlugin {
|
|
7
7
|
static get id () { return 'cassandra-driver' }
|
|
8
8
|
static get system () { return 'cassandra' }
|
|
9
|
+
static get peerServicePrecursors () { return [CASSANDRA_CONTACT_POINTS_KEY] }
|
|
9
10
|
|
|
10
|
-
start ({ keyspace, query,
|
|
11
|
+
start ({ keyspace, query, contactPoints = {} }) {
|
|
11
12
|
if (Array.isArray(query)) {
|
|
12
13
|
query = combine(query)
|
|
13
14
|
}
|
|
@@ -21,8 +22,7 @@ class CassandraDriverPlugin extends DatabasePlugin {
|
|
|
21
22
|
'db.type': 'cassandra',
|
|
22
23
|
'cassandra.query': query,
|
|
23
24
|
'cassandra.keyspace': keyspace,
|
|
24
|
-
|
|
25
|
-
[CLIENT_PORT_KEY]: connectionOptions.port
|
|
25
|
+
[CASSANDRA_CONTACT_POINTS_KEY]: contactPoints.join(',') || null
|
|
26
26
|
}
|
|
27
27
|
})
|
|
28
28
|
}
|
|
@@ -7,12 +7,13 @@ const { addMetadataTags, getFilter, getMethodMetadata } = require('./util')
|
|
|
7
7
|
class GrpcClientPlugin extends ClientPlugin {
|
|
8
8
|
static get id () { return 'grpc' }
|
|
9
9
|
static get operation () { return 'client:request' }
|
|
10
|
+
static get peerServicePrecursors () { return ['rpc.service'] }
|
|
10
11
|
|
|
11
12
|
start ({ metadata, path, type }) {
|
|
12
13
|
const metadataFilter = this.config.metadataFilter
|
|
13
14
|
const method = getMethodMetadata(path, type)
|
|
14
|
-
const span = this.startSpan(
|
|
15
|
-
service: this.config.service,
|
|
15
|
+
const span = this.startSpan(this.operationName(), {
|
|
16
|
+
service: this.config.service || this.serviceName(),
|
|
16
17
|
resource: path,
|
|
17
18
|
kind: 'client',
|
|
18
19
|
type: 'http',
|
|
@@ -29,6 +30,11 @@ class GrpcClientPlugin extends ClientPlugin {
|
|
|
29
30
|
}
|
|
30
31
|
})
|
|
31
32
|
|
|
33
|
+
// needed as precursor for peer.service
|
|
34
|
+
if (method.service && method.package) {
|
|
35
|
+
span.setTag('rpc.service', method.package + '.' + method.service)
|
|
36
|
+
}
|
|
37
|
+
|
|
32
38
|
if (metadata) {
|
|
33
39
|
addMetadataTags(span, metadata, metadataFilter, 'request')
|
|
34
40
|
inject(this.tracer, span, metadata)
|
|
@@ -24,9 +24,9 @@ class GrpcServerPlugin extends ServerPlugin {
|
|
|
24
24
|
const metadataFilter = this.config.metadataFilter
|
|
25
25
|
const childOf = extract(this.tracer, metadata)
|
|
26
26
|
const method = getMethodMetadata(name, type)
|
|
27
|
-
const span = this.startSpan(
|
|
27
|
+
const span = this.startSpan(this.operationName(), {
|
|
28
28
|
childOf,
|
|
29
|
-
service: this.config.service,
|
|
29
|
+
service: this.config.service || this.serviceName(),
|
|
30
30
|
resource: name,
|
|
31
31
|
kind: 'server',
|
|
32
32
|
type: 'web',
|
|
@@ -6,7 +6,12 @@ class KafkajsConsumerPlugin extends ConsumerPlugin {
|
|
|
6
6
|
static get id () { return 'kafkajs' }
|
|
7
7
|
static get operation () { return 'consume' }
|
|
8
8
|
|
|
9
|
-
start ({ topic, partition, message }) {
|
|
9
|
+
start ({ topic, partition, message, groupId }) {
|
|
10
|
+
if (this.config.dsmEnabled) {
|
|
11
|
+
this.tracer.decodeDataStreamsContext(message.headers['dd-pathway-ctx'])
|
|
12
|
+
this.tracer
|
|
13
|
+
.setCheckpoint(['direction:in', `group:${groupId}`, `topic:${topic}`, 'type:kafka'])
|
|
14
|
+
}
|
|
10
15
|
const childOf = extract(this.tracer, message.headers)
|
|
11
16
|
this.startSpan({
|
|
12
17
|
childOf,
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
|
|
4
|
+
const { encodePathwayContext } = require('../../dd-trace/src/datastreams/pathway')
|
|
5
|
+
const BOOTSTRAP_SERVERS_KEY = 'messaging.kafka.bootstrap.servers'
|
|
4
6
|
|
|
5
7
|
class KafkajsProducerPlugin extends ProducerPlugin {
|
|
6
8
|
static get id () { return 'kafkajs' }
|
|
7
9
|
static get operation () { return 'produce' }
|
|
10
|
+
static get peerServicePrecursors () { return [BOOTSTRAP_SERVERS_KEY] }
|
|
8
11
|
|
|
9
|
-
start ({ topic, messages }) {
|
|
12
|
+
start ({ topic, messages, bootstrapServers }) {
|
|
13
|
+
let pathwayCtx
|
|
14
|
+
if (this.config.dsmEnabled) {
|
|
15
|
+
const dataStreamsContext = this.tracer
|
|
16
|
+
.setCheckpoint(['direction:out', `topic:${topic}`, 'type:kafka'])
|
|
17
|
+
pathwayCtx = encodePathwayContext(dataStreamsContext)
|
|
18
|
+
}
|
|
10
19
|
const span = this.startSpan({
|
|
11
20
|
resource: topic,
|
|
12
21
|
meta: {
|
|
@@ -17,9 +26,12 @@ class KafkajsProducerPlugin extends ProducerPlugin {
|
|
|
17
26
|
'kafka.batch_size': messages.length
|
|
18
27
|
}
|
|
19
28
|
})
|
|
20
|
-
|
|
29
|
+
if (bootstrapServers) {
|
|
30
|
+
span.setTag(BOOTSTRAP_SERVERS_KEY, bootstrapServers)
|
|
31
|
+
}
|
|
21
32
|
for (const message of messages) {
|
|
22
33
|
if (typeof message === 'object') {
|
|
34
|
+
if (this.config.dsmEnabled) message.headers['dd-pathway-ctx'] = pathwayCtx
|
|
23
35
|
this.tracer.inject(span, 'text_map', message.headers)
|
|
24
36
|
}
|
|
25
37
|
}
|
|
@@ -5,17 +5,19 @@ const DatabasePlugin = require('../../dd-trace/src/plugins/database')
|
|
|
5
5
|
class MongodbCorePlugin extends DatabasePlugin {
|
|
6
6
|
static get id () { return 'mongodb-core' }
|
|
7
7
|
static get component () { return 'mongodb' }
|
|
8
|
-
|
|
8
|
+
// avoid using db.name for peer.service since it includes the collection name
|
|
9
|
+
// should be removed if one day this will be fixed
|
|
10
|
+
static get peerServicePrecursors () { return [] }
|
|
9
11
|
start ({ ns, ops, options = {}, name }) {
|
|
10
12
|
const query = getQuery(ops)
|
|
11
13
|
const resource = truncate(getResource(this, ns, query, name))
|
|
12
|
-
|
|
13
14
|
this.startSpan(this.operationName(), {
|
|
14
15
|
service: this.serviceName(this.config),
|
|
15
16
|
resource,
|
|
16
17
|
type: 'mongodb',
|
|
17
18
|
kind: 'client',
|
|
18
19
|
meta: {
|
|
20
|
+
// this is not technically correct since it includes the collection but we changing will break customer stuff
|
|
19
21
|
'db.name': ns,
|
|
20
22
|
'mongodb.query': query,
|
|
21
23
|
'out.host': options.host,
|
|
@@ -23,6 +25,15 @@ class MongodbCorePlugin extends DatabasePlugin {
|
|
|
23
25
|
}
|
|
24
26
|
})
|
|
25
27
|
}
|
|
28
|
+
|
|
29
|
+
getPeerService (tags) {
|
|
30
|
+
const ns = tags['db.name']
|
|
31
|
+
if (ns && tags['peer.service'] === undefined) {
|
|
32
|
+
// the mongo ns is either dbName either dbName.collection. So we keep the first part
|
|
33
|
+
tags['peer.service'] = ns.split('.', 1)[0]
|
|
34
|
+
}
|
|
35
|
+
return super.getPeerService(tags)
|
|
36
|
+
}
|
|
26
37
|
}
|
|
27
38
|
|
|
28
39
|
function getQuery (cmd) {
|
|
@@ -100,7 +100,7 @@ class OpenApiPlugin extends TracingPlugin {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
// createChatCompletion, createCompletion
|
|
103
|
-
if (
|
|
103
|
+
if (typeof payload.logit_bias === 'object' && payload.logit_bias) {
|
|
104
104
|
for (const [tokenId, bias] of Object.entries(payload.logit_bias)) {
|
|
105
105
|
tags[`openai.request.logit_bias.${tokenId}`] = bias
|
|
106
106
|
}
|
|
@@ -264,6 +264,8 @@ function retrieveModelRequestExtraction (tags, payload) {
|
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
function createChatCompletionRequestExtraction (tags, payload, store) {
|
|
267
|
+
if (!defensiveArrayLength(payload.messages)) return
|
|
268
|
+
|
|
267
269
|
store.messages = payload.messages
|
|
268
270
|
for (let i = 0; i < payload.messages.length; i++) {
|
|
269
271
|
const message = payload.messages[i]
|
|
@@ -411,7 +413,7 @@ function createFineTuneRequestExtraction (tags, body) {
|
|
|
411
413
|
tags['openai.request.compute_classification_metrics'] = body.compute_classification_metrics
|
|
412
414
|
tags['openai.request.classification_n_classes'] = body.classification_n_classes
|
|
413
415
|
tags['openai.request.classification_positive_class'] = body.classification_positive_class
|
|
414
|
-
tags['openai.request.classification_betas_count'] = body.classification_betas
|
|
416
|
+
tags['openai.request.classification_betas_count'] = defensiveArrayLength(body.classification_betas)
|
|
415
417
|
}
|
|
416
418
|
|
|
417
419
|
function commonFineTuneResponseExtraction (tags, body) {
|
|
@@ -521,6 +523,7 @@ function commonCreateResponseExtraction (tags, body, store) {
|
|
|
521
523
|
|
|
522
524
|
// createCompletion, createChatCompletion, createEdit, createEmbedding
|
|
523
525
|
function usageExtraction (tags, body) {
|
|
526
|
+
if (typeof body.usage !== 'object' || !body.usage) return
|
|
524
527
|
tags['openai.response.usage.prompt_tokens'] = body.usage.prompt_tokens
|
|
525
528
|
tags['openai.response.usage.completion_tokens'] = body.usage.completion_tokens
|
|
526
529
|
tags['openai.response.usage.total_tokens'] = body.usage.total_tokens
|
|
@@ -675,4 +678,8 @@ function normalizeStringOrTokenArray (input, truncate = true) {
|
|
|
675
678
|
return truncate ? truncateText(normalized) : normalized
|
|
676
679
|
}
|
|
677
680
|
|
|
681
|
+
function defensiveArrayLength (maybeArray) {
|
|
682
|
+
return Array.isArray(maybeArray) ? maybeArray.length : undefined
|
|
683
|
+
}
|
|
684
|
+
|
|
678
685
|
module.exports = OpenApiPlugin
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const DogStatsDClient = require('../../dd-trace/src/dogstatsd')
|
|
3
|
+
const { DogStatsDClient, NoopDogStatsDClient } = require('../../dd-trace/src/dogstatsd')
|
|
4
4
|
const ExternalLogger = require('../../dd-trace/src/external-logger/src')
|
|
5
5
|
|
|
6
6
|
const FLUSH_INTERVAL = 10 * 1000
|
|
@@ -10,15 +10,19 @@ let logger = null
|
|
|
10
10
|
let interval = null
|
|
11
11
|
|
|
12
12
|
module.exports.init = function (tracerConfig) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
if (tracerConfig.dogstatsd) {
|
|
14
|
+
metrics = new DogStatsDClient({
|
|
15
|
+
host: tracerConfig.dogstatsd.hostname,
|
|
16
|
+
port: tracerConfig.dogstatsd.port,
|
|
17
|
+
tags: [
|
|
18
|
+
`service:${tracerConfig.tags.service}`,
|
|
19
|
+
`env:${tracerConfig.tags.env}`,
|
|
20
|
+
`version:${tracerConfig.tags.version}`
|
|
21
|
+
]
|
|
22
|
+
})
|
|
23
|
+
} else {
|
|
24
|
+
metrics = new NoopDogStatsDClient()
|
|
25
|
+
}
|
|
22
26
|
|
|
23
27
|
logger = new ExternalLogger({
|
|
24
28
|
ddsource: 'openai',
|