dd-trace 6.0.0-pre-ac0fc13 → 6.0.0-pre-a99e5ea
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/index.d.ts +20 -0
- package/package.json +3 -3
- package/packages/datadog-instrumentations/src/apollo.js +101 -0
- package/packages/datadog-instrumentations/src/cucumber.js +2 -1
- package/packages/datadog-instrumentations/src/grpc/server.js +3 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/jest.js +7 -5
- package/packages/datadog-instrumentations/src/mocha.js +4 -1
- package/packages/datadog-plugin-amqplib/src/consumer.js +5 -4
- package/packages/datadog-plugin-amqplib/src/producer.js +3 -4
- package/packages/datadog-plugin-apollo/src/gateway/execute.js +12 -0
- package/packages/datadog-plugin-apollo/src/gateway/fetch.js +36 -0
- package/packages/datadog-plugin-apollo/src/gateway/index.js +36 -0
- package/packages/datadog-plugin-apollo/src/gateway/plan.js +13 -0
- package/packages/datadog-plugin-apollo/src/gateway/postprocessing.js +12 -0
- package/packages/datadog-plugin-apollo/src/gateway/request.js +139 -0
- package/packages/datadog-plugin-apollo/src/gateway/validate.js +21 -0
- package/packages/datadog-plugin-apollo/src/index.js +15 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -11
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +3 -6
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +5 -7
- package/packages/datadog-plugin-cucumber/src/index.js +2 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +2 -2
- package/packages/datadog-plugin-jest/src/index.js +2 -2
- package/packages/datadog-plugin-kafkajs/src/consumer.js +4 -3
- package/packages/datadog-plugin-kafkajs/src/producer.js +3 -5
- package/packages/datadog-plugin-mocha/src/index.js +2 -2
- package/packages/datadog-plugin-rhea/src/consumer.js +5 -3
- package/packages/datadog-plugin-rhea/src/producer.js +3 -4
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +23 -12
- package/packages/dd-trace/src/appsec/iast/index.js +10 -0
- package/packages/dd-trace/src/appsec/iast/path-line.js +9 -6
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +6 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-telemetry.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +14 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +1 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/iast-metric.js +34 -27
- package/packages/dd-trace/src/appsec/iast/telemetry/namespaces.js +39 -11
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +7 -6
- package/packages/dd-trace/src/appsec/remote_config/index.js +1 -1
- package/packages/dd-trace/src/appsec/reporter.js +24 -11
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +0 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +6 -1
- package/packages/dd-trace/src/config.js +0 -3
- package/packages/dd-trace/src/data_streams_context.js +1 -1
- package/packages/dd-trace/src/datastreams/pathway.js +58 -1
- package/packages/dd-trace/src/datastreams/processor.js +3 -5
- package/packages/dd-trace/src/lambda/runtime/ritm.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +21 -2
- package/packages/dd-trace/src/opentracing/span.js +2 -0
- package/packages/dd-trace/src/opentracing/span_context.js +1 -0
- package/packages/dd-trace/src/plugins/apollo.js +50 -0
- package/packages/dd-trace/src/plugins/composite.js +1 -0
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/tracing.js +6 -2
- package/packages/dd-trace/src/plugins/util/test.js +2 -2
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +24 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +24 -0
- package/packages/dd-trace/src/telemetry/index.js +15 -4
- package/packages/dd-trace/src/tracer.js +3 -3
- package/CONTRIBUTING.md +0 -171
- package/MIGRATING.md +0 -224
- package/packages/dd-trace/src/external-logger/test/index.spec.js +0 -147
- package/scripts/check-proposal-labels.js +0 -71
- package/scripts/check_licenses.js +0 -69
- package/scripts/helpers/color.js +0 -8
- package/scripts/helpers/exec.js +0 -22
- package/scripts/helpers/title.js +0 -15
- package/scripts/install_plugin_modules.js +0 -248
- package/scripts/publish_docs.js +0 -21
- package/scripts/st.js +0 -105
package/index.d.ts
CHANGED
|
@@ -137,8 +137,10 @@ interface Tracer extends opentracing.Tracer {
|
|
|
137
137
|
// is doesn't need to be exported for Tracer
|
|
138
138
|
/** @hidden */
|
|
139
139
|
interface Plugins {
|
|
140
|
+
"aerospike": tracer.plugins.aerospike;
|
|
140
141
|
"amqp10": tracer.plugins.amqp10;
|
|
141
142
|
"amqplib": tracer.plugins.amqplib;
|
|
143
|
+
"apollo": tracer.plugins.apollo;
|
|
142
144
|
"aws-sdk": tracer.plugins.aws_sdk;
|
|
143
145
|
"bunyan": tracer.plugins.bunyan;
|
|
144
146
|
"cassandra-driver": tracer.plugins.cassandra_driver;
|
|
@@ -1098,6 +1100,12 @@ declare namespace tracer {
|
|
|
1098
1100
|
meta?: boolean;
|
|
1099
1101
|
}
|
|
1100
1102
|
|
|
1103
|
+
/**
|
|
1104
|
+
* This plugin automatically instruments the
|
|
1105
|
+
* [aerospike](https://github.com/aerospike/aerospike-client-nodejs) for module versions >= v3.16.2.
|
|
1106
|
+
*/
|
|
1107
|
+
interface aerospike extends Instrumentation {}
|
|
1108
|
+
|
|
1101
1109
|
/**
|
|
1102
1110
|
* This plugin automatically instruments the
|
|
1103
1111
|
* [amqp10](https://github.com/noodlefrenzy/node-amqp10) module.
|
|
@@ -1110,6 +1118,14 @@ declare namespace tracer {
|
|
|
1110
1118
|
*/
|
|
1111
1119
|
interface amqplib extends Instrumentation {}
|
|
1112
1120
|
|
|
1121
|
+
/**
|
|
1122
|
+
* Currently this plugin automatically instruments
|
|
1123
|
+
* [@apollo/gateway](https://github.com/apollographql/federation) for module versions >= v2.3.0.
|
|
1124
|
+
* This module uses graphql operations to service requests & thus generates graphql spans.
|
|
1125
|
+
* We recommend disabling the graphql plugin if you only want to trace @apollo/gateway
|
|
1126
|
+
*/
|
|
1127
|
+
interface apollo extends Instrumentation {}
|
|
1128
|
+
|
|
1113
1129
|
/**
|
|
1114
1130
|
* This plugin automatically instruments the
|
|
1115
1131
|
* [aws-sdk](https://github.com/aws/aws-sdk-js) module.
|
|
@@ -1624,6 +1640,10 @@ declare namespace tracer {
|
|
|
1624
1640
|
* The service name to be used for this plugin. If a function is used, it will be passed the connection parameters and its return value will be used as the service name.
|
|
1625
1641
|
*/
|
|
1626
1642
|
service?: string | ((params: any) => string);
|
|
1643
|
+
/**
|
|
1644
|
+
* The database monitoring propagation mode to be used for this plugin.
|
|
1645
|
+
*/
|
|
1646
|
+
dbmPropagationMode?: string;
|
|
1627
1647
|
}
|
|
1628
1648
|
|
|
1629
1649
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "6.0.0-pre-
|
|
3
|
+
"version": "6.0.0-pre-a99e5ea",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -70,10 +70,10 @@
|
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
72
|
"@datadog/native-appsec": "7.1.0",
|
|
73
|
-
"@datadog/native-iast-rewriter": "2.
|
|
73
|
+
"@datadog/native-iast-rewriter": "2.3.0",
|
|
74
74
|
"@datadog/native-iast-taint-tracking": "1.7.0",
|
|
75
75
|
"@datadog/native-metrics": "^2.0.0",
|
|
76
|
-
"@datadog/pprof": "5.
|
|
76
|
+
"@datadog/pprof": "5.1.0",
|
|
77
77
|
"@datadog/sketches-js": "^2.1.0",
|
|
78
78
|
"@opentelemetry/api": "^1.0.0",
|
|
79
79
|
"@opentelemetry/core": "^1.14.0",
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const {
|
|
2
|
+
addHook,
|
|
3
|
+
channel
|
|
4
|
+
} = require('./helpers/instrument')
|
|
5
|
+
const shimmer = require('../../datadog-shimmer')
|
|
6
|
+
const tracingChannel = require('dc-polyfill').tracingChannel
|
|
7
|
+
|
|
8
|
+
const CHANNELS = {
|
|
9
|
+
'gateway.request': tracingChannel('apm:apollo:gateway:request'),
|
|
10
|
+
'gateway.plan': tracingChannel('apm:apollo:gateway:plan'),
|
|
11
|
+
'gateway.validate': tracingChannel('apm:apollo:gateway:validate'),
|
|
12
|
+
'gateway.execute': tracingChannel('apm:apollo:gateway:execute'),
|
|
13
|
+
'gateway.fetch': tracingChannel('apm:apollo:gateway:fetch'),
|
|
14
|
+
'gateway.postprocessing': tracingChannel('apm:apollo:gateway:postprocessing')
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const executorCh = channel('apm:apollo:gateway:request:executor')
|
|
18
|
+
const generalErrorCh = channel('apm:apollo:gateway:general:error')
|
|
19
|
+
|
|
20
|
+
function wrapExecutor (executor) {
|
|
21
|
+
return function (...args) {
|
|
22
|
+
const ctx = { requestContext: args[0], gateway: this }
|
|
23
|
+
executorCh.publish(ctx)
|
|
24
|
+
return executor.apply(this, args)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function wrapApolloGateway (ApolloGateway) {
|
|
29
|
+
class ApolloGatewayWrapper extends ApolloGateway {
|
|
30
|
+
constructor (...args) {
|
|
31
|
+
super(...args)
|
|
32
|
+
shimmer.wrap(this, 'executor', wrapExecutor)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return ApolloGatewayWrapper
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function wrapRecordExceptions (recordExceptions) {
|
|
39
|
+
return function wrappedRecordExceptions (...args) {
|
|
40
|
+
const errors = args[1]
|
|
41
|
+
// only the last exception in the array of exceptions will be reported on the span,
|
|
42
|
+
// this is mimicking apollo-gateways internal instrumentation
|
|
43
|
+
// TODO: should we consider a mechanism to report all exceptions? since this method aggregates all exceptions
|
|
44
|
+
// where as a span can only have one exception set on it at a time
|
|
45
|
+
generalErrorCh.publish({ error: errors[errors.length - 1] })
|
|
46
|
+
return recordExceptions.apply(this, args)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function wrapStartActiveSpan (startActiveSpan) {
|
|
51
|
+
return function (...args) {
|
|
52
|
+
const firstArg = args[0]
|
|
53
|
+
const cb = args[args.length - 1]
|
|
54
|
+
if (typeof firstArg !== 'string' || typeof cb !== 'function') return startActiveSpan.apply(this, args)
|
|
55
|
+
|
|
56
|
+
const method = CHANNELS[firstArg]
|
|
57
|
+
let ctx = {}
|
|
58
|
+
if (firstArg === 'gateway.fetch') {
|
|
59
|
+
ctx = { attributes: args[1].attributes }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
switch (firstArg) {
|
|
63
|
+
case 'gateway.plan' :
|
|
64
|
+
case 'gateway.validate': {
|
|
65
|
+
args[args.length - 1] = function (...callbackArgs) {
|
|
66
|
+
return method.traceSync(cb, ctx, this, ...callbackArgs)
|
|
67
|
+
}
|
|
68
|
+
break
|
|
69
|
+
}
|
|
70
|
+
case 'gateway.request':
|
|
71
|
+
case 'gateway.execute':
|
|
72
|
+
case 'gateway.postprocessing' :
|
|
73
|
+
case 'gateway.fetch': {
|
|
74
|
+
args[args.length - 1] = function (...callbackArgs) {
|
|
75
|
+
return method.tracePromise(cb, ctx, this, ...callbackArgs)
|
|
76
|
+
}
|
|
77
|
+
break
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return startActiveSpan.apply(this, args)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
addHook({ name: '@apollo/gateway', file: 'dist/utilities/opentelemetry.js', versions: ['>=2.3.0'] },
|
|
85
|
+
(obj) => {
|
|
86
|
+
const newTracerObj = Object.create(obj.tracer)
|
|
87
|
+
shimmer.wrap(newTracerObj, 'startActiveSpan', wrapStartActiveSpan)
|
|
88
|
+
obj.tracer = newTracerObj
|
|
89
|
+
return obj
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
addHook({ name: '@apollo/gateway', file: 'dist/utilities/opentelemetry.js', versions: ['>=2.6.0'] },
|
|
93
|
+
(obj) => {
|
|
94
|
+
shimmer.wrap(obj, 'recordExceptions', wrapRecordExceptions)
|
|
95
|
+
return obj
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
addHook({ name: '@apollo/gateway', versions: ['>=2.3.0'] }, (gateway) => {
|
|
99
|
+
shimmer.wrap(gateway, 'ApolloGateway', wrapApolloGateway)
|
|
100
|
+
return gateway
|
|
101
|
+
})
|
|
@@ -92,7 +92,8 @@ function getStatusFromResultLatest (result) {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
function isNewTest (testSuite, testName) {
|
|
95
|
-
|
|
95
|
+
const testsForSuite = knownTests.cucumber?.[testSuite] || []
|
|
96
|
+
return !testsForSuite.includes(testName)
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
function getTestStatusFromRetries (testStatuses) {
|
|
@@ -92,7 +92,9 @@ function createWrapEmit (call, ctx, onCancel) {
|
|
|
92
92
|
finishChannel.publish(ctx)
|
|
93
93
|
call.removeListener('cancelled', onCancel)
|
|
94
94
|
break
|
|
95
|
-
|
|
95
|
+
// Streams are always cancelled before `finish` since 1.10.0 so we have
|
|
96
|
+
// to use `prefinish` instead to avoid cancellation false positives.
|
|
97
|
+
case 'prefinish':
|
|
96
98
|
if (call.status) {
|
|
97
99
|
updateChannel.publish(call.status)
|
|
98
100
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module.exports = {
|
|
4
4
|
'@apollo/server': () => require('../apollo-server'),
|
|
5
|
+
'@apollo/gateway': () => require('../apollo'),
|
|
5
6
|
'apollo-server-core': () => require('../apollo-server-core'),
|
|
6
7
|
'@aws-sdk/smithy-client': () => require('../aws-sdk'),
|
|
7
8
|
'@cucumber/cucumber': () => require('../cucumber'),
|
|
@@ -140,14 +140,16 @@ function getWrappedEnvironment (BaseEnvironment, jestVersion) {
|
|
|
140
140
|
// Function that receives a list of known tests for a test service and
|
|
141
141
|
// returns the ones that belong to the current suite
|
|
142
142
|
getKnownTestsForSuite (knownTests) {
|
|
143
|
+
if (this.knownTestsForThisSuite) {
|
|
144
|
+
return this.knownTestsForThisSuite
|
|
145
|
+
}
|
|
143
146
|
let knownTestsForSuite = knownTests
|
|
144
|
-
// If jest
|
|
145
|
-
|
|
147
|
+
// If jest is using workers, known tests are serialized to json.
|
|
148
|
+
// If jest runs in band, they are not.
|
|
149
|
+
if (typeof knownTestsForSuite === 'string') {
|
|
146
150
|
knownTestsForSuite = JSON.parse(knownTestsForSuite)
|
|
147
151
|
}
|
|
148
|
-
return knownTestsForSuite
|
|
149
|
-
.filter(test => test.includes(this.testSuite))
|
|
150
|
-
.map(test => test.replace(`jest.${this.testSuite}.`, '').trim())
|
|
152
|
+
return knownTestsForSuite.jest?.[this.testSuite] || []
|
|
151
153
|
}
|
|
152
154
|
|
|
153
155
|
// Add the `add_test` event we don't have the test object yet, so
|
|
@@ -106,7 +106,10 @@ function getTestFullName (test) {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
function isNewTest (test) {
|
|
109
|
-
|
|
109
|
+
const testSuite = getTestSuitePath(test.file, process.cwd())
|
|
110
|
+
const testName = removeEfdStringFromTestName(test.fullTitle())
|
|
111
|
+
const testsForSuite = knownTests.mocha?.[testSuite] || []
|
|
112
|
+
return !testsForSuite.includes(testName)
|
|
110
113
|
}
|
|
111
114
|
|
|
112
115
|
function retryTest (test) {
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const { TEXT_MAP } = require('../../../ext/formats')
|
|
4
4
|
const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
|
|
5
|
-
const { getAmqpMessageSize
|
|
5
|
+
const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams/processor')
|
|
6
|
+
const { DsmPathwayCodec } = require('../../dd-trace/src/datastreams/pathway')
|
|
6
7
|
const { getResourceName } = require('./util')
|
|
7
8
|
|
|
8
9
|
class AmqplibConsumerPlugin extends ConsumerPlugin {
|
|
@@ -29,12 +30,12 @@ class AmqplibConsumerPlugin extends ConsumerPlugin {
|
|
|
29
30
|
})
|
|
30
31
|
|
|
31
32
|
if (
|
|
32
|
-
this.config.dsmEnabled &&
|
|
33
|
-
message
|
|
33
|
+
this.config.dsmEnabled && message?.properties?.headers &&
|
|
34
|
+
DsmPathwayCodec.contextExists(message.properties.headers)
|
|
34
35
|
) {
|
|
35
36
|
const payloadSize = getAmqpMessageSize({ headers: message.properties.headers, content: message.content })
|
|
36
37
|
const queue = fields.queue ? fields.queue : fields.routingKey
|
|
37
|
-
this.tracer.decodeDataStreamsContext(message.properties.headers
|
|
38
|
+
this.tracer.decodeDataStreamsContext(message.properties.headers)
|
|
38
39
|
this.tracer
|
|
39
40
|
.setCheckpoint(['direction:in', `topic:${queue}`, 'type:rabbitmq'], span, payloadSize)
|
|
40
41
|
}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const { TEXT_MAP } = require('../../../ext/formats')
|
|
4
4
|
const { CLIENT_PORT_KEY } = require('../../dd-trace/src/constants')
|
|
5
5
|
const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
|
|
6
|
-
const {
|
|
7
|
-
const { getAmqpMessageSize
|
|
6
|
+
const { DsmPathwayCodec } = require('../../dd-trace/src/datastreams/pathway')
|
|
7
|
+
const { getAmqpMessageSize } = require('../../dd-trace/src/datastreams/processor')
|
|
8
8
|
const { getResourceName } = require('./util')
|
|
9
9
|
|
|
10
10
|
class AmqplibProducerPlugin extends ProducerPlugin {
|
|
@@ -40,8 +40,7 @@ class AmqplibProducerPlugin extends ProducerPlugin {
|
|
|
40
40
|
.setCheckpoint(
|
|
41
41
|
['direction:out', `exchange:${fields.exchange}`, `has_routing_key:${hasRoutingKey}`, 'type:rabbitmq']
|
|
42
42
|
, span, payloadSize)
|
|
43
|
-
|
|
44
|
-
fields.headers[CONTEXT_PROPAGATION_KEY] = pathwayCtx
|
|
43
|
+
DsmPathwayCodec.encode(dataStreamsContext, fields.headers)
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
|
|
4
|
+
|
|
5
|
+
class ApolloGatewayExecutePlugin extends ApolloBasePlugin {
|
|
6
|
+
static get operation () { return 'execute' }
|
|
7
|
+
static get prefix () {
|
|
8
|
+
return 'tracing:apm:apollo:gateway:execute'
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = ApolloGatewayExecutePlugin
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { storage } = require('../../../datadog-core')
|
|
4
|
+
const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
|
|
5
|
+
|
|
6
|
+
class ApolloGatewayFetchPlugin extends ApolloBasePlugin {
|
|
7
|
+
static get operation () { return 'fetch' }
|
|
8
|
+
static get prefix () {
|
|
9
|
+
return 'tracing:apm:apollo:gateway:fetch'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
bindStart (ctx) {
|
|
13
|
+
const store = storage.getStore()
|
|
14
|
+
const childOf = store ? store.span : null
|
|
15
|
+
|
|
16
|
+
const spanData = {
|
|
17
|
+
childOf,
|
|
18
|
+
service: this.getServiceName(),
|
|
19
|
+
type: this.constructor.type,
|
|
20
|
+
meta: {}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const serviceName = ctx?.attributes?.service
|
|
24
|
+
|
|
25
|
+
if (serviceName) { spanData.meta['serviceName'] = serviceName }
|
|
26
|
+
|
|
27
|
+
const span = this.startSpan(this.getOperationName(), spanData, false)
|
|
28
|
+
|
|
29
|
+
ctx.parentStore = store
|
|
30
|
+
ctx.currentStore = { ...store, span }
|
|
31
|
+
|
|
32
|
+
return ctx.currentStore
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = ApolloGatewayFetchPlugin
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { storage } = require('../../../datadog-core')
|
|
4
|
+
const CompositePlugin = require('../../../dd-trace/src/plugins/composite')
|
|
5
|
+
const ApolloGatewayExecutePlugin = require('./execute')
|
|
6
|
+
const ApolloGatewayPostProcessingPlugin = require('./postprocessing')
|
|
7
|
+
const ApolloGatewayRequestPlugin = require('./request')
|
|
8
|
+
const ApolloGatewayPlanPlugin = require('./plan')
|
|
9
|
+
const ApolloGatewayValidatePlugin = require('./validate')
|
|
10
|
+
const ApolloGatewayFetchPlugin = require('./fetch')
|
|
11
|
+
|
|
12
|
+
class ApolloGatewayPlugin extends CompositePlugin {
|
|
13
|
+
static get id () { return 'gateway' }
|
|
14
|
+
static get plugins () {
|
|
15
|
+
return {
|
|
16
|
+
execute: ApolloGatewayExecutePlugin,
|
|
17
|
+
postprocessing: ApolloGatewayPostProcessingPlugin,
|
|
18
|
+
request: ApolloGatewayRequestPlugin,
|
|
19
|
+
plan: ApolloGatewayPlanPlugin,
|
|
20
|
+
fetch: ApolloGatewayFetchPlugin,
|
|
21
|
+
validate: ApolloGatewayValidatePlugin
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
constructor (...args) {
|
|
26
|
+
super(...args)
|
|
27
|
+
this.addSub('apm:apollo:gateway:general:error', (ctx) => {
|
|
28
|
+
const store = storage.getStore()
|
|
29
|
+
const span = store?.span
|
|
30
|
+
if (!span) return
|
|
31
|
+
span.setTag('error', ctx.error)
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = ApolloGatewayPlugin
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
|
|
5
|
+
|
|
6
|
+
class ApolloGatewayPlanPlugin extends ApolloBasePlugin {
|
|
7
|
+
static get operation () { return 'plan' }
|
|
8
|
+
static get prefix () {
|
|
9
|
+
return 'tracing:apm:apollo:gateway:plan'
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = ApolloGatewayPlanPlugin
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
|
|
4
|
+
|
|
5
|
+
class ApolloGatewayPostProcessingPlugin extends ApolloBasePlugin {
|
|
6
|
+
static get operation () { return 'postprocessing' }
|
|
7
|
+
static get prefix () {
|
|
8
|
+
return 'tracing:apm:apollo:gateway:postprocessing'
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = ApolloGatewayPostProcessingPlugin
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { storage } = require('../../../datadog-core')
|
|
4
|
+
const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
|
|
5
|
+
|
|
6
|
+
let tools
|
|
7
|
+
|
|
8
|
+
const OPERATION_DEFINITION = 'OperationDefinition'
|
|
9
|
+
const FRAGMENT_DEFINITION = 'FragmentDefinition'
|
|
10
|
+
|
|
11
|
+
class ApolloGatewayRequestPlugin extends ApolloBasePlugin {
|
|
12
|
+
static get operation () { return 'request' }
|
|
13
|
+
static get prefix () {
|
|
14
|
+
return 'tracing:apm:apollo:gateway:request'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
constructor (...args) {
|
|
18
|
+
super(...args)
|
|
19
|
+
this.addSub('apm:apollo:gateway:request:executor', (ctx) => {
|
|
20
|
+
if (ctx.requestContext || ctx.gateway) {
|
|
21
|
+
this.requestContext = ctx
|
|
22
|
+
} else {
|
|
23
|
+
this.requestContext = {}
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
bindStart (ctx) {
|
|
29
|
+
const store = storage.getStore()
|
|
30
|
+
const childOf = store ? store.span : null
|
|
31
|
+
const spanData = {
|
|
32
|
+
childOf,
|
|
33
|
+
service: this.serviceName(
|
|
34
|
+
{ id: `${this.constructor.id}.${this.constructor.operation}`, pluginConfig: this.config }),
|
|
35
|
+
type: this.constructor.type,
|
|
36
|
+
kind: this.constructor.kind,
|
|
37
|
+
meta: {}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const { requestContext, gateway } = this.requestContext
|
|
41
|
+
|
|
42
|
+
if (requestContext?.operationName) {
|
|
43
|
+
spanData.meta['graphql.operation.name'] = requestContext.operationName
|
|
44
|
+
}
|
|
45
|
+
if (gateway?.config?.telemetry?.includeDocument !== false && requestContext?.source) {
|
|
46
|
+
spanData.meta['graphql.source'] = requestContext.source
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const operationContext =
|
|
50
|
+
buildOperationContext(gateway.schema, requestContext.document, requestContext.request.operationName)
|
|
51
|
+
|
|
52
|
+
if (operationContext?.operation?.operation) {
|
|
53
|
+
const document = requestContext?.document
|
|
54
|
+
const type = operationContext?.operation?.operation
|
|
55
|
+
const name = operationContext?.operation?.name && operationContext?.operation?.name?.value
|
|
56
|
+
|
|
57
|
+
spanData['resource'] = getSignature(document, name, type, this?.config?.signature)
|
|
58
|
+
spanData.meta['graphql.operation.type'] = type
|
|
59
|
+
}
|
|
60
|
+
const span = this.startSpan(this.operationName({ id: `${this.constructor.id}.${this.constructor.operation}` }),
|
|
61
|
+
spanData, false)
|
|
62
|
+
|
|
63
|
+
ctx.parentStore = store
|
|
64
|
+
ctx.currentStore = { ...store, span }
|
|
65
|
+
return ctx.currentStore
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
asyncStart (ctx) {
|
|
69
|
+
const errors = ctx?.result?.errors
|
|
70
|
+
// apollo gateway catches certain errors and returns them in the result object
|
|
71
|
+
// we want to capture these errors as spans
|
|
72
|
+
if (errors instanceof Array &&
|
|
73
|
+
errors[errors.length - 1] && errors[errors.length - 1].stack && errors[errors.length - 1].message) {
|
|
74
|
+
ctx.currentStore.span.setTag('error', errors[errors.length - 1])
|
|
75
|
+
}
|
|
76
|
+
ctx.currentStore.span.finish()
|
|
77
|
+
return ctx.parentStore
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
end () {
|
|
81
|
+
// do nothing to avoid ApolloBasePlugin's end method
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function buildOperationContext (schema, operationDocument, operationName) {
|
|
86
|
+
let operation
|
|
87
|
+
let operationCount = 0
|
|
88
|
+
const fragments = Object.create(null)
|
|
89
|
+
try {
|
|
90
|
+
operationDocument.definitions.forEach(definition => {
|
|
91
|
+
switch (definition.kind) {
|
|
92
|
+
case OPERATION_DEFINITION:
|
|
93
|
+
operationCount++
|
|
94
|
+
if (!operationName && operationCount > 1) {
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
if (
|
|
98
|
+
!operationName ||
|
|
99
|
+
(definition.name && definition.name.value === operationName)
|
|
100
|
+
) {
|
|
101
|
+
operation = definition
|
|
102
|
+
}
|
|
103
|
+
break
|
|
104
|
+
case FRAGMENT_DEFINITION:
|
|
105
|
+
fragments[definition.name.value] = definition
|
|
106
|
+
break
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
} catch (e) {
|
|
110
|
+
// safety net
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
schema,
|
|
115
|
+
operation,
|
|
116
|
+
fragments
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function getSignature (document, operationName, operationType, calculate) {
|
|
121
|
+
if (calculate !== false && tools !== false) {
|
|
122
|
+
try {
|
|
123
|
+
try {
|
|
124
|
+
tools = tools || require('./tools')
|
|
125
|
+
} catch (e) {
|
|
126
|
+
tools = false
|
|
127
|
+
throw e
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return tools.defaultEngineReportingSignature(document, operationName)
|
|
131
|
+
} catch (e) {
|
|
132
|
+
// safety net
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return [operationType, operationName].filter(val => val).join(' ')
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
module.exports = ApolloGatewayRequestPlugin
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const ApolloBasePlugin = require('../../../dd-trace/src/plugins/apollo')
|
|
4
|
+
|
|
5
|
+
class ApolloGatewayValidatePlugin extends ApolloBasePlugin {
|
|
6
|
+
static get operation () { return 'validate' }
|
|
7
|
+
static get prefix () {
|
|
8
|
+
return 'tracing:apm:apollo:gateway:validate'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
end (ctx) {
|
|
12
|
+
const result = ctx.result
|
|
13
|
+
if (result instanceof Array &&
|
|
14
|
+
result[result.length - 1] && result[result.length - 1].stack && result[result.length - 1].message) {
|
|
15
|
+
ctx.currentStore.span.setTag('error', result[result.length - 1])
|
|
16
|
+
}
|
|
17
|
+
ctx.currentStore.span.finish()
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = ApolloGatewayValidatePlugin
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const CompositePlugin = require('../../dd-trace/src/plugins/composite')
|
|
4
|
+
const ApolloGatewayPlugin = require('./gateway')
|
|
5
|
+
|
|
6
|
+
class ApolloPlugin extends CompositePlugin {
|
|
7
|
+
static get id () { return 'apollo' }
|
|
8
|
+
static get plugins () {
|
|
9
|
+
return {
|
|
10
|
+
gateway: ApolloGatewayPlugin
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
module.exports = ApolloPlugin
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const {
|
|
3
|
-
CONTEXT_PROPAGATION_KEY,
|
|
4
3
|
getSizeOrZero
|
|
5
4
|
} = require('../../../dd-trace/src/datastreams/processor')
|
|
6
|
-
const {
|
|
5
|
+
const { DsmPathwayCodec } = require('../../../dd-trace/src/datastreams/pathway')
|
|
7
6
|
const log = require('../../../dd-trace/src/log')
|
|
8
7
|
const BaseAwsSdkPlugin = require('../base')
|
|
9
8
|
const { storage } = require('../../../datadog-core')
|
|
@@ -113,13 +112,10 @@ class Kinesis extends BaseAwsSdkPlugin {
|
|
|
113
112
|
const parsedAttributes = JSON.parse(Buffer.from(record.Data).toString())
|
|
114
113
|
|
|
115
114
|
if (
|
|
116
|
-
parsedAttributes &&
|
|
117
|
-
parsedAttributes._datadog &&
|
|
118
|
-
parsedAttributes._datadog[CONTEXT_PROPAGATION_KEY] &&
|
|
119
|
-
streamName
|
|
115
|
+
parsedAttributes?._datadog && streamName && DsmPathwayCodec.contextExists(parsedAttributes._datadog)
|
|
120
116
|
) {
|
|
121
117
|
const payloadSize = getSizeOrZero(record.Data)
|
|
122
|
-
this.tracer.decodeDataStreamsContext(
|
|
118
|
+
this.tracer.decodeDataStreamsContext(parsedAttributes._datadog)
|
|
123
119
|
this.tracer
|
|
124
120
|
.setCheckpoint(['direction:in', `topic:${streamName}`, 'type:kinesis'], span, payloadSize)
|
|
125
121
|
}
|
|
@@ -182,10 +178,7 @@ class Kinesis extends BaseAwsSdkPlugin {
|
|
|
182
178
|
if (this.config.dsmEnabled) {
|
|
183
179
|
parsedData._datadog = ddInfo
|
|
184
180
|
const dataStreamsContext = this.setDSMCheckpoint(span, parsedData, stream)
|
|
185
|
-
|
|
186
|
-
const pathwayCtx = encodePathwayContext(dataStreamsContext)
|
|
187
|
-
ddInfo[CONTEXT_PROPAGATION_KEY] = pathwayCtx.toJSON()
|
|
188
|
-
}
|
|
181
|
+
DsmPathwayCodec.encode(dataStreamsContext, ddInfo)
|
|
189
182
|
}
|
|
190
183
|
|
|
191
184
|
if (Object.keys(ddInfo).length !== 0) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
const {
|
|
3
|
-
const {
|
|
2
|
+
const { getHeadersSize } = require('../../../dd-trace/src/datastreams/processor')
|
|
3
|
+
const { DsmPathwayCodec } = require('../../../dd-trace/src/datastreams/pathway')
|
|
4
4
|
const log = require('../../../dd-trace/src/log')
|
|
5
5
|
const BaseAwsSdkPlugin = require('../base')
|
|
6
6
|
|
|
@@ -94,10 +94,7 @@ class Sns extends BaseAwsSdkPlugin {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
const dataStreamsContext = this.setDSMCheckpoint(span, params, topicArn)
|
|
97
|
-
|
|
98
|
-
const pathwayCtx = encodePathwayContext(dataStreamsContext)
|
|
99
|
-
ddInfo[CONTEXT_PROPAGATION_KEY] = pathwayCtx.toJSON()
|
|
100
|
-
}
|
|
97
|
+
DsmPathwayCodec.encode(dataStreamsContext, ddInfo)
|
|
101
98
|
}
|
|
102
99
|
|
|
103
100
|
if (Object.keys(ddInfo).length !== 0) {
|