dd-trace 5.104.0 → 5.105.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 +90 -102
- package/index.d.ts +82 -3
- package/package.json +15 -15
- package/packages/datadog-core/src/storage.js +1 -1
- package/packages/datadog-instrumentations/src/aerospike.js +1 -1
- package/packages/datadog-instrumentations/src/ai.js +8 -7
- package/packages/datadog-instrumentations/src/aws-sdk.js +13 -0
- package/packages/datadog-instrumentations/src/azure-cosmos.js +7 -0
- package/packages/datadog-instrumentations/src/azure-functions.js +3 -0
- package/packages/datadog-instrumentations/src/cucumber.js +78 -5
- package/packages/datadog-instrumentations/src/dns.js +54 -18
- package/packages/datadog-instrumentations/src/fastify.js +142 -82
- package/packages/datadog-instrumentations/src/graphql.js +188 -62
- package/packages/datadog-instrumentations/src/helpers/ai-messages.js +322 -14
- package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/openai-ai-guard.js +269 -0
- package/packages/datadog-instrumentations/src/helpers/promise-instrumentor.js +42 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/azure-cosmos.js +50 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langgraph.js +4 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +85 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +37 -236
- package/packages/datadog-instrumentations/src/hono.js +54 -3
- package/packages/datadog-instrumentations/src/http/server.js +9 -4
- package/packages/datadog-instrumentations/src/jest/coverage-backfill.js +163 -0
- package/packages/datadog-instrumentations/src/jest.js +360 -150
- package/packages/datadog-instrumentations/src/kafkajs.js +120 -16
- package/packages/datadog-instrumentations/src/mocha/main.js +128 -17
- package/packages/datadog-instrumentations/src/nats.js +182 -0
- package/packages/datadog-instrumentations/src/nyc.js +38 -1
- package/packages/datadog-instrumentations/src/openai.js +33 -18
- package/packages/datadog-instrumentations/src/oracledb.js +6 -1
- package/packages/datadog-instrumentations/src/pino.js +17 -5
- package/packages/datadog-instrumentations/src/playwright.js +515 -292
- package/packages/datadog-instrumentations/src/router.js +76 -32
- package/packages/datadog-instrumentations/src/stripe.js +1 -1
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +1 -1
- package/packages/datadog-plugin-azure-cosmos/src/index.js +144 -0
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +1 -1
- package/packages/datadog-plugin-azure-functions/src/index.js +5 -2
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +1 -1
- package/packages/datadog-plugin-bunyan/src/index.js +28 -0
- package/packages/datadog-plugin-cucumber/src/index.js +17 -3
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +199 -28
- package/packages/datadog-plugin-cypress/src/support.js +69 -1
- package/packages/datadog-plugin-dns/src/lookup.js +8 -6
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +1 -1
- package/packages/datadog-plugin-graphql/src/execute.js +2 -0
- package/packages/datadog-plugin-graphql/src/resolve.js +64 -67
- package/packages/datadog-plugin-http/src/server.js +40 -15
- package/packages/datadog-plugin-jest/src/index.js +11 -3
- package/packages/datadog-plugin-jest/src/util.js +15 -8
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +1 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +3 -0
- package/packages/datadog-plugin-langgraph/src/stream.js +1 -1
- package/packages/datadog-plugin-mocha/src/index.js +19 -4
- package/packages/datadog-plugin-mongodb-core/src/index.js +281 -40
- package/packages/datadog-plugin-nats/src/consumer.js +43 -0
- package/packages/datadog-plugin-nats/src/index.js +20 -0
- package/packages/datadog-plugin-nats/src/producer.js +62 -0
- package/packages/datadog-plugin-nats/src/util.js +33 -0
- package/packages/datadog-plugin-next/src/index.js +5 -3
- package/packages/datadog-plugin-openai/src/tracing.js +15 -2
- package/packages/datadog-plugin-oracledb/src/index.js +13 -2
- package/packages/datadog-plugin-pino/src/index.js +42 -0
- package/packages/datadog-plugin-playwright/src/index.js +4 -4
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -1
- package/packages/datadog-plugin-rhea/src/producer.js +1 -1
- package/packages/datadog-plugin-router/src/index.js +33 -44
- package/packages/datadog-plugin-selenium/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +5 -13
- package/packages/datadog-plugin-winston/src/index.js +30 -0
- package/packages/datadog-shimmer/src/shimmer.js +33 -40
- package/packages/dd-trace/src/aiguard/index.js +1 -1
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/api_security_sampler.js +1 -1
- package/packages/dd-trace/src/appsec/index.js +1 -1
- package/packages/dd-trace/src/appsec/reporter.js +5 -6
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -1
- package/packages/dd-trace/src/appsec/sdk/utils.js +1 -1
- package/packages/dd-trace/src/appsec/user_tracking.js +5 -4
- package/packages/dd-trace/src/baggage.js +7 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +0 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +25 -13
- package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +70 -6
- package/packages/dd-trace/src/config/generated-config-types.d.ts +6 -2
- package/packages/dd-trace/src/config/supported-configurations.json +27 -8
- package/packages/dd-trace/src/datastreams/writer.js +2 -4
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +5 -8
- package/packages/dd-trace/src/encode/0.4.js +124 -108
- package/packages/dd-trace/src/encode/0.5.js +114 -26
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +31 -23
- package/packages/dd-trace/src/encode/agentless-json.js +4 -2
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +32 -13
- package/packages/dd-trace/src/encode/span-stats.js +16 -16
- package/packages/dd-trace/src/encode/tags-processors.js +16 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/genai/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +9 -7
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +0 -16
- package/packages/dd-trace/src/llmobs/span_processor.js +3 -3
- package/packages/dd-trace/src/llmobs/tagger.js +9 -1
- package/packages/dd-trace/src/llmobs/telemetry.js +1 -1
- package/packages/dd-trace/src/llmobs/util.js +66 -3
- package/packages/dd-trace/src/log/index.js +1 -1
- package/packages/dd-trace/src/msgpack/chunk.js +394 -10
- package/packages/dd-trace/src/msgpack/index.js +96 -2
- package/packages/dd-trace/src/openfeature/encoding.js +70 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +20 -0
- package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +143 -0
- package/packages/dd-trace/src/openfeature/span-enrichment.js +149 -0
- package/packages/dd-trace/src/opentelemetry/span-helpers.js +4 -3
- package/packages/dd-trace/src/opentelemetry/span.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/log.js +18 -7
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +62 -67
- package/packages/dd-trace/src/opentracing/span.js +59 -19
- package/packages/dd-trace/src/opentracing/span_context.js +49 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +20 -20
- package/packages/dd-trace/src/plugins/database.js +7 -6
- package/packages/dd-trace/src/plugins/index.js +4 -0
- package/packages/dd-trace/src/plugins/log_injection.js +56 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +3 -48
- package/packages/dd-trace/src/plugins/outbound.js +1 -1
- package/packages/dd-trace/src/plugins/plugin.js +15 -17
- package/packages/dd-trace/src/plugins/tracing.js +43 -5
- package/packages/dd-trace/src/plugins/util/test.js +236 -13
- package/packages/dd-trace/src/plugins/util/web.js +79 -65
- package/packages/dd-trace/src/priority_sampler.js +2 -2
- package/packages/dd-trace/src/profiling/profiler.js +2 -2
- package/packages/dd-trace/src/profiling/profilers/wall.js +10 -4
- package/packages/dd-trace/src/sampling_rule.js +7 -7
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +10 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +8 -0
- package/packages/dd-trace/src/service-naming/source-resolver.js +46 -0
- package/packages/dd-trace/src/span_format.js +190 -58
- package/packages/dd-trace/src/spanleak.js +1 -1
- package/packages/dd-trace/src/standalone/index.js +3 -3
- package/packages/dd-trace/src/tagger.js +0 -2
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +70 -39
- package/vendor/dist/@datadog/sketches-js/LICENSE +10 -36
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/packages/dd-trace/src/msgpack/encoder.js +0 -308
- package/packages/dd-trace/src/plugins/structured_log_plugin.js +0 -9
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { writeFileSync } = require('node:fs')
|
|
3
|
+
const { existsSync, readFileSync, writeFileSync } = require('node:fs')
|
|
4
4
|
const { tmpdir } = require('node:os')
|
|
5
5
|
const { randomUUID } = require('node:crypto')
|
|
6
6
|
const path = require('node:path')
|
|
@@ -8,6 +8,9 @@ const path = require('node:path')
|
|
|
8
8
|
const { getValueFromEnvSources } = require('../config/helper')
|
|
9
9
|
const log = require('../log')
|
|
10
10
|
|
|
11
|
+
const COVERAGE_BACKFILL_KEY = '_ddCoverageBackfill'
|
|
12
|
+
const COVERAGE_BACKFILL_ROOT_DIR_KEY = '_ddCoverageBackfillRootDir'
|
|
13
|
+
|
|
11
14
|
/**
|
|
12
15
|
* Gets the test optimization settings cache file path from the env var.
|
|
13
16
|
* @returns {string|undefined} The cache file path, or undefined if not set.
|
|
@@ -36,26 +39,87 @@ function setupSettingsCachePath () {
|
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* @param {object} settings - The settings object to cache.
|
|
42
|
+
* Reads the shared test optimization cache file.
|
|
43
|
+
* @returns {object} Cached settings and metadata.
|
|
42
44
|
*/
|
|
43
|
-
function
|
|
45
|
+
function readCacheFile () {
|
|
46
|
+
const settingsCachePath = getSettingsCachePath()
|
|
47
|
+
if (!settingsCachePath || !existsSync(settingsCachePath)) {
|
|
48
|
+
return {}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(readFileSync(settingsCachePath, 'utf8'))
|
|
53
|
+
} catch (err) {
|
|
54
|
+
log.debug('Failed to read settings cache: %s', err.message)
|
|
55
|
+
return {}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Writes the shared test optimization cache file.
|
|
61
|
+
* @param {object} cache - Cached settings and metadata.
|
|
62
|
+
*/
|
|
63
|
+
function writeCacheFile (cache) {
|
|
44
64
|
const settingsCachePath = getSettingsCachePath()
|
|
45
65
|
if (!settingsCachePath) {
|
|
46
66
|
return
|
|
47
67
|
}
|
|
48
68
|
|
|
49
69
|
try {
|
|
50
|
-
writeFileSync(settingsCachePath, JSON.stringify(
|
|
70
|
+
writeFileSync(settingsCachePath, JSON.stringify(cache), 'utf8')
|
|
51
71
|
log.debug('Settings written to %s', settingsCachePath)
|
|
52
72
|
} catch (err) {
|
|
53
73
|
log.error('Failed to write settings to cache file', err)
|
|
54
74
|
}
|
|
55
75
|
}
|
|
56
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Writes the settings to the cache file specified by DD_EXPERIMENTAL_TEST_OPT_SETTINGS_CACHE.
|
|
79
|
+
* Does nothing if the env var is not set.
|
|
80
|
+
* @param {object} settings - The settings object to cache.
|
|
81
|
+
*/
|
|
82
|
+
function writeSettingsToCache (settings) {
|
|
83
|
+
writeCacheFile({
|
|
84
|
+
...readCacheFile(),
|
|
85
|
+
...settings,
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Writes TIA coverage backfill to the shared nyc settings cache.
|
|
91
|
+
* @param {object} coverage - Repository-relative coverage bitmaps by filename.
|
|
92
|
+
* @param {string} [rootDir] - Root directory that coverage filenames are relative to.
|
|
93
|
+
*/
|
|
94
|
+
function writeCoverageBackfillToCache (coverage, rootDir) {
|
|
95
|
+
writeCacheFile({
|
|
96
|
+
...readCacheFile(),
|
|
97
|
+
[COVERAGE_BACKFILL_KEY]: coverage,
|
|
98
|
+
[COVERAGE_BACKFILL_ROOT_DIR_KEY]: rootDir,
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Reads TIA coverage backfill from the shared nyc settings cache.
|
|
104
|
+
* @returns {object|undefined} Repository-relative coverage bitmaps by filename.
|
|
105
|
+
*/
|
|
106
|
+
function readCoverageBackfillFromCache () {
|
|
107
|
+
return readCacheFile()[COVERAGE_BACKFILL_KEY]
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Reads TIA coverage backfill root directory from the shared nyc settings cache.
|
|
112
|
+
* @returns {string|undefined} Root directory that cached coverage filenames are relative to.
|
|
113
|
+
*/
|
|
114
|
+
function readCoverageBackfillRootDirFromCache () {
|
|
115
|
+
return readCacheFile()[COVERAGE_BACKFILL_ROOT_DIR_KEY]
|
|
116
|
+
}
|
|
117
|
+
|
|
57
118
|
module.exports = {
|
|
58
119
|
getSettingsCachePath,
|
|
120
|
+
readCoverageBackfillFromCache,
|
|
121
|
+
readCoverageBackfillRootDirFromCache,
|
|
59
122
|
setupSettingsCachePath,
|
|
123
|
+
writeCoverageBackfillToCache,
|
|
60
124
|
writeSettingsToCache,
|
|
61
125
|
}
|
|
@@ -65,7 +65,7 @@ export interface GeneratedConfig {
|
|
|
65
65
|
dbm: {
|
|
66
66
|
injectSqlBaseHash: boolean;
|
|
67
67
|
};
|
|
68
|
-
dbmPropagationMode:
|
|
68
|
+
dbmPropagationMode: "disabled" | "service" | "full" | "dynamic_service";
|
|
69
69
|
DD_ACTION_EXECUTION_ID: string | undefined;
|
|
70
70
|
DD_AGENTLESS_LOG_SUBMISSION_ENABLED: boolean;
|
|
71
71
|
DD_AGENTLESS_LOG_SUBMISSION_URL: string | undefined;
|
|
@@ -162,7 +162,6 @@ export interface GeneratedConfig {
|
|
|
162
162
|
DD_TEST_FLEET_CONFIG_PATH: string | undefined;
|
|
163
163
|
DD_TEST_LOCAL_CONFIG_PATH: string | undefined;
|
|
164
164
|
DD_TEST_SESSION_NAME: string | undefined;
|
|
165
|
-
DD_TEST_TIA_KEEP_COV_CONFIG: boolean;
|
|
166
165
|
DD_TRACE_AEROSPIKE_ENABLED: boolean;
|
|
167
166
|
DD_TRACE_AI_ENABLED: boolean;
|
|
168
167
|
DD_TRACE_AMQP10_ENABLED: boolean;
|
|
@@ -211,6 +210,7 @@ export interface GeneratedConfig {
|
|
|
211
210
|
DD_TRACE_AWS_SDK_STEPFUNCTIONS_BATCH_PROPAGATION_ENABLED: boolean;
|
|
212
211
|
DD_TRACE_AWS_SDK_STEPFUNCTIONS_ENABLED: boolean;
|
|
213
212
|
DD_TRACE_AXIOS_ENABLED: boolean;
|
|
213
|
+
DD_TRACE_AZURE_COSMOS_ENABLED: boolean;
|
|
214
214
|
DD_TRACE_AZURE_DURABLE_FUNCTIONS_ENABLED: boolean;
|
|
215
215
|
DD_TRACE_AZURE_EVENT_HUBS_ENABLED: boolean;
|
|
216
216
|
DD_TRACE_AZURE_EVENTHUBS_BATCH_LINKS_ENABLED: boolean;
|
|
@@ -331,6 +331,7 @@ export interface GeneratedConfig {
|
|
|
331
331
|
DD_TRACE_MYSQL_ENABLED: boolean;
|
|
332
332
|
DD_TRACE_MYSQL2_ENABLED: boolean;
|
|
333
333
|
DD_TRACE_NATIVE_SPAN_EVENTS: boolean;
|
|
334
|
+
DD_TRACE_NATS_ENABLED: boolean;
|
|
334
335
|
DD_TRACE_NET_ENABLED: boolean;
|
|
335
336
|
DD_TRACE_NEXT_ENABLED: boolean;
|
|
336
337
|
DD_TRACE_NODE_CHILD_PROCESS_ENABLED: boolean;
|
|
@@ -428,6 +429,9 @@ export interface GeneratedConfig {
|
|
|
428
429
|
flaggingProvider: {
|
|
429
430
|
enabled: boolean;
|
|
430
431
|
initializationTimeoutMs: number;
|
|
432
|
+
spanEnrichment: {
|
|
433
|
+
enabled: boolean;
|
|
434
|
+
};
|
|
431
435
|
};
|
|
432
436
|
};
|
|
433
437
|
flakyTestRetriesCount: number;
|
|
@@ -640,7 +640,9 @@
|
|
|
640
640
|
"configurationNames": [
|
|
641
641
|
"dbmPropagationMode"
|
|
642
642
|
],
|
|
643
|
-
"default": "disabled"
|
|
643
|
+
"default": "disabled",
|
|
644
|
+
"allowed": "disabled|service|full|dynamic_service",
|
|
645
|
+
"transform": "toLowerCase"
|
|
644
646
|
}
|
|
645
647
|
],
|
|
646
648
|
"DD_DOGSTATSD_HOST": [
|
|
@@ -773,6 +775,16 @@
|
|
|
773
775
|
"default": "false"
|
|
774
776
|
}
|
|
775
777
|
],
|
|
778
|
+
"DD_EXPERIMENTAL_FLAGGING_PROVIDER_SPAN_ENRICHMENT_ENABLED": [
|
|
779
|
+
{
|
|
780
|
+
"implementation": "A",
|
|
781
|
+
"type": "boolean",
|
|
782
|
+
"configurationNames": [
|
|
783
|
+
"experimental.flaggingProvider.spanEnrichment.enabled"
|
|
784
|
+
],
|
|
785
|
+
"default": "false"
|
|
786
|
+
}
|
|
787
|
+
],
|
|
776
788
|
"DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED": [
|
|
777
789
|
{
|
|
778
790
|
"implementation": "B",
|
|
@@ -1773,13 +1785,6 @@
|
|
|
1773
1785
|
"internalPropertyName": "isTestManagementEnabled"
|
|
1774
1786
|
}
|
|
1775
1787
|
],
|
|
1776
|
-
"DD_TEST_TIA_KEEP_COV_CONFIG": [
|
|
1777
|
-
{
|
|
1778
|
-
"implementation": "A",
|
|
1779
|
-
"type": "boolean",
|
|
1780
|
-
"default": "false"
|
|
1781
|
-
}
|
|
1782
|
-
],
|
|
1783
1788
|
"DD_TEST_SESSION_NAME": [
|
|
1784
1789
|
{
|
|
1785
1790
|
"implementation": "A",
|
|
@@ -2176,6 +2181,13 @@
|
|
|
2176
2181
|
"default": "true"
|
|
2177
2182
|
}
|
|
2178
2183
|
],
|
|
2184
|
+
"DD_TRACE_AZURE_COSMOS_ENABLED": [
|
|
2185
|
+
{
|
|
2186
|
+
"implementation": "A",
|
|
2187
|
+
"type": "boolean",
|
|
2188
|
+
"default": "true"
|
|
2189
|
+
}
|
|
2190
|
+
],
|
|
2179
2191
|
"DD_TRACE_AZURE_DURABLE_FUNCTIONS_ENABLED": [
|
|
2180
2192
|
{
|
|
2181
2193
|
"implementation": "B",
|
|
@@ -3184,6 +3196,13 @@
|
|
|
3184
3196
|
"default": "false"
|
|
3185
3197
|
}
|
|
3186
3198
|
],
|
|
3199
|
+
"DD_TRACE_NATS_ENABLED": [
|
|
3200
|
+
{
|
|
3201
|
+
"implementation": "A",
|
|
3202
|
+
"type": "boolean",
|
|
3203
|
+
"default": "false"
|
|
3204
|
+
}
|
|
3205
|
+
],
|
|
3187
3206
|
"DD_TRACE_NET_ENABLED": [
|
|
3188
3207
|
{
|
|
3189
3208
|
"implementation": "A",
|
|
@@ -4,11 +4,9 @@ const zlib = require('zlib')
|
|
|
4
4
|
const pkg = require('../../../../package.json')
|
|
5
5
|
const log = require('../log')
|
|
6
6
|
const request = require('../exporters/common/request')
|
|
7
|
-
const {
|
|
7
|
+
const { encode: encodeMsgpack } = require('../msgpack')
|
|
8
8
|
const { getAgentUrl } = require('../agent/url')
|
|
9
9
|
|
|
10
|
-
const msgpack = new MsgpackEncoder()
|
|
11
|
-
|
|
12
10
|
function makeRequest (data, url, cb) {
|
|
13
11
|
const options = {
|
|
14
12
|
path: '/v0.1/pipeline_stats',
|
|
@@ -39,7 +37,7 @@ class DataStreamsWriter {
|
|
|
39
37
|
log.debug('Maximum number of active requests reached. Payload discarded: %j', payload)
|
|
40
38
|
return
|
|
41
39
|
}
|
|
42
|
-
const encodedPayload =
|
|
40
|
+
const encodedPayload = encodeMsgpack(payload)
|
|
43
41
|
|
|
44
42
|
zlib.gzip(encodedPayload, { level: 1 }, (err, compressedData) => {
|
|
45
43
|
if (err) {
|
|
@@ -6,7 +6,7 @@ module.exports = {
|
|
|
6
6
|
templateRequiresEvaluation,
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
const identifierRegex = /^[
|
|
9
|
+
const identifierRegex = /^(@[\w$]+|[a-zA-Z_$][\w$]*)$/
|
|
10
10
|
|
|
11
11
|
// The following identifiers have purposefully not been included in this list:
|
|
12
12
|
// - The reserved words `this` and `super` as they can have valid use cases as `ref` values
|
|
@@ -99,14 +99,11 @@ function compile (node) {
|
|
|
99
99
|
? `(typeof ${compile(value[0])} === '${value[1]}')` // TODO: Is parenthesizing necessary?
|
|
100
100
|
: `Function.prototype[Symbol.hasInstance].call(${assertIdentifier(value[1])}, ${compile(value[0])})`
|
|
101
101
|
} else if (type === 'ref') {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
return '$dd_key'
|
|
106
|
-
} else if (value === '@value') {
|
|
107
|
-
return '$dd_value'
|
|
102
|
+
const refValue = assertIdentifier(value)
|
|
103
|
+
if (refValue.startsWith('@')) {
|
|
104
|
+
return `$dd_${refValue.slice(1)}`
|
|
108
105
|
}
|
|
109
|
-
return
|
|
106
|
+
return refValue
|
|
110
107
|
} else if (Array.isArray(value)) {
|
|
111
108
|
const args = value.map(compile)
|
|
112
109
|
switch (type) {
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const getConfig = require('../config')
|
|
4
|
-
const { MsgpackChunk
|
|
4
|
+
const { MsgpackChunk } = require('../msgpack')
|
|
5
5
|
const log = require('../log')
|
|
6
6
|
const { normalizeSpan } = require('./tags-processors')
|
|
7
7
|
|
|
8
8
|
const SOFT_LIMIT = 8 * 1024 * 1024 // 8MB
|
|
9
|
+
// Values longer than this byte threshold skip the `_stringMap` lookup and
|
|
10
|
+
// emit through `bytes.write` directly. Hashing a multi-KiB string for
|
|
11
|
+
// `Map.get` costs more than the cache hit saves on the inputs that produce
|
|
12
|
+
// strings this long (events JSON, stack traces, large query bodies) — they
|
|
13
|
+
// are unique per span, so the cache hit rate stays near zero anyway.
|
|
14
|
+
const STRING_CACHE_BYPASS_LIMIT = 1024
|
|
9
15
|
|
|
10
16
|
// Pre-encoded static keys + value-prefix bytes; the hot encode loop emits
|
|
11
17
|
// each via one Uint8Array.set instead of routing through the string cache.
|
|
@@ -43,6 +49,17 @@ const KEY_SERVICE = buildKey('service')
|
|
|
43
49
|
const KEY_ERROR = buildKey('error')
|
|
44
50
|
const KEY_START = buildKey('start')
|
|
45
51
|
const KEY_DURATION = buildKey('duration')
|
|
52
|
+
|
|
53
|
+
// Fused `[KEY_ERROR, fixint]` payloads. `error` is `0` or `1` on nearly every
|
|
54
|
+
// span (the boolean-shaped tracer field collapsed onto a single byte). One
|
|
55
|
+
// `bytes.set` writes the key and the value together instead of routing the
|
|
56
|
+
// value through `writeIntOrFloat`'s reserve + branch table.
|
|
57
|
+
const KEY_ERROR_0 = Buffer.concat([KEY_ERROR, Buffer.from([0x00])])
|
|
58
|
+
const KEY_ERROR_1 = Buffer.concat([KEY_ERROR, Buffer.from([0x01])])
|
|
59
|
+
// `[KEY_START, 0xCF]` — `start` is always a nanosecond timestamp ≥ 2³², so
|
|
60
|
+
// the msgpack u64 type byte is statically known and fuses with the key. The
|
|
61
|
+
// 8-byte value is written inline right after.
|
|
62
|
+
const KEY_START_PREFIX = buildKeyWithPrefix('start', 0xCF)
|
|
46
63
|
const KEY_SPAN_EVENTS = buildKey('span_events')
|
|
47
64
|
const KEY_META_STRUCT = buildKey('meta_struct')
|
|
48
65
|
const KEY_TRACE_ID_PREFIX = buildKeyWithPrefix('trace_id', 0xCF)
|
|
@@ -97,6 +114,8 @@ const ATTR_PAYLOAD_BOOL_FALSE = Buffer.concat([ATTR_PREFIX_BOOL, Buffer.from([0x
|
|
|
97
114
|
function formatSpanWithLegacyEvents (span) {
|
|
98
115
|
span = normalizeSpan(span)
|
|
99
116
|
if (span.span_events) {
|
|
117
|
+
// TODO: this is currently a main cost driver. By unifying it with the formatter
|
|
118
|
+
// it should be possible to improve performance significantly overall.
|
|
100
119
|
span.meta.events = stringifySpanEvents(span.span_events)
|
|
101
120
|
// `= undefined` over `delete` to keep the span's hidden class — `delete`
|
|
102
121
|
// would push every event-bearing span into V8 dictionary mode.
|
|
@@ -201,8 +220,12 @@ function escapeJsonString (value) {
|
|
|
201
220
|
return '"' + value + '"'
|
|
202
221
|
}
|
|
203
222
|
|
|
223
|
+
function lazyEncodedTraceBufferLogger (bytes, start, end) {
|
|
224
|
+
const hex = bytes.buffer.subarray(start, end).toString('hex').match(/../g).join(' ')
|
|
225
|
+
return `Adding encoded trace to buffer: ${hex}`
|
|
226
|
+
}
|
|
227
|
+
|
|
204
228
|
class AgentEncoder {
|
|
205
|
-
#msgpack = new MsgpackEncoder()
|
|
206
229
|
#limit
|
|
207
230
|
#writer
|
|
208
231
|
#config
|
|
@@ -239,11 +262,7 @@ class AgentEncoder {
|
|
|
239
262
|
|
|
240
263
|
if (this.#debugEncoding) {
|
|
241
264
|
const end = bytes.length
|
|
242
|
-
|
|
243
|
-
log.debug(() => {
|
|
244
|
-
const hex = bytes.buffer.subarray(start, end).toString('hex').match(/../g).join(' ')
|
|
245
|
-
return `Adding encoded trace to buffer: ${hex}`
|
|
246
|
-
})
|
|
265
|
+
log.debug(lazyEncodedTraceBufferLogger, bytes, start, end)
|
|
247
266
|
}
|
|
248
267
|
|
|
249
268
|
// Soft limit overshoot is fine — the agent caps at 50 MB.
|
|
@@ -269,7 +288,7 @@ class AgentEncoder {
|
|
|
269
288
|
}
|
|
270
289
|
|
|
271
290
|
_encode (bytes, trace) {
|
|
272
|
-
|
|
291
|
+
bytes.writeArrayPrefix(trace)
|
|
273
292
|
|
|
274
293
|
const formatSpan = this.#formatSpan
|
|
275
294
|
const stringMap = this._stringMap
|
|
@@ -286,10 +305,10 @@ class AgentEncoder {
|
|
|
286
305
|
if (span.span_events) mapSize++
|
|
287
306
|
|
|
288
307
|
// Pre-fetch the cached string entries up front and fuse the map prefix,
|
|
289
|
-
// optional `type`, three IDs,
|
|
308
|
+
// optional `type`, three IDs, `name` / `resource` / `service`, and —
|
|
309
|
+
// in the common fixint-error case — the error/start/duration_key
|
|
290
310
|
// emissions into a single `bytes.reserve` + sequential native writes.
|
|
291
|
-
// Replaces
|
|
292
|
-
// header, type, three IDs, three strings) with one.
|
|
311
|
+
// Replaces up to ten separate `bytes.reserve` calls per span with one.
|
|
293
312
|
let typeEntry
|
|
294
313
|
if (span.type) {
|
|
295
314
|
typeEntry = stringMap[span.type] ?? this._cacheString(span.type)
|
|
@@ -301,8 +320,17 @@ class AgentEncoder {
|
|
|
301
320
|
const resourceLen = resourceEntry.length
|
|
302
321
|
const serviceLen = serviceEntry.length
|
|
303
322
|
|
|
304
|
-
//
|
|
305
|
-
//
|
|
323
|
+
// Almost every span carries `error: 0` or `error: 1` AND a nanosecond
|
|
324
|
+
// `start` timestamp ≥ 2³² (so `start` always encodes as a u64). When
|
|
325
|
+
// both hold, the block fuses error key+value, the start key + 0xCF
|
|
326
|
+
// type byte + 8-byte timestamp, and the duration key into the per-span
|
|
327
|
+
// reserve. The fallback path covers synthetic/test inputs with small
|
|
328
|
+
// starts and rare non-binary error flags by keeping per-field emits so
|
|
329
|
+
// each integer picks the shortest msgpack encoding.
|
|
330
|
+
const errorIsFixint = span.error === 0 || span.error === 1
|
|
331
|
+
const startFitsU64 = span.start >= 0x1_00_00_00_00
|
|
332
|
+
const fuseTail = errorIsFixint && startFitsU64
|
|
333
|
+
|
|
306
334
|
let blockSize = 1 +
|
|
307
335
|
KEY_TRACE_ID_PREFIX.length + 8 +
|
|
308
336
|
KEY_SPAN_ID_PREFIX.length + 8 +
|
|
@@ -311,6 +339,9 @@ class AgentEncoder {
|
|
|
311
339
|
KEY_RESOURCE.length + resourceLen +
|
|
312
340
|
KEY_SERVICE.length + serviceLen
|
|
313
341
|
if (typeEntry) blockSize += KEY_TYPE.length + typeEntry.length
|
|
342
|
+
if (fuseTail) {
|
|
343
|
+
blockSize += KEY_ERROR_0.length + KEY_START_PREFIX.length + 8 + KEY_DURATION.length
|
|
344
|
+
}
|
|
314
345
|
|
|
315
346
|
const blockOffset = bytes.length
|
|
316
347
|
bytes.reserve(blockSize)
|
|
@@ -343,13 +374,35 @@ class AgentEncoder {
|
|
|
343
374
|
target.set(KEY_SERVICE, cursor)
|
|
344
375
|
cursor += KEY_SERVICE.length
|
|
345
376
|
target.set(serviceEntry, cursor)
|
|
377
|
+
cursor += serviceLen
|
|
378
|
+
|
|
379
|
+
if (fuseTail) {
|
|
380
|
+
target.set(span.error === 0 ? KEY_ERROR_0 : KEY_ERROR_1, cursor)
|
|
381
|
+
cursor += KEY_ERROR_0.length
|
|
346
382
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
383
|
+
target.set(KEY_START_PREFIX, cursor)
|
|
384
|
+
cursor += KEY_START_PREFIX.length
|
|
385
|
+
// Inline u64 write so the 0xCF type byte and the 8 timestamp bytes
|
|
386
|
+
// share the same reserve as the keys.
|
|
387
|
+
target.writeUInt32BE((span.start / 0x1_00_00_00_00) >>> 0, cursor)
|
|
388
|
+
target.writeUInt32BE(span.start >>> 0, cursor + 4)
|
|
389
|
+
cursor += 8
|
|
390
|
+
|
|
391
|
+
target.set(KEY_DURATION, cursor)
|
|
392
|
+
} else {
|
|
393
|
+
if (span.error === 0) {
|
|
394
|
+
bytes.set(KEY_ERROR_0)
|
|
395
|
+
} else if (span.error === 1) {
|
|
396
|
+
bytes.set(KEY_ERROR_1)
|
|
397
|
+
} else {
|
|
398
|
+
bytes.set(KEY_ERROR)
|
|
399
|
+
bytes.writeIntOrFloat(span.error)
|
|
400
|
+
}
|
|
401
|
+
bytes.set(KEY_START)
|
|
402
|
+
bytes.writeIntOrFloat(span.start)
|
|
403
|
+
bytes.set(KEY_DURATION)
|
|
404
|
+
}
|
|
405
|
+
bytes.writeIntOrFloat(span.duration)
|
|
353
406
|
|
|
354
407
|
this.#encodeMetaEntries(bytes, KEY_META_PREFIX, span.meta)
|
|
355
408
|
this.#encodeMetaEntries(bytes, KEY_METRICS_PREFIX, span.metrics)
|
|
@@ -390,34 +443,14 @@ class AgentEncoder {
|
|
|
390
443
|
|
|
391
444
|
_reset () {
|
|
392
445
|
this._traceCount = 0
|
|
393
|
-
this._traceBytes.
|
|
446
|
+
this._traceBytes.reset()
|
|
394
447
|
this._stringCount = 0
|
|
395
|
-
this._stringBytes.
|
|
448
|
+
this._stringBytes.reset()
|
|
396
449
|
this._stringMap = Object.create(null)
|
|
397
450
|
|
|
398
451
|
this._cacheString('')
|
|
399
452
|
}
|
|
400
453
|
|
|
401
|
-
_encodeBuffer (bytes, buffer) {
|
|
402
|
-
this.#msgpack.encodeBin(bytes, buffer)
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
_encodeBool (bytes, value) {
|
|
406
|
-
this.#msgpack.encodeBoolean(bytes, value)
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
_encodeArrayPrefix (bytes, value) {
|
|
410
|
-
this.#msgpack.encodeArrayPrefix(bytes, value)
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
_encodeMapPrefix (bytes, keysLength) {
|
|
414
|
-
this.#msgpack.encodeMapPrefix(bytes, keysLength)
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
_encodeByte (bytes, value) {
|
|
418
|
-
this.#msgpack.encodeByte(bytes, value)
|
|
419
|
-
}
|
|
420
|
-
|
|
421
454
|
// TODO: Use BigInt instead.
|
|
422
455
|
_encodeId (bytes, identifier) {
|
|
423
456
|
const idBuffer = identifier.toBuffer()
|
|
@@ -438,18 +471,6 @@ class AgentEncoder {
|
|
|
438
471
|
target[offset + 8] = idBuffer[start + 7]
|
|
439
472
|
}
|
|
440
473
|
|
|
441
|
-
_encodeNumber (bytes, value) {
|
|
442
|
-
this.#msgpack.encodeNumber(bytes, value)
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
_encodeInteger (bytes, value) {
|
|
446
|
-
this.#msgpack.encodeInteger(bytes, value)
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
_encodeLong (bytes, value) {
|
|
450
|
-
this.#msgpack.encodeLong(bytes, value)
|
|
451
|
-
}
|
|
452
|
-
|
|
453
474
|
// Single pass: reserve the count slot, encode entries while counting, patch the count.
|
|
454
475
|
// Subclasses (0.5, CI visibility encoders) inherit this; the wire stays on float64
|
|
455
476
|
// for numeric values to keep their established trace / events intake unchanged.
|
|
@@ -467,7 +488,7 @@ class AgentEncoder {
|
|
|
467
488
|
count++
|
|
468
489
|
} else if (typeof entryValue === 'number') {
|
|
469
490
|
this._encodeString(bytes, key)
|
|
470
|
-
|
|
491
|
+
bytes.writeFloat(entryValue)
|
|
471
492
|
count++
|
|
472
493
|
}
|
|
473
494
|
}
|
|
@@ -480,6 +501,10 @@ class AgentEncoder {
|
|
|
480
501
|
}
|
|
481
502
|
|
|
482
503
|
_encodeString (bytes, value = '') {
|
|
504
|
+
if (value.length > STRING_CACHE_BYPASS_LIMIT) {
|
|
505
|
+
bytes.write(value)
|
|
506
|
+
return
|
|
507
|
+
}
|
|
483
508
|
const entry = this._stringMap[value] ?? this._cacheString(value)
|
|
484
509
|
const length = entry.length
|
|
485
510
|
const offset = bytes.length
|
|
@@ -540,6 +565,17 @@ class AgentEncoder {
|
|
|
540
565
|
const writeOffset = bytes.length
|
|
541
566
|
|
|
542
567
|
if (typeof entryValue === 'string') {
|
|
568
|
+
if (entryValue.length > STRING_CACHE_BYPASS_LIMIT) {
|
|
569
|
+
// Long values (events JSON, stack traces, large query bodies) are
|
|
570
|
+
// unique per span; hashing them for the cache lookup costs more
|
|
571
|
+
// than the lookup ever recovers. Emit the key from the cache and
|
|
572
|
+
// stream the value directly.
|
|
573
|
+
bytes.reserve(keyEntryLen)
|
|
574
|
+
bytes.buffer.set(keyEntry, writeOffset)
|
|
575
|
+
bytes.write(entryValue)
|
|
576
|
+
count++
|
|
577
|
+
continue
|
|
578
|
+
}
|
|
543
579
|
const valueEntry = stringMap[entryValue] ?? this._cacheString(entryValue)
|
|
544
580
|
const valueEntryLen = valueEntry.length
|
|
545
581
|
bytes.reserve(keyEntryLen + valueEntryLen)
|
|
@@ -547,9 +583,22 @@ class AgentEncoder {
|
|
|
547
583
|
target.set(keyEntry, writeOffset)
|
|
548
584
|
target.set(valueEntry, writeOffset + keyEntryLen)
|
|
549
585
|
} else {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
586
|
+
// Speculate that `entryValue` is a positive fixint (0..127): one
|
|
587
|
+
// reserve covers both the key and the value. The metrics map (sample
|
|
588
|
+
// rate, priority, `_dd.measured`, attribute counts) is mostly small
|
|
589
|
+
// unsigned integers, so the speculation wins on every entry that
|
|
590
|
+
// doesn't go through the slow `writeIntOrFloat` dispatch chain.
|
|
591
|
+
bytes.reserve(keyEntryLen + 1)
|
|
592
|
+
const target = bytes.buffer
|
|
593
|
+
target.set(keyEntry, writeOffset)
|
|
594
|
+
if (entryValue === (entryValue & 0x7F)) {
|
|
595
|
+
target[writeOffset + keyEntryLen] = entryValue
|
|
596
|
+
} else {
|
|
597
|
+
// Speculation missed; rewind the speculative byte and route the
|
|
598
|
+
// value through the full encoder so it picks the right type.
|
|
599
|
+
bytes.length = writeOffset + keyEntryLen
|
|
600
|
+
bytes.writeIntOrFloat(entryValue)
|
|
601
|
+
}
|
|
553
602
|
}
|
|
554
603
|
count++
|
|
555
604
|
}
|
|
@@ -589,41 +638,6 @@ class AgentEncoder {
|
|
|
589
638
|
return offset + 8
|
|
590
639
|
}
|
|
591
640
|
|
|
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
|
-
*
|
|
601
|
-
* @param {MsgpackChunk} bytes
|
|
602
|
-
* @param {number} value
|
|
603
|
-
*/
|
|
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
|
-
}
|
|
625
|
-
}
|
|
626
|
-
|
|
627
641
|
/**
|
|
628
642
|
* @param {MsgpackChunk} bytes
|
|
629
643
|
* @param {string | number | boolean} value
|
|
@@ -634,21 +648,17 @@ class AgentEncoder {
|
|
|
634
648
|
this._encodeString(bytes, value)
|
|
635
649
|
break
|
|
636
650
|
case 'number':
|
|
637
|
-
|
|
651
|
+
bytes.writeFloat(value)
|
|
638
652
|
break
|
|
639
653
|
case 'boolean':
|
|
640
|
-
|
|
654
|
+
bytes.writeBoolean(value)
|
|
641
655
|
break
|
|
642
656
|
}
|
|
643
657
|
}
|
|
644
658
|
|
|
645
|
-
#encodeFloat (bytes, value) {
|
|
646
|
-
this.#msgpack.encodeFloat(bytes, value)
|
|
647
|
-
}
|
|
648
|
-
|
|
649
659
|
#encodeMetaStruct (bytes, value) {
|
|
650
660
|
if (Array.isArray(value)) {
|
|
651
|
-
|
|
661
|
+
bytes.writeMapPrefix(0)
|
|
652
662
|
return
|
|
653
663
|
}
|
|
654
664
|
|
|
@@ -774,7 +784,7 @@ class AgentEncoder {
|
|
|
774
784
|
bytes.set(KEY_NAME)
|
|
775
785
|
this._encodeString(bytes, event.name)
|
|
776
786
|
bytes.set(KEY_EVENT_TIME)
|
|
777
|
-
|
|
787
|
+
bytes.writeFloat(event.time_unix_nano)
|
|
778
788
|
|
|
779
789
|
const attributes = event.attributes
|
|
780
790
|
if (attributes !== null && typeof attributes === 'object') {
|
|
@@ -844,7 +854,7 @@ class AgentEncoder {
|
|
|
844
854
|
if (typeof value === 'number') {
|
|
845
855
|
this._encodeString(bytes, key)
|
|
846
856
|
bytes.set(Number.isInteger(value) ? ATTR_PREFIX_INT : ATTR_PREFIX_DOUBLE)
|
|
847
|
-
|
|
857
|
+
bytes.writeIntOrFloat(value)
|
|
848
858
|
return true
|
|
849
859
|
}
|
|
850
860
|
if (typeof value === 'boolean') {
|
|
@@ -855,8 +865,11 @@ class AgentEncoder {
|
|
|
855
865
|
if (Array.isArray(value)) {
|
|
856
866
|
return this.#emitArrayAttribute(bytes, key, value)
|
|
857
867
|
}
|
|
858
|
-
memoizedLogDebug(
|
|
859
|
-
|
|
868
|
+
memoizedLogDebug(
|
|
869
|
+
key,
|
|
870
|
+
'Encountered unsupported data type for span event v0.4 encoding, key: ' +
|
|
871
|
+
'%s: with value: %s. Skipping encoding of pair.',
|
|
872
|
+
value
|
|
860
873
|
)
|
|
861
874
|
return false
|
|
862
875
|
}
|
|
@@ -914,7 +927,7 @@ class AgentEncoder {
|
|
|
914
927
|
}
|
|
915
928
|
if (typeof value === 'number') {
|
|
916
929
|
bytes.set(Number.isInteger(value) ? ATTR_PREFIX_INT : ATTR_PREFIX_DOUBLE)
|
|
917
|
-
|
|
930
|
+
bytes.writeIntOrFloat(value)
|
|
918
931
|
return true
|
|
919
932
|
}
|
|
920
933
|
if (typeof value === 'boolean') {
|
|
@@ -922,8 +935,11 @@ class AgentEncoder {
|
|
|
922
935
|
return true
|
|
923
936
|
}
|
|
924
937
|
if (Array.isArray(value)) {
|
|
925
|
-
memoizedLogDebug(
|
|
926
|
-
|
|
938
|
+
memoizedLogDebug(
|
|
939
|
+
key,
|
|
940
|
+
'Encountered nested array data type for span event v0.4 encoding. ' +
|
|
941
|
+
'Skipping encoding key: %s: with value: %s.',
|
|
942
|
+
value
|
|
927
943
|
)
|
|
928
944
|
}
|
|
929
945
|
return false
|
|
@@ -931,10 +947,10 @@ class AgentEncoder {
|
|
|
931
947
|
}
|
|
932
948
|
|
|
933
949
|
const seenKeys = new Set()
|
|
934
|
-
function memoizedLogDebug (key, message) {
|
|
950
|
+
function memoizedLogDebug (key, message, value) {
|
|
935
951
|
if (!seenKeys.has(key)) {
|
|
936
952
|
seenKeys.add(key)
|
|
937
|
-
log.debug(message)
|
|
953
|
+
log.debug(message, key, typeof value)
|
|
938
954
|
}
|
|
939
955
|
}
|
|
940
956
|
|