dd-trace 5.102.0 → 5.104.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/index.d.ts +25 -3
- package/package.json +15 -13
- package/packages/datadog-esbuild/src/utils.js +2 -2
- package/packages/datadog-instrumentations/src/ai.js +1 -1
- package/packages/datadog-instrumentations/src/aws-sdk.js +2 -2
- package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -2
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +32 -15
- package/packages/datadog-instrumentations/src/couchbase.js +69 -220
- package/packages/datadog-instrumentations/src/cucumber.js +104 -31
- package/packages/datadog-instrumentations/src/elasticsearch.js +4 -4
- package/packages/datadog-instrumentations/src/electron/preload.js +42 -0
- package/packages/datadog-instrumentations/src/electron.js +240 -0
- package/packages/datadog-instrumentations/src/fetch.js +5 -5
- package/packages/datadog-instrumentations/src/graphql.js +13 -17
- package/packages/datadog-instrumentations/src/grpc/client.js +48 -32
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +2 -2
- 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 +58 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +3 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +19 -5
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +14 -13
- package/packages/datadog-instrumentations/src/http/client.js +2 -2
- package/packages/datadog-instrumentations/src/ioredis.js +18 -14
- package/packages/datadog-instrumentations/src/jest.js +382 -84
- package/packages/datadog-instrumentations/src/kafkajs.js +184 -174
- package/packages/datadog-instrumentations/src/mariadb.js +1 -1
- package/packages/datadog-instrumentations/src/memcached.js +2 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +309 -56
- package/packages/datadog-instrumentations/src/mocha/utils.js +48 -8
- package/packages/datadog-instrumentations/src/mongodb-core.js +34 -9
- package/packages/datadog-instrumentations/src/mongoose.js +10 -12
- package/packages/datadog-instrumentations/src/mysql.js +2 -2
- package/packages/datadog-instrumentations/src/mysql2.js +1 -1
- package/packages/datadog-instrumentations/src/pg.js +25 -11
- package/packages/datadog-instrumentations/src/playwright.js +449 -60
- package/packages/datadog-instrumentations/src/redis.js +19 -10
- package/packages/datadog-instrumentations/src/router.js +4 -2
- package/packages/datadog-instrumentations/src/vitest.js +246 -149
- package/packages/datadog-plugin-apollo/src/gateway/request.js +1 -21
- package/packages/datadog-plugin-aws-sdk/src/base.js +18 -24
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -1
- 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 +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +1 -1
- package/packages/datadog-plugin-couchbase/src/index.js +58 -52
- package/packages/datadog-plugin-cucumber/src/index.js +1 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +239 -40
- package/packages/datadog-plugin-cypress/src/support.js +13 -1
- package/packages/datadog-plugin-elasticsearch/src/index.js +28 -8
- 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/producer.js +27 -18
- 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 +33 -1
- 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 +2 -2
- package/packages/datadog-plugin-jest/src/index.js +92 -50
- package/packages/datadog-plugin-kafkajs/src/producer.js +32 -0
- package/packages/datadog-plugin-mocha/src/index.js +1 -0
- package/packages/datadog-plugin-mongodb-core/src/index.js +70 -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-pg/src/index.js +3 -3
- package/packages/datadog-plugin-playwright/src/index.js +4 -0
- package/packages/datadog-plugin-redis/src/index.js +54 -24
- package/packages/datadog-plugin-undici/src/index.js +19 -0
- package/packages/datadog-plugin-vitest/src/index.js +19 -7
- package/packages/datadog-shimmer/src/shimmer.js +35 -0
- 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/blocking.js +2 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +10 -3
- package/packages/dd-trace/src/appsec/reporter.js +19 -5
- 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/ci-visibility/requests/request.js +3 -1
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +5 -3
- package/packages/dd-trace/src/config/defaults.js +3 -14
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -1
- 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 +60 -38
- package/packages/dd-trace/src/crashtracking/crashtracker.js +15 -3
- package/packages/dd-trace/src/datastreams/checkpointer.js +2 -2
- package/packages/dd-trace/src/datastreams/context.js +4 -2
- package/packages/dd-trace/src/datastreams/manager.js +1 -1
- package/packages/dd-trace/src/datastreams/processor.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +2 -2
- 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 +45 -54
- package/packages/dd-trace/src/encode/0.5.js +34 -3
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +26 -19
- 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/agents.js +3 -1
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -1
- package/packages/dd-trace/src/exporters/common/request.js +4 -2
- 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/id.js +17 -4
- package/packages/dd-trace/src/lambda/handler-paths.js +52 -0
- package/packages/dd-trace/src/lambda/handler.js +2 -4
- 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/bedrockruntime.js +45 -15
- package/packages/dd-trace/src/llmobs/sdk.js +10 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +2 -1
- package/packages/dd-trace/src/log/writer.js +3 -1
- package/packages/dd-trace/src/noop/span.js +3 -1
- package/packages/dd-trace/src/openfeature/writers/base.js +2 -1
- package/packages/dd-trace/src/openfeature/writers/exposures.js +51 -20
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +3 -2
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +20 -9
- package/packages/dd-trace/src/payload-tagging/config/index.js +2 -2
- package/packages/dd-trace/src/plugins/apollo.js +3 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +52 -17
- 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/log_plugin.js +3 -1
- package/packages/dd-trace/src/plugins/plugin.js +2 -4
- package/packages/dd-trace/src/plugins/tracing.js +5 -3
- package/packages/dd-trace/src/plugins/util/ci.js +8 -8
- package/packages/dd-trace/src/plugins/util/git-cache.js +20 -18
- package/packages/dd-trace/src/plugins/util/git.js +3 -1
- package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -2
- package/packages/dd-trace/src/plugins/util/test.js +119 -5
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +17 -15
- package/packages/dd-trace/src/plugins/util/web.js +11 -0
- 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/wall.js +1 -1
- 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/runtime_metrics.js +5 -8
- package/packages/dd-trace/src/scope.js +7 -5
- package/packages/dd-trace/src/serverless.js +5 -2
- package/packages/dd-trace/src/service-naming/extra-services.js +14 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +20 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +20 -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/lambda/runtime/ritm.js +0 -133
- package/vendor/dist/opentracing/LICENSE +0 -201
- package/vendor/dist/opentracing/binary_carrier.d.ts +0 -11
- package/vendor/dist/opentracing/constants.d.ts +0 -61
- package/vendor/dist/opentracing/examples/demo/demo.d.ts +0 -2
- package/vendor/dist/opentracing/ext/tags.d.ts +0 -90
- package/vendor/dist/opentracing/functions.d.ts +0 -20
- package/vendor/dist/opentracing/global_tracer.d.ts +0 -14
- package/vendor/dist/opentracing/index.d.ts +0 -12
- package/vendor/dist/opentracing/index.js +0 -1
- package/vendor/dist/opentracing/mock_tracer/index.d.ts +0 -5
- package/vendor/dist/opentracing/mock_tracer/mock_context.d.ts +0 -13
- package/vendor/dist/opentracing/mock_tracer/mock_report.d.ts +0 -16
- package/vendor/dist/opentracing/mock_tracer/mock_span.d.ts +0 -50
- package/vendor/dist/opentracing/mock_tracer/mock_tracer.d.ts +0 -26
- package/vendor/dist/opentracing/noop.d.ts +0 -8
- package/vendor/dist/opentracing/reference.d.ts +0 -33
- package/vendor/dist/opentracing/span.d.ts +0 -147
- package/vendor/dist/opentracing/span_context.d.ts +0 -26
- package/vendor/dist/opentracing/test/api_compatibility.d.ts +0 -16
- package/vendor/dist/opentracing/test/mocktracer_implemenation.d.ts +0 -3
- package/vendor/dist/opentracing/test/noop_implementation.d.ts +0 -4
- package/vendor/dist/opentracing/test/opentracing_api.d.ts +0 -3
- package/vendor/dist/opentracing/test/unittest.d.ts +0 -2
- package/vendor/dist/opentracing/tracer.d.ts +0 -127
|
@@ -40,14 +40,14 @@ const KEY_TYPE = buildKey('type')
|
|
|
40
40
|
const KEY_NAME = buildKey('name')
|
|
41
41
|
const KEY_RESOURCE = buildKey('resource')
|
|
42
42
|
const KEY_SERVICE = buildKey('service')
|
|
43
|
+
const KEY_ERROR = buildKey('error')
|
|
44
|
+
const KEY_START = buildKey('start')
|
|
45
|
+
const KEY_DURATION = buildKey('duration')
|
|
43
46
|
const KEY_SPAN_EVENTS = buildKey('span_events')
|
|
44
47
|
const KEY_META_STRUCT = buildKey('meta_struct')
|
|
45
48
|
const KEY_TRACE_ID_PREFIX = buildKeyWithPrefix('trace_id', 0xCF)
|
|
46
49
|
const KEY_SPAN_ID_PREFIX = buildKeyWithPrefix('span_id', 0xCF)
|
|
47
50
|
const KEY_PARENT_ID_PREFIX = buildKeyWithPrefix('parent_id', 0xCF)
|
|
48
|
-
const KEY_ERROR_PREFIX = buildKeyWithPrefix('error', 0xCE)
|
|
49
|
-
const KEY_START_PREFIX = buildKeyWithPrefix('start', 0xCF)
|
|
50
|
-
const KEY_DURATION_PREFIX = buildKeyWithPrefix('duration', 0xCF)
|
|
51
51
|
const KEY_META_PREFIX = buildKeyWithPrefix('meta', 0xDF)
|
|
52
52
|
const KEY_METRICS_PREFIX = buildKeyWithPrefix('metrics', 0xDF)
|
|
53
53
|
|
|
@@ -344,9 +344,12 @@ class AgentEncoder {
|
|
|
344
344
|
cursor += KEY_SERVICE.length
|
|
345
345
|
target.set(serviceEntry, cursor)
|
|
346
346
|
|
|
347
|
-
|
|
348
|
-
this
|
|
349
|
-
|
|
347
|
+
bytes.set(KEY_ERROR)
|
|
348
|
+
this._encodeIntOrFloat(bytes, span.error)
|
|
349
|
+
bytes.set(KEY_START)
|
|
350
|
+
this._encodeIntOrFloat(bytes, span.start)
|
|
351
|
+
bytes.set(KEY_DURATION)
|
|
352
|
+
this._encodeIntOrFloat(bytes, span.duration)
|
|
350
353
|
|
|
351
354
|
this.#encodeMetaEntries(bytes, KEY_META_PREFIX, span.meta)
|
|
352
355
|
this.#encodeMetaEntries(bytes, KEY_METRICS_PREFIX, span.metrics)
|
|
@@ -448,6 +451,8 @@ class AgentEncoder {
|
|
|
448
451
|
}
|
|
449
452
|
|
|
450
453
|
// Single pass: reserve the count slot, encode entries while counting, patch the count.
|
|
454
|
+
// Subclasses (0.5, CI visibility encoders) inherit this; the wire stays on float64
|
|
455
|
+
// for numeric values to keep their established trace / events intake unchanged.
|
|
451
456
|
_encodeMap (bytes, value) {
|
|
452
457
|
const offset = bytes.length
|
|
453
458
|
bytes.reserve(5)
|
|
@@ -542,12 +547,9 @@ class AgentEncoder {
|
|
|
542
547
|
target.set(keyEntry, writeOffset)
|
|
543
548
|
target.set(valueEntry, writeOffset + keyEntryLen)
|
|
544
549
|
} else {
|
|
545
|
-
bytes.reserve(keyEntryLen
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
const valueOffset = writeOffset + keyEntryLen
|
|
549
|
-
target[valueOffset] = 0xCB
|
|
550
|
-
bytes.view.setFloat64(valueOffset + 1, entryValue)
|
|
550
|
+
bytes.reserve(keyEntryLen)
|
|
551
|
+
bytes.buffer.set(keyEntry, writeOffset)
|
|
552
|
+
this._encodeIntOrFloat(bytes, entryValue)
|
|
551
553
|
}
|
|
552
554
|
count++
|
|
553
555
|
}
|
|
@@ -588,49 +590,38 @@ class AgentEncoder {
|
|
|
588
590
|
}
|
|
589
591
|
|
|
590
592
|
/**
|
|
593
|
+
* Emit `value` as the smallest valid msgpack number encoding: compact
|
|
594
|
+
* unsigned/signed int when integer, float64 otherwise. Unlike
|
|
595
|
+
* `MsgpackEncoder#encodeNumber`, NaN keeps its float64 bits instead of
|
|
596
|
+
* coercing to fixint 0.
|
|
597
|
+
*
|
|
598
|
+
* Underscore-protected so the 0.5 subclass can call it from its own
|
|
599
|
+
* `_encode` / `_encodeMap` overrides.
|
|
600
|
+
*
|
|
591
601
|
* @param {MsgpackChunk} bytes
|
|
592
|
-
* @param {Buffer} keyPrefix Precomputed `[key, 0xCE]`.
|
|
593
602
|
* @param {number} value
|
|
594
603
|
*/
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
const high = (value / 2 ** 32) >> 0
|
|
617
|
-
const low = value >>> 0
|
|
618
|
-
const keyPrefixLen = keyPrefix.length
|
|
619
|
-
const offset = bytes.length
|
|
620
|
-
bytes.reserve(keyPrefixLen + 8)
|
|
621
|
-
|
|
622
|
-
const target = bytes.buffer
|
|
623
|
-
target.set(keyPrefix, offset)
|
|
624
|
-
|
|
625
|
-
const valueOffset = offset + keyPrefixLen
|
|
626
|
-
target[valueOffset] = high >> 24
|
|
627
|
-
target[valueOffset + 1] = high >> 16
|
|
628
|
-
target[valueOffset + 2] = high >> 8
|
|
629
|
-
target[valueOffset + 3] = high
|
|
630
|
-
target[valueOffset + 4] = low >> 24
|
|
631
|
-
target[valueOffset + 5] = low >> 16
|
|
632
|
-
target[valueOffset + 6] = low >> 8
|
|
633
|
-
target[valueOffset + 7] = low
|
|
604
|
+
_encodeIntOrFloat (bytes, value) {
|
|
605
|
+
// Fast path: positive fixint (0..127). `value === (value & 0x7F)` is true
|
|
606
|
+
// iff `value` is an exact integer in that range — covers `error: 0/1`,
|
|
607
|
+
// priority flags, attribute counts, HTTP status codes mapped to numbers,
|
|
608
|
+
// and most small metrics. NaN, ±Infinity, negatives, and any non-integer
|
|
609
|
+
// float fall through.
|
|
610
|
+
if (value === (value & 0x7F)) {
|
|
611
|
+
const offset = bytes.length
|
|
612
|
+
bytes.reserve(1)
|
|
613
|
+
bytes.buffer[offset] = value
|
|
614
|
+
return
|
|
615
|
+
}
|
|
616
|
+
if (Number.isInteger(value)) {
|
|
617
|
+
if (value >= 0) {
|
|
618
|
+
this.#msgpack.encodeUnsigned(bytes, value)
|
|
619
|
+
} else {
|
|
620
|
+
this.#msgpack.encodeSigned(bytes, value)
|
|
621
|
+
}
|
|
622
|
+
} else {
|
|
623
|
+
this.#encodeFloat(bytes, value)
|
|
624
|
+
}
|
|
634
625
|
}
|
|
635
626
|
|
|
636
627
|
/**
|
|
@@ -853,7 +844,7 @@ class AgentEncoder {
|
|
|
853
844
|
if (typeof value === 'number') {
|
|
854
845
|
this._encodeString(bytes, key)
|
|
855
846
|
bytes.set(Number.isInteger(value) ? ATTR_PREFIX_INT : ATTR_PREFIX_DOUBLE)
|
|
856
|
-
this
|
|
847
|
+
this._encodeIntOrFloat(bytes, value)
|
|
857
848
|
return true
|
|
858
849
|
}
|
|
859
850
|
if (typeof value === 'boolean') {
|
|
@@ -923,7 +914,7 @@ class AgentEncoder {
|
|
|
923
914
|
}
|
|
924
915
|
if (typeof value === 'number') {
|
|
925
916
|
bytes.set(Number.isInteger(value) ? ATTR_PREFIX_INT : ATTR_PREFIX_DOUBLE)
|
|
926
|
-
this
|
|
917
|
+
this._encodeIntOrFloat(bytes, value)
|
|
927
918
|
return true
|
|
928
919
|
}
|
|
929
920
|
if (typeof value === 'boolean') {
|
|
@@ -46,15 +46,46 @@ class AgentEncoder extends BaseEncoder {
|
|
|
46
46
|
this._encodeId(bytes, span.trace_id)
|
|
47
47
|
this._encodeId(bytes, span.span_id)
|
|
48
48
|
this._encodeId(bytes, span.parent_id)
|
|
49
|
-
this.
|
|
50
|
-
this.
|
|
51
|
-
this.
|
|
49
|
+
this._encodeIntOrFloat(bytes, span.start || 0)
|
|
50
|
+
this._encodeIntOrFloat(bytes, span.duration || 0)
|
|
51
|
+
this._encodeIntOrFloat(bytes, span.error)
|
|
52
52
|
this._encodeMap(bytes, span.meta || {})
|
|
53
53
|
this._encodeMap(bytes, span.metrics || {})
|
|
54
54
|
this._encodeString(bytes, span.type)
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
// Override the inherited 0.4 `_encodeMap` so the v0.5 wire emits each numeric
|
|
59
|
+
// value via `_encodeIntOrFloat` (compact unsigned/signed int when integer,
|
|
60
|
+
// float64 otherwise) instead of always float64. The 0.4 base method stays on
|
|
61
|
+
// float64 because the CI-visibility encoders inherit it and target a
|
|
62
|
+
// different intake.
|
|
63
|
+
_encodeMap (bytes, value) {
|
|
64
|
+
const offset = bytes.length
|
|
65
|
+
bytes.reserve(5)
|
|
66
|
+
bytes.buffer[offset] = 0xDF
|
|
67
|
+
|
|
68
|
+
let count = 0
|
|
69
|
+
for (const key of Object.keys(value)) {
|
|
70
|
+
const entryValue = value[key]
|
|
71
|
+
if (typeof entryValue === 'string') {
|
|
72
|
+
this._encodeString(bytes, key)
|
|
73
|
+
this._encodeString(bytes, entryValue)
|
|
74
|
+
count++
|
|
75
|
+
} else if (typeof entryValue === 'number') {
|
|
76
|
+
this._encodeString(bytes, key)
|
|
77
|
+
this._encodeIntOrFloat(bytes, entryValue)
|
|
78
|
+
count++
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const target = bytes.buffer
|
|
83
|
+
target[offset + 1] = count >>> 24
|
|
84
|
+
target[offset + 2] = count >>> 16
|
|
85
|
+
target[offset + 3] = count >>> 8
|
|
86
|
+
target[offset + 4] = count
|
|
87
|
+
}
|
|
88
|
+
|
|
58
89
|
_encodeString (bytes, value = '') {
|
|
59
90
|
let index = this._stringMap[value]
|
|
60
91
|
if (index === undefined) {
|
|
@@ -7,6 +7,7 @@ const {
|
|
|
7
7
|
TELEMETRY_ENDPOINT_PAYLOAD_SERIALIZATION_MS,
|
|
8
8
|
TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT,
|
|
9
9
|
} = require('../ci-visibility/telemetry')
|
|
10
|
+
const { MsgpackChunk } = require('../msgpack')
|
|
10
11
|
const { AgentEncoder } = require('./0.4')
|
|
11
12
|
const { truncateSpan, normalizeSpan } = require('./tags-processors')
|
|
12
13
|
|
|
@@ -20,6 +21,9 @@ const TEST_AND_SPAN_KEYS_LENGTH = 11
|
|
|
20
21
|
|
|
21
22
|
const INTAKE_SOFT_LIMIT = 2 * 1024 * 1024 // 2MB
|
|
22
23
|
|
|
24
|
+
// Prefix is ~1 KB in practice; `MsgpackChunk` resizes on overflow.
|
|
25
|
+
const PREFIX_CHUNK_INITIAL_SIZE = 2048
|
|
26
|
+
|
|
23
27
|
function formatSpan (span) {
|
|
24
28
|
let encodingVersion = ENCODING_VERSION
|
|
25
29
|
if (span.type === 'test' && span.meta && span.meta.test_session_id) {
|
|
@@ -259,10 +263,6 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
259
263
|
}
|
|
260
264
|
|
|
261
265
|
_encode (bytes, trace) {
|
|
262
|
-
if (this._isReset) {
|
|
263
|
-
this._encodePayloadStart(bytes)
|
|
264
|
-
this._isReset = false
|
|
265
|
-
}
|
|
266
266
|
const startTime = Date.now()
|
|
267
267
|
|
|
268
268
|
const events = trace.map(formatSpan)
|
|
@@ -281,20 +281,28 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
281
281
|
|
|
282
282
|
makePayload () {
|
|
283
283
|
distributionMetric(TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT, { endpoint: 'test_cycle' }, this._eventCount)
|
|
284
|
-
const bytes = this._traceBytes
|
|
285
|
-
const eventsOffset = this._eventsOffset
|
|
286
|
-
const eventsCount = this._eventCount
|
|
287
284
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
285
|
+
// Encode the payload prefix (version + metadata + events-array header) at flush time,
|
|
286
|
+
// not on the first `_encode`. The CI Visibility flow adds metadata across multiple
|
|
287
|
+
// diagnostic channels (`session:start` adds `test_session.name`, the async
|
|
288
|
+
// `library-configuration` callback adds capability tags). Any span finished between
|
|
289
|
+
// those calls would otherwise freeze the prefix with stale metadata.
|
|
290
|
+
const prefixBytes = new MsgpackChunk(PREFIX_CHUNK_INITIAL_SIZE)
|
|
291
|
+
this._encodePayloadStart(prefixBytes)
|
|
293
292
|
|
|
294
|
-
const
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
293
|
+
const eventsOffset = this._eventsOffset
|
|
294
|
+
const eventsCount = this._eventCount
|
|
295
|
+
prefixBytes.buffer[eventsOffset] = 0xDD
|
|
296
|
+
prefixBytes.buffer[eventsOffset + 1] = eventsCount >> 24
|
|
297
|
+
prefixBytes.buffer[eventsOffset + 2] = eventsCount >> 16
|
|
298
|
+
prefixBytes.buffer[eventsOffset + 3] = eventsCount >> 8
|
|
299
|
+
prefixBytes.buffer[eventsOffset + 4] = eventsCount
|
|
300
|
+
|
|
301
|
+
const eventsBytes = this._traceBytes
|
|
302
|
+
const totalSize = prefixBytes.length + eventsBytes.length
|
|
303
|
+
const buffer = Buffer.allocUnsafe(totalSize)
|
|
304
|
+
prefixBytes.buffer.copy(buffer, 0, 0, prefixBytes.length)
|
|
305
|
+
eventsBytes.buffer.copy(buffer, prefixBytes.length, 0, eventsBytes.length)
|
|
298
306
|
|
|
299
307
|
this.reset()
|
|
300
308
|
|
|
@@ -302,7 +310,8 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
302
310
|
}
|
|
303
311
|
|
|
304
312
|
_encodePayloadStart (bytes) {
|
|
305
|
-
//
|
|
313
|
+
// Encodes the payload up to (and including) the `events` array prefix. The 5 reserved
|
|
314
|
+
// bytes for the array length are patched in `makePayload`.
|
|
306
315
|
const payload = {
|
|
307
316
|
version: ENCODING_VERSION,
|
|
308
317
|
metadata: {
|
|
@@ -346,7 +355,6 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
346
355
|
this._encodeMap(bytes, payload.metadata.test_session_end)
|
|
347
356
|
}
|
|
348
357
|
this._encodeString(bytes, 'events')
|
|
349
|
-
// Get offset of the events list to update the length of the array when calling `makePayload`
|
|
350
358
|
this._eventsOffset = bytes.length
|
|
351
359
|
bytes.reserve(5)
|
|
352
360
|
}
|
|
@@ -354,7 +362,6 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
354
362
|
reset () {
|
|
355
363
|
this._reset()
|
|
356
364
|
this._eventCount = 0
|
|
357
|
-
this._isReset = true
|
|
358
365
|
}
|
|
359
366
|
}
|
|
360
367
|
|
|
@@ -85,7 +85,7 @@ function spanToJSON (span) {
|
|
|
85
85
|
class AgentlessJSONEncoder {
|
|
86
86
|
/**
|
|
87
87
|
* @param {object} writer - Writer instance with a flush() method, called when the buffer exceeds the soft limit
|
|
88
|
-
* @param {object} [metadata
|
|
88
|
+
* @param {object} [metadata] - Shared metadata spread into each trace object (hostname, env, tracerVersion, etc.)
|
|
89
89
|
*/
|
|
90
90
|
constructor (writer, metadata = {}) {
|
|
91
91
|
this._writer = writer
|
|
@@ -18,7 +18,7 @@ class AgentlessExporter {
|
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* @param {object} config - Configuration object
|
|
21
|
-
* @param {string} [config.site
|
|
21
|
+
* @param {string} [config.site] - The Datadog site. Defaults to 'datadoghq.com'.
|
|
22
22
|
* @param {string} [config.url] - Override intake URL
|
|
23
23
|
* @param {number} [config.flushInterval] - Batch flush interval in ms
|
|
24
24
|
* @param {string} [config.env] - Environment name
|
|
@@ -109,7 +109,8 @@ class AgentlessExporter {
|
|
|
109
109
|
log.error('Failed to flush traces on timer: %s', err.message)
|
|
110
110
|
}
|
|
111
111
|
this.#timer = undefined
|
|
112
|
-
}, flushInterval)
|
|
112
|
+
}, flushInterval)
|
|
113
|
+
this.#timer.unref?.()
|
|
113
114
|
}
|
|
114
115
|
}
|
|
115
116
|
|
|
@@ -19,8 +19,8 @@ class AgentlessWriter extends BaseWriter {
|
|
|
19
19
|
/**
|
|
20
20
|
* @param {object} options - Writer options
|
|
21
21
|
* @param {URL} [options.url] - The intake URL. If not provided, constructed from site.
|
|
22
|
-
* @param {string} [options.site
|
|
23
|
-
* @param {object} [options.metadata
|
|
22
|
+
* @param {string} [options.site] - The Datadog site
|
|
23
|
+
* @param {object} [options.metadata] - Metadata to pass to the encoder (hostname, env, etc.)
|
|
24
24
|
*/
|
|
25
25
|
constructor ({ url, site = 'datadoghq.com', metadata = {} }) {
|
|
26
26
|
super({ url })
|
|
@@ -4,6 +4,8 @@ const http = require('http')
|
|
|
4
4
|
const https = require('https')
|
|
5
5
|
const { storage } = require('../../../../datadog-core')
|
|
6
6
|
|
|
7
|
+
const legacyStorage = storage('legacy')
|
|
8
|
+
|
|
7
9
|
const keepAlive = true
|
|
8
10
|
const maxSockets = 1
|
|
9
11
|
|
|
@@ -26,7 +28,7 @@ function createAgentClass (BaseAgent) {
|
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
_noop (callback) {
|
|
29
|
-
return
|
|
31
|
+
return legacyStorage.run({ noop: true }, callback)
|
|
30
32
|
}
|
|
31
33
|
}
|
|
32
34
|
|
|
@@ -20,6 +20,8 @@ const {
|
|
|
20
20
|
markEndpointReached,
|
|
21
21
|
} = require('./retry')
|
|
22
22
|
|
|
23
|
+
const legacyStorage = storage('legacy')
|
|
24
|
+
|
|
23
25
|
const maxActiveBufferSize = 1024 * 1024 * 64
|
|
24
26
|
|
|
25
27
|
let activeBufferSize = 0
|
|
@@ -161,7 +163,7 @@ function request (data, options, callback) {
|
|
|
161
163
|
|
|
162
164
|
activeBufferSize += options.headers['Content-Length'] ?? 0
|
|
163
165
|
|
|
164
|
-
|
|
166
|
+
legacyStorage.run({ noop: true }, () => {
|
|
165
167
|
let finished = false
|
|
166
168
|
const finalize = () => {
|
|
167
169
|
if (finished) return
|
|
@@ -180,7 +182,7 @@ function request (data, options, callback) {
|
|
|
180
182
|
// Unref so a pending retry never keeps the host process alive past
|
|
181
183
|
// its natural exit point; long-running apps still retry because the
|
|
182
184
|
// event loop is held open by their own work.
|
|
183
|
-
setTimeout(attempt, getRetryDelay(options, attemptIndex), attemptIndex + 1).unref()
|
|
185
|
+
setTimeout(attempt, getRetryDelay(options, attemptIndex), attemptIndex + 1).unref?.()
|
|
184
186
|
} else {
|
|
185
187
|
callback(error)
|
|
186
188
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { channel } = require('dc-polyfill')
|
|
4
|
+
const { truncateSpan, normalizeSpan } = require('../../encode/tags-processors')
|
|
5
|
+
|
|
6
|
+
const traceChannel = channel('datadog:apm:electron:export')
|
|
7
|
+
|
|
8
|
+
class ElectronExporter {
|
|
9
|
+
#timer
|
|
10
|
+
#traces = []
|
|
11
|
+
|
|
12
|
+
constructor (config) {
|
|
13
|
+
this._config = config
|
|
14
|
+
|
|
15
|
+
globalThis[Symbol.for('dd-trace')].beforeExitHandlers.add(this.flush.bind(this))
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export (spans) {
|
|
19
|
+
this.#traces.push(spans)
|
|
20
|
+
|
|
21
|
+
const { flushInterval } = this._config
|
|
22
|
+
|
|
23
|
+
if (flushInterval === 0) {
|
|
24
|
+
this.flush()
|
|
25
|
+
} else if (this.#timer === undefined) {
|
|
26
|
+
this.#timer = setTimeout(() => {
|
|
27
|
+
this.flush()
|
|
28
|
+
this.#timer = undefined
|
|
29
|
+
}, flushInterval)
|
|
30
|
+
this.#timer.unref?.()
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
flush (done = () => {}) {
|
|
35
|
+
clearTimeout(this.#timer)
|
|
36
|
+
this.#timer = undefined
|
|
37
|
+
|
|
38
|
+
const traces = this.#traces.splice(0)
|
|
39
|
+
|
|
40
|
+
if (traces.length > 0 && traceChannel.hasSubscribers) {
|
|
41
|
+
const formattedTraces = traces.map(spans => spans.map(span => normalizeSpan(truncateSpan(span))))
|
|
42
|
+
traceChannel.publish(formattedTraces)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
done()
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = ElectronExporter
|
|
@@ -12,19 +12,21 @@ const {
|
|
|
12
12
|
resolveGitHeadSHA,
|
|
13
13
|
} = require('./config/git_properties')
|
|
14
14
|
|
|
15
|
-
/**
|
|
16
|
-
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {{ commitSHA: string | undefined, repositoryUrl: string | undefined }} GitMetadata
|
|
17
|
+
* @type {{ enabled?: GitMetadata, disabled?: GitMetadata }}
|
|
18
|
+
*/
|
|
19
|
+
const cache = {}
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
22
|
* @param {import('./config/config-types').ConfigProperties} config
|
|
20
23
|
*/
|
|
21
24
|
function getGitMetadata (config) {
|
|
22
|
-
if (cached) return cached
|
|
23
|
-
|
|
24
25
|
if (!config.DD_TRACE_GIT_METADATA_ENABLED) {
|
|
25
|
-
|
|
26
|
-
return
|
|
26
|
+
cache.disabled ??= { commitSHA: undefined, repositoryUrl: undefined }
|
|
27
|
+
return cache.disabled
|
|
27
28
|
}
|
|
29
|
+
if (cache.enabled) return cache.enabled
|
|
28
30
|
|
|
29
31
|
let repositoryUrl = removeUserSensitiveInfo(config.DD_GIT_REPOSITORY_URL ?? config.tags[GIT_REPOSITORY_URL])
|
|
30
32
|
let commitSHA = config.DD_GIT_COMMIT_SHA ?? config.tags[GIT_COMMIT_SHA]
|
|
@@ -59,8 +61,8 @@ function getGitMetadata (config) {
|
|
|
59
61
|
|
|
60
62
|
commitSHA ??= resolveGitHeadSHA(gitFolderPath)
|
|
61
63
|
|
|
62
|
-
|
|
63
|
-
return
|
|
64
|
+
cache.enabled = { commitSHA, repositoryUrl }
|
|
65
|
+
return cache.enabled
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
module.exports = getGitMetadata
|
|
@@ -13,6 +13,12 @@ let batch = 0
|
|
|
13
13
|
class Identifier {
|
|
14
14
|
/** @type {number[] | Uint8Array} */
|
|
15
15
|
#buffer
|
|
16
|
+
/** @type {bigint | undefined} */
|
|
17
|
+
#bigInt
|
|
18
|
+
/** @type {string | undefined} */
|
|
19
|
+
#stringHex
|
|
20
|
+
/** @type {string | undefined} */
|
|
21
|
+
#stringDecimal
|
|
16
22
|
|
|
17
23
|
/**
|
|
18
24
|
* @param {string} value
|
|
@@ -29,16 +35,23 @@ class Identifier {
|
|
|
29
35
|
* @returns {string}
|
|
30
36
|
*/
|
|
31
37
|
toString (radix = 16) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
if (radix === 16) {
|
|
39
|
+
this.#stringHex ??= Buffer.from(this.#buffer).toString('hex')
|
|
40
|
+
return this.#stringHex
|
|
41
|
+
}
|
|
42
|
+
if (radix === 10) {
|
|
43
|
+
this.#stringDecimal ??= toNumberString(this.#buffer, 10)
|
|
44
|
+
return this.#stringDecimal
|
|
45
|
+
}
|
|
46
|
+
return toNumberString(this.#buffer, radix)
|
|
35
47
|
}
|
|
36
48
|
|
|
37
49
|
/**
|
|
38
50
|
* @returns {bigint}
|
|
39
51
|
*/
|
|
40
52
|
toBigInt () {
|
|
41
|
-
|
|
53
|
+
this.#bigInt ??= Buffer.from(this.#buffer).readBigUInt64BE(0)
|
|
54
|
+
return this.#bigInt
|
|
42
55
|
}
|
|
43
56
|
|
|
44
57
|
/**
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* Modifications copyright 2022 Datadog, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Some functions are part of aws-lambda-nodejs-runtime-interface-client
|
|
6
|
+
* https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/blob/v2.1.0/src/utils/UserFunction.ts
|
|
7
|
+
*/
|
|
8
|
+
'use strict'
|
|
9
|
+
|
|
10
|
+
const path = require('path')
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Example: `'./api/src/index.nested.handler'` → `['./api/src/', 'index.nested.handler']`.
|
|
14
|
+
*
|
|
15
|
+
* @param {string} fullHandler
|
|
16
|
+
*/
|
|
17
|
+
function extractModuleRootAndHandler (fullHandler) {
|
|
18
|
+
const handlerString = path.basename(fullHandler)
|
|
19
|
+
const moduleRoot = fullHandler.slice(0, Math.max(0, fullHandler.indexOf(handlerString)))
|
|
20
|
+
return [moduleRoot, handlerString]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Example: `'index.nested.handler'` → `['index', 'nested.handler']`.
|
|
25
|
+
*
|
|
26
|
+
* @param {string} handler
|
|
27
|
+
* @throws {Error} When the handler is not of the form `<module>.<path>`.
|
|
28
|
+
*/
|
|
29
|
+
function extractModuleNameAndHandlerPath (handler) {
|
|
30
|
+
const match = handler.match(/^([^.]*)\.(.*)$/)
|
|
31
|
+
if (!match || match.length !== 3) {
|
|
32
|
+
throw new Error(`Malformed handler name: ${handler}`)
|
|
33
|
+
}
|
|
34
|
+
return [match[1], match[2]]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @param {string} lambdaStylePath `LAMBDA_TASK_ROOT` joined with the module root and module name.
|
|
39
|
+
*/
|
|
40
|
+
function getLambdaFilePaths (lambdaStylePath) {
|
|
41
|
+
return [
|
|
42
|
+
`${lambdaStylePath}.js`,
|
|
43
|
+
`${lambdaStylePath}.mjs`,
|
|
44
|
+
`${lambdaStylePath}.cjs`,
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = {
|
|
49
|
+
extractModuleRootAndHandler,
|
|
50
|
+
extractModuleNameAndHandlerPath,
|
|
51
|
+
getLambdaFilePaths,
|
|
52
|
+
}
|
|
@@ -6,8 +6,6 @@ const { ERROR_MESSAGE, ERROR_TYPE } = require('../constants')
|
|
|
6
6
|
const { ImpendingTimeout } = require('./runtime/errors')
|
|
7
7
|
const { extractContext } = require('./context')
|
|
8
8
|
|
|
9
|
-
const globalTracer = global._ddtrace
|
|
10
|
-
const tracer = globalTracer._tracer
|
|
11
9
|
const timeoutChannel = channel('apm:aws:lambda:timeout')
|
|
12
10
|
// Always crash the flushes when a message is received
|
|
13
11
|
// from this channel.
|
|
@@ -25,8 +23,7 @@ let __lambdaTimeout
|
|
|
25
23
|
*/
|
|
26
24
|
function checkTimeout (context) {
|
|
27
25
|
const remainingTimeInMillis = context.getRemainingTimeInMillis()
|
|
28
|
-
|
|
29
|
-
const apmFlushDeadline = tracer._config.DD_APM_FLUSH_DEADLINE_MILLISECONDS
|
|
26
|
+
const apmFlushDeadline = global._ddtrace._tracer._config.DD_APM_FLUSH_DEADLINE_MILLISECONDS
|
|
30
27
|
|
|
31
28
|
__lambdaTimeout = setTimeout(() => {
|
|
32
29
|
timeoutChannel.publish()
|
|
@@ -42,6 +39,7 @@ function checkTimeout (context) {
|
|
|
42
39
|
* Once that is done, it finishes the last span.
|
|
43
40
|
*/
|
|
44
41
|
function crashFlush () {
|
|
42
|
+
const tracer = global._ddtrace._tracer
|
|
45
43
|
const activeSpan = tracer.scope().active()
|
|
46
44
|
if (activeSpan === null) {
|
|
47
45
|
log.debug('An impending timeout was reached, but no root span was found. No error will be tagged.')
|