dd-trace 5.101.0 → 5.103.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/ext/exporters.js +1 -0
- package/package.json +20 -17
- package/packages/datadog-esbuild/src/utils.js +2 -2
- package/packages/datadog-instrumentations/src/aerospike.js +2 -2
- package/packages/datadog-instrumentations/src/ai.js +9 -9
- package/packages/datadog-instrumentations/src/amqplib.js +6 -7
- package/packages/datadog-instrumentations/src/anthropic.js +10 -10
- package/packages/datadog-instrumentations/src/apollo-server-core.js +3 -3
- package/packages/datadog-instrumentations/src/apollo-server.js +5 -5
- package/packages/datadog-instrumentations/src/avsc.js +6 -6
- package/packages/datadog-instrumentations/src/aws-sdk.js +151 -67
- package/packages/datadog-instrumentations/src/azure-durable-functions.js +8 -8
- package/packages/datadog-instrumentations/src/bluebird.js +2 -2
- package/packages/datadog-instrumentations/src/body-parser.js +2 -2
- package/packages/datadog-instrumentations/src/cassandra-driver.js +7 -7
- package/packages/datadog-instrumentations/src/child_process.js +12 -12
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +41 -24
- package/packages/datadog-instrumentations/src/connect.js +7 -7
- package/packages/datadog-instrumentations/src/cookie-parser.js +4 -4
- package/packages/datadog-instrumentations/src/cookie.js +2 -2
- package/packages/datadog-instrumentations/src/couchbase.js +73 -238
- package/packages/datadog-instrumentations/src/crypto.js +4 -4
- package/packages/datadog-instrumentations/src/cucumber.js +78 -17
- package/packages/datadog-instrumentations/src/dns.js +0 -3
- package/packages/datadog-instrumentations/src/elasticsearch.js +8 -11
- package/packages/datadog-instrumentations/src/electron/preload.js +42 -0
- package/packages/datadog-instrumentations/src/electron.js +240 -0
- package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +6 -6
- package/packages/datadog-instrumentations/src/express-session.js +4 -4
- package/packages/datadog-instrumentations/src/express.js +10 -11
- package/packages/datadog-instrumentations/src/fastify.js +2 -2
- package/packages/datadog-instrumentations/src/fetch.js +5 -5
- package/packages/datadog-instrumentations/src/fs.js +14 -14
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +5 -7
- package/packages/datadog-instrumentations/src/google-genai.js +4 -4
- package/packages/datadog-instrumentations/src/graphql.js +13 -12
- package/packages/datadog-instrumentations/src/grpc/server.js +2 -2
- package/packages/datadog-instrumentations/src/hapi.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +9 -9
- package/packages/datadog-instrumentations/src/helpers/hook.js +4 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/kafka.js +41 -0
- package/packages/datadog-instrumentations/src/helpers/promise.js +2 -2
- package/packages/datadog-instrumentations/src/hono.js +2 -2
- package/packages/datadog-instrumentations/src/http/client.js +6 -6
- package/packages/datadog-instrumentations/src/http/server.js +9 -9
- package/packages/datadog-instrumentations/src/ioredis.js +16 -12
- package/packages/datadog-instrumentations/src/jest.js +382 -81
- package/packages/datadog-instrumentations/src/kafkajs.js +165 -174
- package/packages/datadog-instrumentations/src/knex.js +17 -17
- package/packages/datadog-instrumentations/src/koa.js +12 -12
- package/packages/datadog-instrumentations/src/ldapjs.js +5 -5
- package/packages/datadog-instrumentations/src/light-my-request.js +2 -2
- package/packages/datadog-instrumentations/src/limitd-client.js +4 -4
- package/packages/datadog-instrumentations/src/lodash.js +4 -4
- package/packages/datadog-instrumentations/src/mariadb.js +13 -13
- package/packages/datadog-instrumentations/src/memcached.js +2 -2
- package/packages/datadog-instrumentations/src/microgateway-core.js +2 -2
- package/packages/datadog-instrumentations/src/mocha/common.js +3 -3
- package/packages/datadog-instrumentations/src/mocha/main.js +85 -11
- package/packages/datadog-instrumentations/src/mocha/utils.js +133 -16
- package/packages/datadog-instrumentations/src/mocha/worker.js +7 -5
- package/packages/datadog-instrumentations/src/mongodb-core.js +42 -30
- package/packages/datadog-instrumentations/src/mongodb.js +5 -5
- package/packages/datadog-instrumentations/src/mongoose.js +21 -21
- package/packages/datadog-instrumentations/src/mquery.js +5 -5
- package/packages/datadog-instrumentations/src/multer.js +4 -4
- package/packages/datadog-instrumentations/src/mysql.js +16 -16
- package/packages/datadog-instrumentations/src/mysql2.js +4 -4
- package/packages/datadog-instrumentations/src/net.js +14 -8
- package/packages/datadog-instrumentations/src/nyc.js +5 -5
- package/packages/datadog-instrumentations/src/openai.js +19 -19
- package/packages/datadog-instrumentations/src/oracledb.js +6 -6
- package/packages/datadog-instrumentations/src/passport-utils.js +5 -5
- package/packages/datadog-instrumentations/src/pg.js +39 -25
- package/packages/datadog-instrumentations/src/pino.js +6 -10
- package/packages/datadog-instrumentations/src/playwright.js +445 -68
- package/packages/datadog-instrumentations/src/protobufjs.js +16 -16
- package/packages/datadog-instrumentations/src/redis.js +20 -12
- package/packages/datadog-instrumentations/src/restify.js +2 -2
- package/packages/datadog-instrumentations/src/router.js +12 -12
- package/packages/datadog-instrumentations/src/stripe.js +12 -12
- package/packages/datadog-instrumentations/src/vitest.js +107 -26
- package/packages/datadog-instrumentations/src/winston.js +4 -4
- package/packages/datadog-instrumentations/src/ws.js +7 -7
- package/packages/datadog-plugin-apollo/src/gateway/request.js +1 -21
- package/packages/datadog-plugin-aws-sdk/src/base.js +70 -28
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +20 -13
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +46 -36
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +34 -23
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +14 -15
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +74 -55
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +20 -18
- package/packages/datadog-plugin-aws-sdk/src/util.js +22 -0
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +6 -6
- package/packages/datadog-plugin-couchbase/src/index.js +58 -52
- package/packages/datadog-plugin-cucumber/src/index.js +5 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +215 -26
- package/packages/datadog-plugin-cypress/src/support.js +13 -1
- package/packages/datadog-plugin-electron/src/index.js +17 -0
- package/packages/datadog-plugin-electron/src/ipc.js +143 -0
- package/packages/datadog-plugin-electron/src/net.js +82 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -5
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +27 -18
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +3 -1
- package/packages/datadog-plugin-graphql/src/execute.js +6 -28
- package/packages/datadog-plugin-graphql/src/resolve.js +30 -35
- package/packages/datadog-plugin-graphql/src/tools/signature.js +32 -7
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +118 -100
- package/packages/datadog-plugin-graphql/src/utils.js +29 -0
- package/packages/datadog-plugin-grpc/src/client.js +6 -7
- package/packages/datadog-plugin-grpc/src/util.js +57 -22
- package/packages/datadog-plugin-http/src/client.js +3 -7
- package/packages/datadog-plugin-jest/src/index.js +92 -50
- package/packages/datadog-plugin-jest/src/util.js +1 -2
- package/packages/datadog-plugin-mocha/src/index.js +5 -0
- package/packages/datadog-plugin-mongodb-core/src/index.js +36 -69
- package/packages/datadog-plugin-mysql/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/services.js +2 -1
- package/packages/datadog-plugin-openai/src/tracing.js +12 -23
- package/packages/datadog-plugin-pg/src/index.js +3 -3
- package/packages/datadog-plugin-playwright/src/index.js +5 -1
- package/packages/datadog-plugin-redis/src/index.js +18 -23
- package/packages/datadog-plugin-vitest/src/index.js +8 -1
- package/packages/datadog-shimmer/src/shimmer.js +7 -1
- package/packages/dd-trace/src/aiguard/index.js +3 -1
- package/packages/dd-trace/src/aiguard/sdk.js +36 -30
- package/packages/dd-trace/src/aiguard/tags.js +20 -11
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +81 -81
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugins/kafka.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +4 -4
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +1 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +83 -48
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +21 -24
- package/packages/dd-trace/src/appsec/reporter.js +3 -1
- package/packages/dd-trace/src/appsec/rule_manager.js +4 -2
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +31 -16
- package/packages/dd-trace/src/azure_metadata.js +17 -6
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +4 -4
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +4 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +6 -4
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +1 -1
- package/packages/dd-trace/src/config/defaults.js +3 -14
- package/packages/dd-trace/src/config/generated-config-types.d.ts +3 -1
- package/packages/dd-trace/src/config/git_properties.js +2 -2
- package/packages/dd-trace/src/config/helper.js +4 -0
- package/packages/dd-trace/src/config/index.js +2 -2
- package/packages/dd-trace/src/config/major-overrides.js +98 -0
- package/packages/dd-trace/src/config/parsers.js +7 -1
- package/packages/dd-trace/src/config/supported-configurations.json +51 -38
- package/packages/dd-trace/src/datastreams/checkpointer.js +2 -2
- package/packages/dd-trace/src/datastreams/index.js +2 -1
- package/packages/dd-trace/src/datastreams/manager.js +1 -1
- package/packages/dd-trace/src/datastreams/processor.js +3 -4
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/state.js +2 -1
- package/packages/dd-trace/src/debugger/index.js +7 -7
- package/packages/dd-trace/src/dogstatsd.js +2 -2
- package/packages/dd-trace/src/encode/0.4.js +748 -232
- package/packages/dd-trace/src/encode/0.5.js +47 -10
- package/packages/dd-trace/src/encode/agentless-json.js +1 -1
- package/packages/dd-trace/src/exporter.js +2 -0
- package/packages/dd-trace/src/exporters/agent/index.js +2 -1
- package/packages/dd-trace/src/exporters/agentless/index.js +3 -2
- package/packages/dd-trace/src/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -1
- package/packages/dd-trace/src/exporters/common/request.js +1 -1
- package/packages/dd-trace/src/exporters/electron/index.js +49 -0
- package/packages/dd-trace/src/external-logger/src/index.js +2 -1
- package/packages/dd-trace/src/git_metadata.js +10 -8
- package/packages/dd-trace/src/lambda/handler-paths.js +52 -0
- package/packages/dd-trace/src/lambda/index.js +62 -14
- package/packages/dd-trace/src/lambda/runtime/patch.js +21 -46
- package/packages/dd-trace/src/llmobs/index.js +13 -2
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -2
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +45 -15
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +6 -3
- package/packages/dd-trace/src/llmobs/sdk.js +24 -26
- package/packages/dd-trace/src/llmobs/span_processor.js +25 -5
- package/packages/dd-trace/src/llmobs/util.js +1 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +2 -1
- package/packages/dd-trace/src/msgpack/chunk.js +6 -3
- package/packages/dd-trace/src/openfeature/noop.js +40 -36
- package/packages/dd-trace/src/openfeature/writers/base.js +2 -1
- package/packages/dd-trace/src/openfeature/writers/exposures.js +33 -52
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +2 -1
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +1 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +0 -22
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +20 -9
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +2 -11
- package/packages/dd-trace/src/payload-tagging/config/index.js +2 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +49 -4
- package/packages/dd-trace/src/plugins/database.js +54 -12
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/plugin.js +2 -4
- package/packages/dd-trace/src/plugins/util/ci.js +9 -9
- package/packages/dd-trace/src/plugins/util/git-cache.js +23 -23
- package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -2
- package/packages/dd-trace/src/plugins/util/test.js +56 -12
- package/packages/dd-trace/src/plugins/util/url.js +1 -3
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +18 -16
- package/packages/dd-trace/src/plugins/util/web.js +5 -7
- package/packages/dd-trace/src/priority_sampler.js +1 -1
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +3 -23
- package/packages/dd-trace/src/profiling/profilers/wall.js +5 -6
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +1 -1
- package/packages/dd-trace/src/rate_limiter.js +1 -1
- package/packages/dd-trace/src/remote_config/scheduler.js +1 -1
- package/packages/dd-trace/src/ritm.js +2 -1
- package/packages/dd-trace/src/runtime_metrics/index.js +2 -2
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -8
- package/packages/dd-trace/src/scope.js +3 -10
- package/packages/dd-trace/src/serverless.js +6 -6
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +27 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +24 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
- package/packages/dd-trace/src/span_stats.js +1 -1
- package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +1 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +2 -2
- package/packages/dd-trace/src/tracer.js +7 -7
- package/packages/dd-trace/src/lambda/runtime/ritm.js +0 -133
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { performance } = require('node:perf_hooks')
|
|
4
|
+
|
|
3
5
|
const { createCoverageMap } = require('../../../vendor/dist/istanbul-lib-coverage')
|
|
4
6
|
const shimmer = require('../../datadog-shimmer')
|
|
5
7
|
const log = require('../../dd-trace/src/log')
|
|
@@ -12,6 +14,7 @@ const {
|
|
|
12
14
|
getTestSuitePath,
|
|
13
15
|
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE,
|
|
14
16
|
getIsFaultyEarlyFlakeDetection,
|
|
17
|
+
getEfdRetryCount,
|
|
15
18
|
recordAttemptToFixExecution,
|
|
16
19
|
collectAttemptToFixExecutionsFromTraces,
|
|
17
20
|
logAttemptToFixTestExecution,
|
|
@@ -62,6 +65,9 @@ const lastStatusByPickleId = new Map()
|
|
|
62
65
|
/** For ATR: statuses keyed by stable scenario id (uri:name) so retries accumulate correctly */
|
|
63
66
|
const atrStatusesByScenarioKey = new Map()
|
|
64
67
|
const numRetriesByPickleId = new Map()
|
|
68
|
+
const efdRetryCountByPickleId = new Map()
|
|
69
|
+
const efdSlowAbortedPickleIds = new Set()
|
|
70
|
+
const testCaseStartedTimesById = new Map()
|
|
65
71
|
const numAttemptToCtx = new Map()
|
|
66
72
|
const newTestsByTestFullname = new Map()
|
|
67
73
|
const attemptToFixTestsByTestFullname = new Map()
|
|
@@ -82,6 +88,7 @@ let isUnskippable = false
|
|
|
82
88
|
let isSuitesSkippingEnabled = false
|
|
83
89
|
let isEarlyFlakeDetectionEnabled = false
|
|
84
90
|
let earlyFlakeDetectionNumRetries = 0
|
|
91
|
+
let earlyFlakeDetectionSlowTestRetries = {}
|
|
85
92
|
let earlyFlakeDetectionFaultyThreshold = 0
|
|
86
93
|
let isEarlyFlakeDetectionFaulty = false
|
|
87
94
|
let isFlakyTestRetriesEnabled = false
|
|
@@ -290,9 +297,9 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
290
297
|
|
|
291
298
|
patched.add(pl)
|
|
292
299
|
|
|
293
|
-
shimmer.wrap(pl.prototype, 'run', run => function () {
|
|
300
|
+
shimmer.wrap(pl.prototype, 'run', run => function (...args) {
|
|
294
301
|
if (!testFinishCh.hasSubscribers) {
|
|
295
|
-
return run.apply(this,
|
|
302
|
+
return run.apply(this, args)
|
|
296
303
|
}
|
|
297
304
|
|
|
298
305
|
let numAttempt = 0
|
|
@@ -360,9 +367,10 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
360
367
|
}
|
|
361
368
|
this.eventBroadcaster.on('envelope', onEnvelope)
|
|
362
369
|
let promise
|
|
370
|
+
const executionStart = performance.now()
|
|
363
371
|
|
|
364
372
|
testFnCh.runStores(ctx, () => {
|
|
365
|
-
promise = run.apply(this,
|
|
373
|
+
promise = run.apply(this, args)
|
|
366
374
|
})
|
|
367
375
|
promise.finally(async () => {
|
|
368
376
|
this.eventBroadcaster.removeListener('envelope', onEnvelope)
|
|
@@ -424,15 +432,31 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
424
432
|
isEfdRetry = numRetries > 0
|
|
425
433
|
}
|
|
426
434
|
|
|
435
|
+
if (
|
|
436
|
+
isEarlyFlakeDetectionEnabled &&
|
|
437
|
+
status !== 'skip' &&
|
|
438
|
+
(isNew || isModified) &&
|
|
439
|
+
!isEfdRetry &&
|
|
440
|
+
!efdRetryCountByPickleId.has(this.pickle.id)
|
|
441
|
+
) {
|
|
442
|
+
const retryCount = getEfdRetryCount(performance.now() - executionStart, earlyFlakeDetectionSlowTestRetries)
|
|
443
|
+
efdRetryCountByPickleId.set(this.pickle.id, retryCount)
|
|
444
|
+
if (retryCount === 0) {
|
|
445
|
+
efdSlowAbortedPickleIds.add(this.pickle.id)
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const efdRetryCount = efdRetryCountByPickleId.get(this.pickle.id) ?? earlyFlakeDetectionNumRetries
|
|
450
|
+
|
|
427
451
|
// Check if all EFD retries failed
|
|
428
452
|
if (isEfdRetry && (isNew || isModified)) {
|
|
429
453
|
const statuses = lastStatusByPickleId.get(this.pickle.id)
|
|
430
|
-
if (statuses.length ===
|
|
454
|
+
if (statuses.length === efdRetryCount + 1) {
|
|
431
455
|
const { fail } = statuses.reduce((acc, status) => {
|
|
432
456
|
acc[status]++
|
|
433
457
|
return acc
|
|
434
458
|
}, { pass: 0, fail: 0 })
|
|
435
|
-
if (fail ===
|
|
459
|
+
if (fail === efdRetryCount + 1) {
|
|
436
460
|
hasFailedAllRetries = true
|
|
437
461
|
}
|
|
438
462
|
}
|
|
@@ -480,7 +504,7 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
480
504
|
const isLastAtrRetry = isFlakyTestRetriesEnabled && !isAttemptToFix && !isEfdRetry && numTestRetries > 0
|
|
481
505
|
|
|
482
506
|
const statuses = lastStatusByPickleId.get(this.pickle.id)
|
|
483
|
-
const isLastEfdRetry = isEfdRetry && statuses?.length ===
|
|
507
|
+
const isLastEfdRetry = isEfdRetry && statuses?.length === efdRetryCount + 1
|
|
484
508
|
const isLastAttemptToFixRetry = isAttemptToFix && statuses?.length === testManagementAttemptToFixRetries + 1
|
|
485
509
|
|
|
486
510
|
// Intermediate (non-last EFD or ATF retries) executions do not report a final status
|
|
@@ -514,6 +538,7 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
514
538
|
isDisabled,
|
|
515
539
|
isQuarantined,
|
|
516
540
|
isModified,
|
|
541
|
+
earlyFlakeAbortReason: efdSlowAbortedPickleIds.has(this.pickle.id) ? 'slow' : undefined,
|
|
517
542
|
...attemptCtx.currentStore,
|
|
518
543
|
finalStatus,
|
|
519
544
|
})
|
|
@@ -526,11 +551,11 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
526
551
|
})
|
|
527
552
|
}
|
|
528
553
|
})
|
|
529
|
-
shimmer.wrap(pl.prototype, 'runStep', runStep => function () {
|
|
554
|
+
shimmer.wrap(pl.prototype, 'runStep', runStep => function (...args) {
|
|
530
555
|
if (!testFinishCh.hasSubscribers) {
|
|
531
|
-
return runStep.apply(this,
|
|
556
|
+
return runStep.apply(this, args)
|
|
532
557
|
}
|
|
533
|
-
const testStep =
|
|
558
|
+
const testStep = args[0]
|
|
534
559
|
let resource
|
|
535
560
|
|
|
536
561
|
if (isLatestVersion) {
|
|
@@ -542,7 +567,7 @@ function wrapRun (pl, isLatestVersion, version) {
|
|
|
542
567
|
const ctx = { resource }
|
|
543
568
|
return testStepStartCh.runStores(ctx, () => {
|
|
544
569
|
try {
|
|
545
|
-
const promise = runStep.apply(this,
|
|
570
|
+
const promise = runStep.apply(this, args)
|
|
546
571
|
|
|
547
572
|
promise.then((result) => {
|
|
548
573
|
const finalResult = satisfies(version, '>=12.0.0') ? result.result : result
|
|
@@ -603,6 +628,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
603
628
|
|
|
604
629
|
isEarlyFlakeDetectionEnabled = configurationResponse.libraryConfig?.isEarlyFlakeDetectionEnabled
|
|
605
630
|
earlyFlakeDetectionNumRetries = configurationResponse.libraryConfig?.earlyFlakeDetectionNumRetries
|
|
631
|
+
earlyFlakeDetectionSlowTestRetries = configurationResponse.libraryConfig?.earlyFlakeDetectionSlowTestRetries ?? {}
|
|
606
632
|
earlyFlakeDetectionFaultyThreshold = configurationResponse.libraryConfig?.earlyFlakeDetectionFaultyThreshold
|
|
607
633
|
isSuitesSkippingEnabled = configurationResponse.libraryConfig?.isSuitesSkippingEnabled
|
|
608
634
|
isFlakyTestRetriesEnabled = configurationResponse.libraryConfig?.isFlakyTestRetriesEnabled
|
|
@@ -627,7 +653,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
627
653
|
const skippableResponse = await getChannelPromise(skippableSuitesCh)
|
|
628
654
|
|
|
629
655
|
errorSkippableRequest = skippableResponse.err
|
|
630
|
-
skippableSuites = skippableResponse.skippableSuites
|
|
656
|
+
skippableSuites = skippableResponse.skippableSuites ?? []
|
|
631
657
|
|
|
632
658
|
if (!errorSkippableRequest) {
|
|
633
659
|
const filteredPickles = isCoordinator
|
|
@@ -692,6 +718,10 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
692
718
|
|
|
693
719
|
atrStatusesByScenarioKey.clear()
|
|
694
720
|
attemptToFixTestsByTestFullname.clear()
|
|
721
|
+
efdRetryCountByPickleId.clear()
|
|
722
|
+
efdSlowAbortedPickleIds.clear()
|
|
723
|
+
testCaseStartedTimesById.clear()
|
|
724
|
+
newTestsByTestFullname.clear()
|
|
695
725
|
sessionStartCh.publish({ command, frameworkVersion })
|
|
696
726
|
|
|
697
727
|
if (!errorSkippableRequest && skippedSuites.length) {
|
|
@@ -816,7 +846,9 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
816
846
|
}
|
|
817
847
|
}
|
|
818
848
|
// TODO: for >=11 we could use `runTestCaseResult` instead of accumulating results in `lastStatusByPickleId`
|
|
849
|
+
const firstExecutionStart = performance.now()
|
|
819
850
|
let runTestCaseResult = await runTestCaseFunction.apply(this, arguments)
|
|
851
|
+
const firstExecutionDurationMs = performance.now() - firstExecutionStart
|
|
820
852
|
|
|
821
853
|
// Restore dryRun so it doesn't affect subsequent tests in the same worker
|
|
822
854
|
this.options.dryRun = originalDryRun
|
|
@@ -835,7 +867,15 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
835
867
|
|
|
836
868
|
// If it's a new test and it hasn't been skipped, we run it again
|
|
837
869
|
if (isEarlyFlakeDetectionEnabled && lastTestStatus !== 'skip' && (isNew || isModified)) {
|
|
838
|
-
|
|
870
|
+
let efdRetryCount = efdRetryCountByPickleId.get(pickle.id)
|
|
871
|
+
if (efdRetryCount === undefined) {
|
|
872
|
+
efdRetryCount = getEfdRetryCount(firstExecutionDurationMs, earlyFlakeDetectionSlowTestRetries)
|
|
873
|
+
efdRetryCountByPickleId.set(pickle.id, efdRetryCount)
|
|
874
|
+
if (efdRetryCount === 0) {
|
|
875
|
+
efdSlowAbortedPickleIds.add(pickle.id)
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
for (let retryIndex = 0; retryIndex < efdRetryCount; retryIndex++) {
|
|
839
879
|
numRetriesByPickleId.set(pickle.id, retryIndex + 1)
|
|
840
880
|
// eslint-disable-next-line no-await-in-loop
|
|
841
881
|
runTestCaseResult = await runTestCaseFunction.apply(this, arguments)
|
|
@@ -952,6 +992,9 @@ function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion)
|
|
|
952
992
|
let pickle
|
|
953
993
|
|
|
954
994
|
if (parsed.testCaseStarted) {
|
|
995
|
+
if (parsed.testCaseStarted.id) {
|
|
996
|
+
testCaseStartedTimesById.set(parsed.testCaseStarted.id, performance.now())
|
|
997
|
+
}
|
|
955
998
|
if (isNewVersion) {
|
|
956
999
|
pickle = this.inProgress[worker.id].pickle
|
|
957
1000
|
} else {
|
|
@@ -973,6 +1016,10 @@ function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion)
|
|
|
973
1016
|
|
|
974
1017
|
// after calling `parseWorkerMessageFunction`, the test status can already be read
|
|
975
1018
|
if (parsed.testCaseFinished) {
|
|
1019
|
+
const testCaseStartedId = parsed.testCaseFinished.testCaseStartedId
|
|
1020
|
+
const testCaseStartedAt = testCaseStartedTimesById.get(testCaseStartedId)
|
|
1021
|
+
testCaseStartedTimesById.delete(testCaseStartedId)
|
|
1022
|
+
|
|
976
1023
|
let worstTestStepResult
|
|
977
1024
|
if (isNewVersion && eventDataCollector) {
|
|
978
1025
|
pickle = this.inProgress[worker.id].pickle
|
|
@@ -1003,8 +1050,19 @@ function getWrappedParseWorkerMessage (parseWorkerMessageFunction, isNewVersion)
|
|
|
1003
1050
|
testStatuses = [status]
|
|
1004
1051
|
newTestsByTestFullname.set(testFullname, testStatuses)
|
|
1005
1052
|
}
|
|
1053
|
+
let efdRetryCount = efdRetryCountByPickleId.get(pickle.id)
|
|
1054
|
+
if (efdRetryCount === undefined) {
|
|
1055
|
+
const firstExecutionDurationMs = testCaseStartedAt === undefined ? 0 : performance.now() - testCaseStartedAt
|
|
1056
|
+
efdRetryCount = status === 'skip'
|
|
1057
|
+
? 0
|
|
1058
|
+
: getEfdRetryCount(firstExecutionDurationMs, earlyFlakeDetectionSlowTestRetries)
|
|
1059
|
+
efdRetryCountByPickleId.set(pickle.id, efdRetryCount)
|
|
1060
|
+
if (efdRetryCount === 0 && status !== 'skip') {
|
|
1061
|
+
efdSlowAbortedPickleIds.add(pickle.id)
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1006
1064
|
// We have finished all retries
|
|
1007
|
-
if (testStatuses.length ===
|
|
1065
|
+
if (testStatuses.length === efdRetryCount + 1) {
|
|
1008
1066
|
const newTestFinalStatus = getTestStatusFromRetries(testStatuses)
|
|
1009
1067
|
// we only push to `finished` if the retries have finished
|
|
1010
1068
|
finished.push(newTestFinalStatus)
|
|
@@ -1143,9 +1201,9 @@ addHook({
|
|
|
1143
1201
|
versions: ['>=11.0.0'],
|
|
1144
1202
|
file: 'lib/formatter/helpers/event_data_collector.js',
|
|
1145
1203
|
}, (eventDataCollectorPackage) => {
|
|
1146
|
-
shimmer.wrap(eventDataCollectorPackage.default.prototype, 'parseEnvelope', parseEnvelope => function () {
|
|
1204
|
+
shimmer.wrap(eventDataCollectorPackage.default.prototype, 'parseEnvelope', parseEnvelope => function (...args) {
|
|
1147
1205
|
eventDataCollector = this
|
|
1148
|
-
return parseEnvelope.apply(this,
|
|
1206
|
+
return parseEnvelope.apply(this, args)
|
|
1149
1207
|
})
|
|
1150
1208
|
return eventDataCollectorPackage
|
|
1151
1209
|
})
|
|
@@ -1164,18 +1222,20 @@ addHook({
|
|
|
1164
1222
|
parseWorkerMessage => getWrappedParseWorkerMessage(parseWorkerMessage, true)
|
|
1165
1223
|
)
|
|
1166
1224
|
// EFD in parallel mode only supported in >=11.0.0
|
|
1167
|
-
shimmer.wrap(adapterPackage.ChildProcessAdapter.prototype, 'startWorker', startWorker => function () {
|
|
1225
|
+
shimmer.wrap(adapterPackage.ChildProcessAdapter.prototype, 'startWorker', startWorker => function (...args) {
|
|
1168
1226
|
if (isKnownTestsEnabled && isValidKnownTests(knownTests)) {
|
|
1169
1227
|
this.options.worldParameters._ddIsKnownTestsEnabled = true
|
|
1170
1228
|
this.options.worldParameters._ddIsEarlyFlakeDetectionEnabled = isEarlyFlakeDetectionEnabled
|
|
1171
1229
|
this.options.worldParameters._ddKnownTests = knownTests
|
|
1172
1230
|
this.options.worldParameters._ddEarlyFlakeDetectionNumRetries = earlyFlakeDetectionNumRetries
|
|
1231
|
+
this.options.worldParameters._ddEarlyFlakeDetectionSlowTestRetries = earlyFlakeDetectionSlowTestRetries
|
|
1173
1232
|
} else {
|
|
1174
1233
|
isEarlyFlakeDetectionEnabled = false
|
|
1175
1234
|
isKnownTestsEnabled = false
|
|
1176
1235
|
this.options.worldParameters._ddIsEarlyFlakeDetectionEnabled = false
|
|
1177
1236
|
this.options.worldParameters._ddIsKnownTestsEnabled = false
|
|
1178
1237
|
this.options.worldParameters._ddEarlyFlakeDetectionNumRetries = 0
|
|
1238
|
+
this.options.worldParameters._ddEarlyFlakeDetectionSlowTestRetries = {}
|
|
1179
1239
|
}
|
|
1180
1240
|
|
|
1181
1241
|
if (isImpactedTestsEnabled) {
|
|
@@ -1192,7 +1252,7 @@ addHook({
|
|
|
1192
1252
|
this.options.worldParameters._ddTestManagementAttemptToFixRetries = testManagementAttemptToFixRetries
|
|
1193
1253
|
}
|
|
1194
1254
|
|
|
1195
|
-
return startWorker.apply(this,
|
|
1255
|
+
return startWorker.apply(this, args)
|
|
1196
1256
|
})
|
|
1197
1257
|
return adapterPackage
|
|
1198
1258
|
})
|
|
@@ -1222,6 +1282,7 @@ addHook({
|
|
|
1222
1282
|
isEarlyFlakeDetectionEnabled = !!this.options.worldParameters._ddIsEarlyFlakeDetectionEnabled
|
|
1223
1283
|
if (isEarlyFlakeDetectionEnabled) {
|
|
1224
1284
|
earlyFlakeDetectionNumRetries = this.options.worldParameters._ddEarlyFlakeDetectionNumRetries
|
|
1285
|
+
earlyFlakeDetectionSlowTestRetries = this.options.worldParameters._ddEarlyFlakeDetectionSlowTestRetries ?? {}
|
|
1225
1286
|
}
|
|
1226
1287
|
isImpactedTestsEnabled = !!this.options.worldParameters._ddImpactedTestsEnabled
|
|
1227
1288
|
if (isImpactedTestsEnabled) {
|
|
@@ -18,8 +18,6 @@ const rrtypes = {
|
|
|
18
18
|
resolveSoa: 'SOA',
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const rrtypeMap = new WeakMap()
|
|
22
|
-
|
|
23
21
|
addHook({ name: 'dns' }, dns => {
|
|
24
22
|
const lookup = createCallbackInstrumentor('apm:dns:lookup', { captureResult: true })
|
|
25
23
|
const lookupService = createCallbackInstrumentor('apm:dns:lookup_service', { captureResult: true })
|
|
@@ -46,7 +44,6 @@ addHook({ name: 'dns' }, dns => {
|
|
|
46
44
|
function patchResolveShorthands (prototype, resolve) {
|
|
47
45
|
for (const method of Object.keys(rrtypes)) {
|
|
48
46
|
if (prototype[method]) {
|
|
49
|
-
rrtypeMap.set(prototype[method], rrtypes[method])
|
|
50
47
|
shimmer.wrap(prototype, method, resolve(buildArgsContext(rrtypes[method])))
|
|
51
48
|
}
|
|
52
49
|
}
|
|
@@ -24,24 +24,21 @@ function wrapTransportPrototype (Transport) {
|
|
|
24
24
|
addHook({ name: '@elastic/elasticsearch', file: 'lib/Transport.js', versions: ['>=5.6.16 <8', '>=8'] }, Transport => {
|
|
25
25
|
shimmer.wrap(Transport.prototype, 'request', createWrapRequest('elasticsearch'))
|
|
26
26
|
shimmer.wrap(Transport.prototype, 'getConnection', createWrapGetConnection('elasticsearch'))
|
|
27
|
-
return Transport
|
|
28
27
|
})
|
|
29
28
|
|
|
30
29
|
addHook({ name: 'elasticsearch', file: 'src/lib/transport.js', versions: ['>=10'] }, Transport => {
|
|
31
30
|
shimmer.wrap(Transport.prototype, 'request', createWrapRequest('elasticsearch'))
|
|
32
|
-
return Transport
|
|
33
31
|
})
|
|
34
32
|
|
|
35
33
|
addHook({ name: 'elasticsearch', file: 'src/lib/connection_pool.js', versions: ['>=10'] }, ConnectionPool => {
|
|
36
|
-
shimmer.wrap(ConnectionPool.prototype, 'select', createWrapSelect(
|
|
37
|
-
return ConnectionPool
|
|
34
|
+
shimmer.wrap(ConnectionPool.prototype, 'select', createWrapSelect())
|
|
38
35
|
})
|
|
39
36
|
|
|
40
37
|
function createWrapGetConnection (name) {
|
|
41
38
|
const connectCh = channel(`apm:${name}:query:connect`)
|
|
42
39
|
return function wrapRequest (request) {
|
|
43
|
-
return function () {
|
|
44
|
-
const connection = request.apply(this,
|
|
40
|
+
return function (...args) {
|
|
41
|
+
const connection = request.apply(this, args)
|
|
45
42
|
if (connectCh.hasSubscribers && connection && connection.url) {
|
|
46
43
|
connectCh.publish(connection.url)
|
|
47
44
|
}
|
|
@@ -53,17 +50,17 @@ function createWrapGetConnection (name) {
|
|
|
53
50
|
function createWrapSelect () {
|
|
54
51
|
const connectCh = channel('apm:elasticsearch:query:connect')
|
|
55
52
|
return function wrapRequest (request) {
|
|
56
|
-
return function () {
|
|
57
|
-
if (
|
|
58
|
-
const cb =
|
|
59
|
-
|
|
53
|
+
return function (...args) {
|
|
54
|
+
if (args.length === 1) {
|
|
55
|
+
const cb = args[0]
|
|
56
|
+
args[0] = shimmer.wrapFunction(cb, cb => function (err, connection) {
|
|
60
57
|
if (connectCh.hasSubscribers && connection && connection.host) {
|
|
61
58
|
connectCh.publish({ hostname: connection.host.host, port: connection.host.port })
|
|
62
59
|
}
|
|
63
60
|
cb(err, connection)
|
|
64
61
|
})
|
|
65
62
|
}
|
|
66
|
-
return request.apply(this,
|
|
63
|
+
return request.apply(this, args)
|
|
67
64
|
}
|
|
68
65
|
}
|
|
69
66
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line n/no-missing-require
|
|
4
|
+
const { contextBridge, ipcRenderer } = require('electron')
|
|
5
|
+
|
|
6
|
+
const BRIDGE_CHANNEL = 'datadog:bridge-send'
|
|
7
|
+
const CONFIG_CHANNEL = 'datadog:bridge-config'
|
|
8
|
+
|
|
9
|
+
// Privacy levels matching @datadog/browser-core DefaultPrivacyLevel
|
|
10
|
+
const MASK = 'mask'
|
|
11
|
+
|
|
12
|
+
const config = ipcRenderer.sendSync(CONFIG_CHANNEL)
|
|
13
|
+
|
|
14
|
+
const defaultPrivacyLevel = config?.defaultPrivacyLevel ?? MASK
|
|
15
|
+
const configuredHosts = config?.allowedWebViewHosts ?? []
|
|
16
|
+
// eslint-disable-next-line no-undef
|
|
17
|
+
const allowedHosts = [...new Set([location.hostname, ...configuredHosts])]
|
|
18
|
+
|
|
19
|
+
const bridge = {
|
|
20
|
+
getCapabilities () {
|
|
21
|
+
return '[]'
|
|
22
|
+
},
|
|
23
|
+
getPrivacyLevel () {
|
|
24
|
+
return defaultPrivacyLevel
|
|
25
|
+
},
|
|
26
|
+
getAllowedWebViewHosts () {
|
|
27
|
+
return JSON.stringify(allowedHosts)
|
|
28
|
+
},
|
|
29
|
+
send (msg) {
|
|
30
|
+
ipcRenderer.send(BRIDGE_CHANNEL, msg)
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Support both contextIsolation enabled (default) and disabled
|
|
35
|
+
|
|
36
|
+
window.DatadogEventBridge = bridge
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
contextBridge.exposeInMainWorld('DatadogEventBridge', bridge)
|
|
40
|
+
} catch {
|
|
41
|
+
// exposeInMainWorld throws when contextIsolation is disabled
|
|
42
|
+
}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { join } = require('path')
|
|
4
|
+
const { wrap } = require('../../datadog-shimmer')
|
|
5
|
+
const { addHook, channel, tracingChannel } = require('./helpers/instrument')
|
|
6
|
+
|
|
7
|
+
const requestCh = tracingChannel('apm:electron:net:request')
|
|
8
|
+
const mainReceiveCh = tracingChannel('apm:electron:ipc:main:receive')
|
|
9
|
+
const mainHandleCh = tracingChannel('apm:electron:ipc:main:handle')
|
|
10
|
+
const mainSendCh = tracingChannel('apm:electron:ipc:main:send')
|
|
11
|
+
const rendererPatchedCh = channel('apm:electron:ipc:renderer:patched')
|
|
12
|
+
const rendererReceiveCh = tracingChannel('apm:electron:ipc:renderer:receive')
|
|
13
|
+
const rendererSendCh = tracingChannel('apm:electron:ipc:renderer:send')
|
|
14
|
+
|
|
15
|
+
const listeners = {}
|
|
16
|
+
const handlers = {}
|
|
17
|
+
|
|
18
|
+
function createWrapRequest (ch) {
|
|
19
|
+
return function wrapRequest (request) {
|
|
20
|
+
return function (...args) {
|
|
21
|
+
if (!ch.start.hasSubscribers) return request.apply(this, arguments)
|
|
22
|
+
|
|
23
|
+
const ctx = { args }
|
|
24
|
+
|
|
25
|
+
return ch.start.runStores(ctx, () => {
|
|
26
|
+
try {
|
|
27
|
+
const req = request.apply(this, ctx.args)
|
|
28
|
+
const emit = req.emit
|
|
29
|
+
|
|
30
|
+
ctx.req = req
|
|
31
|
+
|
|
32
|
+
req.emit = function (eventName, arg) {
|
|
33
|
+
/* eslint-disable no-fallthrough */
|
|
34
|
+
switch (eventName) {
|
|
35
|
+
case 'response':
|
|
36
|
+
ctx.res = arg
|
|
37
|
+
ctx.res.on('error', error => {
|
|
38
|
+
ctx.error = error
|
|
39
|
+
ch.error.publish(ctx)
|
|
40
|
+
ch.asyncStart.publish(ctx)
|
|
41
|
+
})
|
|
42
|
+
ctx.res.on('end', () => ch.asyncStart.publish(ctx))
|
|
43
|
+
break
|
|
44
|
+
case 'error':
|
|
45
|
+
ctx.error = arg
|
|
46
|
+
ch.error.publish(ctx)
|
|
47
|
+
case 'abort':
|
|
48
|
+
ch.asyncStart.publish(ctx)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return emit.apply(this, arguments)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return req
|
|
55
|
+
} catch (e) {
|
|
56
|
+
ctx.error = e
|
|
57
|
+
ch.error.publish(ctx)
|
|
58
|
+
throw e
|
|
59
|
+
} finally {
|
|
60
|
+
ch.end.publish(ctx)
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function createWrapAddListener (ch, mappings) {
|
|
68
|
+
return function wrapAddListener (addListener) {
|
|
69
|
+
return function (channel, listener) {
|
|
70
|
+
const wrappedListener = (event, ...args) => {
|
|
71
|
+
const ctx = { args, channel, event }
|
|
72
|
+
|
|
73
|
+
return ch.tracePromise(() => listener.call(this, event, ...args), ctx)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const mapping = mappings[channel] || new WeakMap()
|
|
77
|
+
const wrapper = mapping.get(listener) || wrappedListener
|
|
78
|
+
|
|
79
|
+
mapping.set(listener, wrapper)
|
|
80
|
+
|
|
81
|
+
return addListener.call(this, channel, wrappedListener)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function createWrapRemoveListener (mappings) {
|
|
87
|
+
return function wrapRemoveListener (removeListener) {
|
|
88
|
+
return function (channel, listener) {
|
|
89
|
+
const mapping = mappings[channel]
|
|
90
|
+
|
|
91
|
+
if (mapping) {
|
|
92
|
+
const wrapper = mapping.get(listener)
|
|
93
|
+
|
|
94
|
+
if (wrapper) {
|
|
95
|
+
return removeListener.call(this, channel, wrapper)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return removeListener.call(this, channel, listener)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function createWrapRemoveAllListeners (mappings) {
|
|
105
|
+
return function wrapRemoveAllListeners (removeAllListeners) {
|
|
106
|
+
return function (channel) {
|
|
107
|
+
if (channel) {
|
|
108
|
+
delete mappings[channel]
|
|
109
|
+
} else {
|
|
110
|
+
for (const key of Object.keys(mappings)) delete mappings[key]
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return removeAllListeners.call(this, channel)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function createWrapSend (ch, promise = false) {
|
|
119
|
+
const trace = (promise ? ch.tracePromise : ch.traceSync).bind(ch)
|
|
120
|
+
|
|
121
|
+
return function wrapSend (send) {
|
|
122
|
+
return function (channel, ...args) {
|
|
123
|
+
const ctx = { args, channel, self: this }
|
|
124
|
+
|
|
125
|
+
return trace(() => send.call(this, channel, ...args), ctx)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function wrapSendToFrame (send) {
|
|
131
|
+
return function (frameId, channel, ...args) {
|
|
132
|
+
const ctx = { args, channel, frameId, self: this }
|
|
133
|
+
|
|
134
|
+
return mainSendCh.traceSync(() => send.call(this, frameId, channel, ...args), ctx)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function wrapBrowserWindow (electron) {
|
|
139
|
+
const moduleExports = {}
|
|
140
|
+
|
|
141
|
+
class DatadogBrowserWindow extends electron.BrowserWindow {
|
|
142
|
+
constructor (options = {}) {
|
|
143
|
+
const win = super(options)
|
|
144
|
+
|
|
145
|
+
win.webContents.session.registerPreloadScript({
|
|
146
|
+
type: 'frame', // TODO: service-worker
|
|
147
|
+
filePath: join(__dirname, 'electron', 'preload.js'),
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
// BrowserWindow doesn't support subclassing because it's all native code
|
|
151
|
+
// so we return an instance of it instead of the subclass.
|
|
152
|
+
return win
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
Object.defineProperty(moduleExports, 'BrowserWindow', {
|
|
157
|
+
enumerable: true,
|
|
158
|
+
get: () => DatadogBrowserWindow,
|
|
159
|
+
configurable: false,
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
for (const key of Reflect.ownKeys(electron)) {
|
|
163
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(electron, key)
|
|
164
|
+
|
|
165
|
+
if (key === 'BrowserWindow') continue
|
|
166
|
+
|
|
167
|
+
Object.defineProperty(moduleExports, key, descriptor)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return moduleExports
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function wrapWebContents (proto) {
|
|
174
|
+
const descriptor = Object.getOwnPropertyDescriptor(proto, 'webContents')
|
|
175
|
+
const wrapped = new WeakSet()
|
|
176
|
+
const wrapSend = createWrapSend(mainSendCh)
|
|
177
|
+
|
|
178
|
+
Object.defineProperty(proto, 'webContents', {
|
|
179
|
+
get () {
|
|
180
|
+
const webContents = descriptor.get.apply(this)
|
|
181
|
+
|
|
182
|
+
if (!wrapped.has(webContents)) {
|
|
183
|
+
// wrap(webContents, 'postMessage', wrapSend)
|
|
184
|
+
wrap(webContents, 'send', wrapSend)
|
|
185
|
+
wrap(webContents, 'sendToFrame', wrapSendToFrame)
|
|
186
|
+
|
|
187
|
+
wrapped.add(webContents)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return webContents
|
|
191
|
+
},
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
addHook({ name: 'electron', versions: ['>=37.0.0'] }, electron => {
|
|
196
|
+
// Electron exports a string in Node and an object in Electron.
|
|
197
|
+
if (typeof electron === 'string') return electron
|
|
198
|
+
|
|
199
|
+
const { BrowserWindow, ipcMain, ipcRenderer, net } = electron
|
|
200
|
+
|
|
201
|
+
if (net) {
|
|
202
|
+
// This also covers `fetch` as it uses `request` under the hood.
|
|
203
|
+
wrap(net, 'request', createWrapRequest(requestCh))
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (ipcRenderer) {
|
|
207
|
+
wrap(ipcRenderer, 'invoke', createWrapSend(rendererSendCh, true))
|
|
208
|
+
// wrap(ipcRenderer, 'postMessage', createWrapSend(rendererSendCh))
|
|
209
|
+
wrap(ipcRenderer, 'send', createWrapSend(rendererSendCh))
|
|
210
|
+
wrap(ipcRenderer, 'sendSync', createWrapSend(rendererSendCh))
|
|
211
|
+
wrap(ipcRenderer, 'sendToHost', createWrapSend(rendererSendCh))
|
|
212
|
+
|
|
213
|
+
wrap(ipcRenderer, 'addListener', createWrapAddListener(rendererReceiveCh, listeners))
|
|
214
|
+
wrap(ipcRenderer, 'off', createWrapRemoveListener(listeners))
|
|
215
|
+
wrap(ipcRenderer, 'on', createWrapAddListener(rendererReceiveCh, listeners))
|
|
216
|
+
wrap(ipcRenderer, 'once', createWrapAddListener(rendererReceiveCh, listeners))
|
|
217
|
+
wrap(ipcRenderer, 'removeListener', createWrapRemoveListener(listeners))
|
|
218
|
+
wrap(ipcRenderer, 'removeAllListeners', createWrapRemoveAllListeners(listeners))
|
|
219
|
+
|
|
220
|
+
ipcRenderer.send('datadog:apm:renderer:patched')
|
|
221
|
+
} else {
|
|
222
|
+
wrap(ipcMain, 'addListener', createWrapAddListener(mainReceiveCh, listeners))
|
|
223
|
+
wrap(ipcMain, 'handle', createWrapAddListener(mainHandleCh, handlers))
|
|
224
|
+
wrap(ipcMain, 'handleOnce', createWrapAddListener(mainHandleCh, handlers))
|
|
225
|
+
wrap(ipcMain, 'off', createWrapRemoveListener(listeners))
|
|
226
|
+
wrap(ipcMain, 'on', createWrapAddListener(mainReceiveCh, listeners))
|
|
227
|
+
wrap(ipcMain, 'once', createWrapAddListener(mainReceiveCh, listeners))
|
|
228
|
+
wrap(ipcMain, 'removeAllListeners', createWrapRemoveAllListeners(listeners))
|
|
229
|
+
wrap(ipcMain, 'removeHandler', createWrapRemoveAllListeners(handlers))
|
|
230
|
+
wrap(ipcMain, 'removeListener', createWrapRemoveListener(listeners))
|
|
231
|
+
|
|
232
|
+
ipcMain.once('datadog:apm:renderer:patched', event => rendererPatchedCh.publish(event))
|
|
233
|
+
|
|
234
|
+
wrapWebContents(BrowserWindow.prototype)
|
|
235
|
+
|
|
236
|
+
electron = wrapBrowserWindow(electron)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return electron
|
|
240
|
+
})
|
|
@@ -12,8 +12,8 @@ const sanitizeMiddlewareFinished = channel('datadog:express-mongo-sanitize:filte
|
|
|
12
12
|
const propertiesToSanitize = ['body', 'params', 'headers', 'query']
|
|
13
13
|
|
|
14
14
|
addHook({ name: 'express-mongo-sanitize', versions: ['>=1.0.0'] }, expressMongoSanitize => {
|
|
15
|
-
shimmer.wrap(expressMongoSanitize, 'sanitize', sanitize => function () {
|
|
16
|
-
const sanitizedObject = sanitize.apply(this,
|
|
15
|
+
shimmer.wrap(expressMongoSanitize, 'sanitize', sanitize => function (...args) {
|
|
16
|
+
const sanitizedObject = sanitize.apply(this, args)
|
|
17
17
|
|
|
18
18
|
if (sanitizeMethodFinished.hasSubscribers) {
|
|
19
19
|
sanitizeMethodFinished.publish({ sanitizedObject })
|
|
@@ -22,21 +22,21 @@ addHook({ name: 'express-mongo-sanitize', versions: ['>=1.0.0'] }, expressMongoS
|
|
|
22
22
|
return sanitizedObject
|
|
23
23
|
})
|
|
24
24
|
|
|
25
|
-
return shimmer.wrapFunction(expressMongoSanitize, expressMongoSanitize => function () {
|
|
26
|
-
const middleware = expressMongoSanitize.apply(this,
|
|
25
|
+
return shimmer.wrapFunction(expressMongoSanitize, expressMongoSanitize => function (...args) {
|
|
26
|
+
const middleware = expressMongoSanitize.apply(this, args)
|
|
27
27
|
|
|
28
28
|
return shimmer.wrapFunction(middleware, middleware => function (req, res, next) {
|
|
29
29
|
if (!sanitizeMiddlewareFinished.hasSubscribers) {
|
|
30
30
|
return middleware.apply(this, arguments)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const wrappedNext = shimmer.wrapFunction(next, next => function () {
|
|
33
|
+
const wrappedNext = shimmer.wrapFunction(next, next => function (...args) {
|
|
34
34
|
sanitizeMiddlewareFinished.publish({
|
|
35
35
|
sanitizedProperties: propertiesToSanitize,
|
|
36
36
|
req,
|
|
37
37
|
})
|
|
38
38
|
|
|
39
|
-
return next.apply(this,
|
|
39
|
+
return next.apply(this, args)
|
|
40
40
|
})
|
|
41
41
|
|
|
42
42
|
return middleware.call(this, req, res, wrappedNext)
|