dd-trace 3.12.1 → 3.15.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 +1 -0
- package/README.md +5 -5
- package/ci/init.js +3 -1
- package/index.d.ts +100 -1
- package/package.json +5 -4
- package/packages/datadog-instrumentations/src/aws-sdk.js +86 -0
- package/packages/datadog-instrumentations/src/cucumber.js +74 -15
- package/packages/datadog-instrumentations/src/cypress.js +1 -1
- package/packages/datadog-instrumentations/src/fs.js +358 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +24 -23
- package/packages/datadog-instrumentations/src/ldapjs.js +12 -2
- package/packages/datadog-instrumentations/src/mocha.js +10 -7
- package/packages/datadog-instrumentations/src/mongoose.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +7 -1
- package/packages/datadog-instrumentations/src/mysql2.js +7 -1
- package/packages/datadog-instrumentations/src/next.js +2 -1
- package/packages/datadog-instrumentations/src/playwright.js +263 -0
- package/packages/datadog-plugin-aws-sdk/src/base.js +12 -5
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +29 -24
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +31 -16
- package/packages/datadog-plugin-cucumber/src/index.js +42 -11
- package/packages/datadog-plugin-cypress/src/plugin.js +129 -4
- package/packages/datadog-plugin-cypress/src/support.js +5 -0
- package/packages/datadog-plugin-fs/src/index.js +45 -0
- package/packages/datadog-plugin-hapi/src/index.js +5 -1
- package/packages/datadog-plugin-http/src/server.js +1 -1
- package/packages/datadog-plugin-http2/src/server.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +40 -70
- package/packages/datadog-plugin-mocha/src/index.js +44 -64
- package/packages/datadog-plugin-mysql/src/index.js +8 -7
- package/packages/datadog-plugin-playwright/src/index.js +112 -0
- package/packages/datadog-shimmer/src/shimmer.js +28 -11
- package/packages/dd-trace/src/appsec/addresses.js +3 -1
- package/packages/dd-trace/src/appsec/blocking.js +35 -9
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +60 -0
- package/packages/dd-trace/src/appsec/iast/iast-context.js +6 -2
- package/packages/dd-trace/src/appsec/iast/index.js +3 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +5 -2
- package/packages/dd-trace/src/appsec/index.js +5 -5
- package/packages/dd-trace/src/appsec/recommended.json +320 -184
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +3 -0
- package/packages/dd-trace/src/appsec/reporter.js +14 -14
- package/packages/dd-trace/src/appsec/sdk/index.js +41 -0
- package/packages/dd-trace/src/appsec/sdk/noop.js +17 -0
- package/packages/dd-trace/src/appsec/sdk/set_user.js +30 -0
- package/packages/dd-trace/src/appsec/sdk/track_event.js +74 -0
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +73 -0
- package/packages/dd-trace/src/appsec/sdk/utils.js +10 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +1 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +1 -5
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +48 -11
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +7 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +4 -2
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +5 -3
- package/packages/dd-trace/src/config.js +63 -7
- package/packages/dd-trace/src/encode/0.4.js +1 -1
- package/packages/dd-trace/src/encode/0.5.js +1 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +44 -4
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +52 -37
- package/packages/dd-trace/src/encode/tags-processors.js +3 -2
- package/packages/dd-trace/src/exporters/common/request.js +10 -3
- package/packages/dd-trace/src/lambda/handler.js +5 -6
- package/packages/dd-trace/src/log/channels.js +47 -0
- package/packages/dd-trace/src/log/index.js +79 -0
- package/packages/dd-trace/src/log/writer.js +124 -0
- package/packages/dd-trace/src/metrics.js +18 -0
- package/packages/dd-trace/src/noop/proxy.js +5 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +188 -36
- package/packages/dd-trace/src/opentracing/propagation/tracestate.js +99 -0
- package/packages/dd-trace/src/opentracing/span.js +2 -1
- package/packages/dd-trace/src/opentracing/span_context.js +6 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +72 -12
- package/packages/dd-trace/src/plugins/index.js +2 -0
- package/packages/dd-trace/src/plugins/util/ci.js +13 -21
- package/packages/dd-trace/src/plugins/util/exec.js +2 -2
- package/packages/dd-trace/src/plugins/util/git.js +16 -1
- package/packages/dd-trace/src/{appsec → plugins/util}/ip_extractor.js +1 -1
- package/packages/dd-trace/src/plugins/util/test.js +53 -10
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +2 -7
- package/packages/dd-trace/src/plugins/util/web.js +11 -0
- package/packages/dd-trace/src/profiler.js +3 -0
- package/packages/dd-trace/src/profiling/config.js +8 -3
- package/packages/dd-trace/src/profiling/exporters/file.js +13 -2
- package/packages/dd-trace/src/profiling/profiler.js +23 -6
- package/packages/dd-trace/src/profiling/profilers/wall.js +1 -0
- package/packages/dd-trace/src/proxy.js +2 -0
- package/packages/dd-trace/src/span_processor.js +1 -1
- package/packages/dd-trace/src/span_sampler.js +68 -52
- package/packages/dd-trace/src/startup-log.js +3 -6
- package/packages/dd-trace/src/telemetry/index.js +23 -2
- package/packages/dd-trace/src/telemetry/send-data.js +4 -1
- package/packages/dd-trace/src/tracer.js +0 -16
- package/scripts/check-proposal-labels.js +71 -0
- package/packages/dd-trace/src/log.js +0 -143
- /package/packages/dd-trace/src/{appsec → plugins/util}/ip_blocklist.js +0 -0
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -57,6 +57,7 @@ dev,multer,MIT,Copyright 2014 Hage Yaapa
|
|
|
57
57
|
dev,msgpack-lite,MIT,Copyright 2015 Yusuke Kawasaki
|
|
58
58
|
dev,nock,MIT,Copyright 2017 Pedro Teixeira and other contributors
|
|
59
59
|
dev,nyc,ISC,Copyright 2015 Contributors
|
|
60
|
+
dev,pprof-format,MIT,Copyright 2022 Stephen Belanger
|
|
60
61
|
dev,proxyquire,MIT,Copyright 2013 Thorsten Lorenz
|
|
61
62
|
dev,rimraf,ISC,Copyright Isaac Z. Schlueter and Contributors
|
|
62
63
|
dev,sinon,BSD-3-Clause,Copyright 2010-2017 Christian Johansen
|
package/README.md
CHANGED
|
@@ -24,11 +24,11 @@ Most of the documentation for `dd-trace` is available on these webpages:
|
|
|
24
24
|
|
|
25
25
|
## Version Release Lines and Maintenance
|
|
26
26
|
|
|
27
|
-
| Release Line | Latest Version | Status |Initial Release | End of Life |
|
|
28
|
-
|
|
|
29
|
-
| [`v1`](https://github.com/DataDog/dd-trace-js/tree/v1.x) |  | **End of Life** | 2021-07-13 | 2022-02-25 |
|
|
30
|
-
| [`v2`](https://github.com/DataDog/dd-trace-js/tree/v2.x) |  | **Maintenance** | 2022-01-28 | 2023-08-15 |
|
|
31
|
-
| [`v3`](https://github.com/DataDog/dd-trace-js/tree/v3.x) |  | **Current** | 2022-08-15 | Unknown |
|
|
27
|
+
| Release Line | Latest Version | Node.js | Status |Initial Release | End of Life |
|
|
28
|
+
| :---: | :---: | :---: | :---: | :---: | :---: |
|
|
29
|
+
| [`v1`](https://github.com/DataDog/dd-trace-js/tree/v1.x) |  | `>= v12` | **End of Life** | 2021-07-13 | 2022-02-25 |
|
|
30
|
+
| [`v2`](https://github.com/DataDog/dd-trace-js/tree/v2.x) |  | `>= v12` | **Maintenance** | 2022-01-28 | 2023-08-15 |
|
|
31
|
+
| [`v3`](https://github.com/DataDog/dd-trace-js/tree/v3.x) |  | `>= v14` | **Current** | 2022-08-15 | Unknown |
|
|
32
32
|
|
|
33
33
|
We currently maintain two release lines, namely `v2` and `v3`.
|
|
34
34
|
Features and bug fixes that are merged are released to the `v3` line and, if appropriate, also the `v2` line.
|
package/ci/init.js
CHANGED
|
@@ -8,7 +8,8 @@ const options = {
|
|
|
8
8
|
tags: {
|
|
9
9
|
[ORIGIN_KEY]: 'ciapp-test'
|
|
10
10
|
},
|
|
11
|
-
isCiVisibility: true
|
|
11
|
+
isCiVisibility: true,
|
|
12
|
+
flushInterval: 5000
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
let shouldInit = true
|
|
@@ -34,6 +35,7 @@ so dd-trace will not be initialized.`)
|
|
|
34
35
|
|
|
35
36
|
if (shouldInit) {
|
|
36
37
|
tracer.init(options)
|
|
38
|
+
tracer.use('fs', false)
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
module.exports = tracer
|
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ClientRequest, IncomingMessage, ServerResponse } from "http";
|
|
1
|
+
import { ClientRequest, IncomingMessage, OutgoingMessage, ServerResponse } from "http";
|
|
2
2
|
import { LookupFunction } from 'net';
|
|
3
3
|
import * as opentracing from "opentracing";
|
|
4
4
|
import { SpanOptions } from "opentracing/lib/tracer";
|
|
@@ -115,6 +115,8 @@ export declare interface Tracer extends opentracing.Tracer {
|
|
|
115
115
|
* @returns {Tracer} The Tracer instance for chaining.
|
|
116
116
|
*/
|
|
117
117
|
setUser (user: User): Tracer;
|
|
118
|
+
|
|
119
|
+
appsec: Appsec;
|
|
118
120
|
}
|
|
119
121
|
|
|
120
122
|
export declare interface TraceOptions extends Analyzable {
|
|
@@ -219,6 +221,21 @@ export declare interface SpanSamplingRule {
|
|
|
219
221
|
name?: string
|
|
220
222
|
}
|
|
221
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Selection and priority order of context propagation injection and extraction mechanisms.
|
|
226
|
+
*/
|
|
227
|
+
export declare interface PropagationStyle {
|
|
228
|
+
/**
|
|
229
|
+
* Selection of context propagation injection mechanisms.
|
|
230
|
+
*/
|
|
231
|
+
inject: string[],
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Selection and priority order of context propagation extraction mechanisms.
|
|
235
|
+
*/
|
|
236
|
+
extract: string[]
|
|
237
|
+
}
|
|
238
|
+
|
|
222
239
|
/**
|
|
223
240
|
* List of options available to the tracer.
|
|
224
241
|
*/
|
|
@@ -537,6 +554,22 @@ export declare interface TracerOptions {
|
|
|
537
554
|
*/
|
|
538
555
|
pollInterval?: number,
|
|
539
556
|
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Whether to enable client IP collection from relevant IP headers
|
|
560
|
+
* @default false
|
|
561
|
+
*/
|
|
562
|
+
clientIpEnabled?: boolean
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Custom header name to source the http.client_ip tag from.
|
|
566
|
+
*/
|
|
567
|
+
clientIpHeader?: string,
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* The selection and priority order of context propagation injection and extraction mechanisms.
|
|
571
|
+
*/
|
|
572
|
+
propagationStyle?: string[] | PropagationStyle
|
|
540
573
|
}
|
|
541
574
|
|
|
542
575
|
/**
|
|
@@ -582,6 +615,65 @@ export declare interface User {
|
|
|
582
615
|
[key: string]: string | undefined
|
|
583
616
|
}
|
|
584
617
|
|
|
618
|
+
export declare interface Appsec {
|
|
619
|
+
/**
|
|
620
|
+
* Links a successful login event to the current trace. Will link the passed user to the current trace with Appsec.setUser() internally.
|
|
621
|
+
* @param {User} user Properties of the authenticated user. Accepts custom fields.
|
|
622
|
+
* @param {[key: string]: string} metadata Custom fields to link to the login success event.
|
|
623
|
+
*
|
|
624
|
+
* @beta This method is in beta and could change in future versions.
|
|
625
|
+
*/
|
|
626
|
+
trackUserLoginSuccessEvent(user: User, metadata?: { [key: string]: string }): void
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Links a failed login event to the current trace.
|
|
630
|
+
* @param {string} userId The user id of the attemped login.
|
|
631
|
+
* @param {boolean} exists If the user id exists.
|
|
632
|
+
* @param {[key: string]: string} metadata Custom fields to link to the login failure event.
|
|
633
|
+
*
|
|
634
|
+
* @beta This method is in beta and could change in future versions.
|
|
635
|
+
*/
|
|
636
|
+
trackUserLoginFailureEvent(userId: string, exists: boolean, metadata?: { [key: string]: string }): void
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* Links a custom event to the current trace.
|
|
640
|
+
* @param {string} eventName The name of the event.
|
|
641
|
+
* @param {[key: string]: string} metadata Custom fields to link to the event.
|
|
642
|
+
*
|
|
643
|
+
* @beta This method is in beta and could change in future versions.
|
|
644
|
+
*/
|
|
645
|
+
trackCustomEvent(eventName: string, metadata?: { [key: string]: string }): void
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Checks if the passed user should be blocked according to AppSec rules.
|
|
649
|
+
* If no user is linked to the current trace, will link the passed user to it.
|
|
650
|
+
* @param {User} user Properties of the authenticated user. Accepts custom fields.
|
|
651
|
+
* @return {boolean} Indicates whether the user should be blocked.
|
|
652
|
+
*
|
|
653
|
+
* @beta This method is in beta and could change in the future
|
|
654
|
+
*/
|
|
655
|
+
isUserBlocked(user: User): boolean
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Sends a "blocked" template response based on the request accept header and ends the response.
|
|
659
|
+
* **You should stop processing the request after calling this function!**
|
|
660
|
+
* @param {IncomingMessage} req Can be passed to force which request to act on. Optional.
|
|
661
|
+
* @param {OutgoingMessage} res Can be passed to force which response to act on. Optional.
|
|
662
|
+
* @return {boolean} Indicates if the action was successful.
|
|
663
|
+
*
|
|
664
|
+
* @beta This method is in beta and could change in the future
|
|
665
|
+
*/
|
|
666
|
+
blockRequest(req?: IncomingMessage, res?: OutgoingMessage): boolean
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Links an authenticated user to the current trace.
|
|
670
|
+
* @param {User} user Properties of the authenticated user. Accepts custom fields.
|
|
671
|
+
*
|
|
672
|
+
* @beta This method is in beta and could change in the future
|
|
673
|
+
*/
|
|
674
|
+
setUser(user: User): void
|
|
675
|
+
}
|
|
676
|
+
|
|
585
677
|
/** @hidden */
|
|
586
678
|
declare type anyObject = {
|
|
587
679
|
[key: string]: any;
|
|
@@ -669,6 +761,7 @@ interface Plugins {
|
|
|
669
761
|
"opensearch": plugins.opensearch;
|
|
670
762
|
"oracledb": plugins.oracledb;
|
|
671
763
|
"paperplane": plugins.paperplane;
|
|
764
|
+
"playwright": plugins.playwright;
|
|
672
765
|
"pg": plugins.pg;
|
|
673
766
|
"pino": plugins.pino;
|
|
674
767
|
"redis": plugins.redis;
|
|
@@ -1358,6 +1451,12 @@ declare namespace plugins {
|
|
|
1358
1451
|
*/
|
|
1359
1452
|
interface paperplane extends HttpServer {}
|
|
1360
1453
|
|
|
1454
|
+
/**
|
|
1455
|
+
* This plugin automatically instruments the
|
|
1456
|
+
* [playwright](https://github.com/microsoft/playwright) module.
|
|
1457
|
+
*/
|
|
1458
|
+
interface playwright extends Integration {}
|
|
1459
|
+
|
|
1361
1460
|
/**
|
|
1362
1461
|
* This plugin automatically instruments the
|
|
1363
1462
|
* [pg](https://node-postgres.com/) module.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.15.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -61,10 +61,10 @@
|
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@datadog/native-appsec": "2.0.0",
|
|
64
|
-
"@datadog/native-iast-rewriter": "
|
|
65
|
-
"@datadog/native-iast-taint-tracking": "1.1.
|
|
64
|
+
"@datadog/native-iast-rewriter": "2.0.1",
|
|
65
|
+
"@datadog/native-iast-taint-tracking": "1.1.1",
|
|
66
66
|
"@datadog/native-metrics": "^1.5.0",
|
|
67
|
-
"@datadog/pprof": "^
|
|
67
|
+
"@datadog/pprof": "^2.0.0",
|
|
68
68
|
"@datadog/sketches-js": "^2.1.0",
|
|
69
69
|
"crypto-randomuuid": "^1.0.0",
|
|
70
70
|
"diagnostics_channel": "^1.1.0",
|
|
@@ -120,6 +120,7 @@
|
|
|
120
120
|
"multer": "^1.4.5-lts.1",
|
|
121
121
|
"nock": "^11.3.3",
|
|
122
122
|
"nyc": "^15.1.0",
|
|
123
|
+
"pprof-format": "^2.0.7",
|
|
123
124
|
"proxyquire": "^1.8.0",
|
|
124
125
|
"rimraf": "^3.0.0",
|
|
125
126
|
"sinon": "^11.1.2",
|
|
@@ -39,6 +39,77 @@ function wrapRequest (send) {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
function wrapSmithySend (send) {
|
|
43
|
+
return function (command, ...args) {
|
|
44
|
+
const cb = args[args.length - 1]
|
|
45
|
+
const innerAr = new AsyncResource('apm:aws:request:inner')
|
|
46
|
+
const outerAr = new AsyncResource('apm:aws:request:outer')
|
|
47
|
+
const serviceIdentifier = this.config.serviceId.toLowerCase()
|
|
48
|
+
const channelSuffix = getChannelSuffix(serviceIdentifier)
|
|
49
|
+
const commandName = command.constructor.name
|
|
50
|
+
const clientName = this.constructor.name.replace(/Client$/, '')
|
|
51
|
+
const operation = `${commandName[0].toLowerCase()}${commandName.slice(1).replace(/Command$/, '')}`
|
|
52
|
+
const request = {
|
|
53
|
+
operation,
|
|
54
|
+
params: command.input
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const startCh = channel(`apm:aws:request:start:${channelSuffix}`)
|
|
58
|
+
const regionCh = channel(`apm:aws:request:region:${channelSuffix}`)
|
|
59
|
+
const completeChannel = channel(`apm:aws:request:complete:${channelSuffix}`)
|
|
60
|
+
const responseStartChannel = channel(`apm:aws:response:start:${channelSuffix}`)
|
|
61
|
+
const responseFinishChannel = channel(`apm:aws:response:finish:${channelSuffix}`)
|
|
62
|
+
|
|
63
|
+
return innerAr.runInAsyncScope(() => {
|
|
64
|
+
startCh.publish({
|
|
65
|
+
serviceIdentifier,
|
|
66
|
+
operation,
|
|
67
|
+
awsService: clientName,
|
|
68
|
+
request
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
// When the region is not set this never resolves so we can't await.
|
|
72
|
+
this.config.region().then(region => {
|
|
73
|
+
regionCh.publish(region)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
if (typeof cb === 'function') {
|
|
77
|
+
args[args.length - 1] = function (err, result) {
|
|
78
|
+
const message = getMessage(request, err, result)
|
|
79
|
+
|
|
80
|
+
completeChannel.publish(message)
|
|
81
|
+
|
|
82
|
+
outerAr.runInAsyncScope(() => {
|
|
83
|
+
responseStartChannel.publish(message)
|
|
84
|
+
|
|
85
|
+
cb.apply(this, arguments)
|
|
86
|
+
|
|
87
|
+
if (message.needsFinish) {
|
|
88
|
+
responseFinishChannel.publish(message.response.error)
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
} else { // always a promise
|
|
93
|
+
return send.call(this, command, ...args)
|
|
94
|
+
.then(
|
|
95
|
+
result => {
|
|
96
|
+
const message = getMessage(request, null, result)
|
|
97
|
+
completeChannel.publish(message)
|
|
98
|
+
return result
|
|
99
|
+
},
|
|
100
|
+
error => {
|
|
101
|
+
const message = getMessage(request, error)
|
|
102
|
+
completeChannel.publish(message)
|
|
103
|
+
throw error
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return send.call(this, command, ...args)
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
42
113
|
function wrapCb (cb, serviceName, request, ar) {
|
|
43
114
|
return function wrappedCb (err, response) {
|
|
44
115
|
const obj = { request, response }
|
|
@@ -71,6 +142,16 @@ function wrapCb (cb, serviceName, request, ar) {
|
|
|
71
142
|
}
|
|
72
143
|
}
|
|
73
144
|
|
|
145
|
+
function getMessage (request, error, result) {
|
|
146
|
+
const response = { request, error, ...result }
|
|
147
|
+
|
|
148
|
+
if (result && result.$metadata) {
|
|
149
|
+
response.requestId = result.$metadata.requestId
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return { request, response }
|
|
153
|
+
}
|
|
154
|
+
|
|
74
155
|
function getChannelSuffix (name) {
|
|
75
156
|
return [
|
|
76
157
|
'cloudwatchlogs',
|
|
@@ -85,6 +166,11 @@ function getChannelSuffix (name) {
|
|
|
85
166
|
].includes(name) ? name : 'default'
|
|
86
167
|
}
|
|
87
168
|
|
|
169
|
+
addHook({ name: '@aws-sdk/smithy-client', versions: ['>=3'] }, smithy => {
|
|
170
|
+
shimmer.wrap(smithy.Client.prototype, 'send', wrapSmithySend)
|
|
171
|
+
return smithy
|
|
172
|
+
})
|
|
173
|
+
|
|
88
174
|
addHook({ name: 'aws-sdk', versions: ['>=2.3.0'] }, AWS => {
|
|
89
175
|
shimmer.wrap(AWS.Request.prototype, 'promise', wrapRequest)
|
|
90
176
|
shimmer.wrap(AWS.config, 'setPromisesDependency', setPromisesDependency => {
|
|
@@ -3,15 +3,35 @@
|
|
|
3
3
|
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
4
4
|
const shimmer = require('../../datadog-shimmer')
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
6
|
+
const testStartCh = channel('ci:cucumber:test:start')
|
|
7
|
+
const testFinishCh = channel('ci:cucumber:test:finish') // used for test steps too
|
|
8
|
+
|
|
9
|
+
const testStepStartCh = channel('ci:cucumber:test-step:start')
|
|
10
|
+
|
|
9
11
|
const errorCh = channel('ci:cucumber:error')
|
|
12
|
+
|
|
13
|
+
const testSuiteStartCh = channel('ci:cucumber:test-suite:start')
|
|
14
|
+
const testSuiteFinishCh = channel('ci:cucumber:test-suite:finish')
|
|
15
|
+
|
|
16
|
+
const sessionStartCh = channel('ci:cucumber:session:start')
|
|
10
17
|
const sessionFinishCh = channel('ci:cucumber:session:finish')
|
|
11
18
|
|
|
12
19
|
// TODO: remove in a later major version
|
|
13
20
|
const patched = new WeakSet()
|
|
14
21
|
|
|
22
|
+
let pickleByFile = {}
|
|
23
|
+
const pickleResultByFile = {}
|
|
24
|
+
|
|
25
|
+
function getSuiteStatusFromTestStatuses (testStatuses) {
|
|
26
|
+
if (testStatuses.some(status => status === 'fail')) {
|
|
27
|
+
return 'fail'
|
|
28
|
+
}
|
|
29
|
+
if (testStatuses.every(status => status === 'skip')) {
|
|
30
|
+
return 'skip'
|
|
31
|
+
}
|
|
32
|
+
return 'pass'
|
|
33
|
+
}
|
|
34
|
+
|
|
15
35
|
function getStatusFromResult (result) {
|
|
16
36
|
if (result.status === 1) {
|
|
17
37
|
return { status: 'pass' }
|
|
@@ -44,13 +64,18 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
44
64
|
patched.add(pl)
|
|
45
65
|
|
|
46
66
|
shimmer.wrap(pl.prototype, 'run', run => function () {
|
|
47
|
-
if (!
|
|
67
|
+
if (!testStartCh.hasSubscribers) {
|
|
48
68
|
return run.apply(this, arguments)
|
|
49
69
|
}
|
|
50
70
|
|
|
51
71
|
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
52
72
|
return asyncResource.runInAsyncScope(() => {
|
|
53
|
-
|
|
73
|
+
const testSuiteFullPath = this.pickle.uri
|
|
74
|
+
|
|
75
|
+
if (!pickleResultByFile[testSuiteFullPath]) { // first test in suite
|
|
76
|
+
testSuiteStartCh.publish(testSuiteFullPath)
|
|
77
|
+
}
|
|
78
|
+
testStartCh.publish({ testName: this.pickle.name, fullTestSuite: testSuiteFullPath })
|
|
54
79
|
try {
|
|
55
80
|
const promise = run.apply(this, arguments)
|
|
56
81
|
promise.finally(() => {
|
|
@@ -58,7 +83,17 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
58
83
|
const { status, skipReason, errorMessage } = isLatestVersion
|
|
59
84
|
? getStatusFromResultLatest(result) : getStatusFromResult(result)
|
|
60
85
|
|
|
61
|
-
|
|
86
|
+
if (!pickleResultByFile[testSuiteFullPath]) {
|
|
87
|
+
pickleResultByFile[testSuiteFullPath] = [status]
|
|
88
|
+
} else {
|
|
89
|
+
pickleResultByFile[testSuiteFullPath].push(status)
|
|
90
|
+
}
|
|
91
|
+
// last test in suite
|
|
92
|
+
if (pickleResultByFile[testSuiteFullPath].length === pickleByFile[testSuiteFullPath].length) {
|
|
93
|
+
const testSuiteStatus = getSuiteStatusFromTestStatuses(pickleResultByFile[testSuiteFullPath])
|
|
94
|
+
testSuiteFinishCh.publish(testSuiteStatus)
|
|
95
|
+
}
|
|
96
|
+
testFinishCh.publish({ status, skipReason, errorMessage })
|
|
62
97
|
})
|
|
63
98
|
return promise
|
|
64
99
|
} catch (err) {
|
|
@@ -68,7 +103,7 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
68
103
|
})
|
|
69
104
|
})
|
|
70
105
|
shimmer.wrap(pl.prototype, 'runStep', runStep => function () {
|
|
71
|
-
if (!
|
|
106
|
+
if (!testStepStartCh.hasSubscribers) {
|
|
72
107
|
return runStep.apply(this, arguments)
|
|
73
108
|
}
|
|
74
109
|
const testStep = arguments[0]
|
|
@@ -82,7 +117,7 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
82
117
|
|
|
83
118
|
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
84
119
|
return asyncResource.runInAsyncScope(() => {
|
|
85
|
-
|
|
120
|
+
testStepStartCh.publish({ resource })
|
|
86
121
|
try {
|
|
87
122
|
const promise = runStep.apply(this, arguments)
|
|
88
123
|
|
|
@@ -90,7 +125,7 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
90
125
|
const { status, skipReason, errorMessage } = isLatestVersion
|
|
91
126
|
? getStatusFromResultLatest(result) : getStatusFromResult(result)
|
|
92
127
|
|
|
93
|
-
|
|
128
|
+
testFinishCh.publish({ isStep: true, status, skipReason, errorMessage })
|
|
94
129
|
})
|
|
95
130
|
return promise
|
|
96
131
|
} catch (err) {
|
|
@@ -129,16 +164,40 @@ addHook({
|
|
|
129
164
|
file: 'lib/runtime/test_case_runner.js'
|
|
130
165
|
}, testCaseHook)
|
|
131
166
|
|
|
167
|
+
function getPickleByFile (runtime) {
|
|
168
|
+
return runtime.pickleIds.reduce((acc, pickleId) => {
|
|
169
|
+
const test = runtime.eventDataCollector.getPickle(pickleId)
|
|
170
|
+
if (acc[test.uri]) {
|
|
171
|
+
acc[test.uri].push(test)
|
|
172
|
+
} else {
|
|
173
|
+
acc[test.uri] = [test]
|
|
174
|
+
}
|
|
175
|
+
return acc
|
|
176
|
+
}, {})
|
|
177
|
+
}
|
|
178
|
+
|
|
132
179
|
addHook({
|
|
133
180
|
name: '@cucumber/cucumber',
|
|
134
181
|
versions: ['>=7.0.0'],
|
|
135
182
|
file: 'lib/runtime/index.js'
|
|
136
|
-
}, (
|
|
137
|
-
shimmer.wrap(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
183
|
+
}, (runtimePackage, cucumberVersion) => {
|
|
184
|
+
shimmer.wrap(runtimePackage.default.prototype, 'start', start => async function () {
|
|
185
|
+
pickleByFile = getPickleByFile(this)
|
|
186
|
+
|
|
187
|
+
const processArgv = process.argv.slice(2).join(' ')
|
|
188
|
+
const command = process.env.npm_lifecycle_script || `cucumber-js ${processArgv}`
|
|
189
|
+
|
|
190
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
191
|
+
asyncResource.runInAsyncScope(() => {
|
|
192
|
+
sessionStartCh.publish({ command, frameworkVersion: cucumberVersion })
|
|
193
|
+
})
|
|
194
|
+
const success = await start.apply(this, arguments)
|
|
195
|
+
|
|
196
|
+
asyncResource.runInAsyncScope(() => {
|
|
197
|
+
sessionFinishCh.publish(success ? 'pass' : 'fail')
|
|
198
|
+
})
|
|
199
|
+
return success
|
|
141
200
|
})
|
|
142
201
|
|
|
143
|
-
return
|
|
202
|
+
return runtimePackage
|
|
144
203
|
})
|