dd-trace 6.10.0 → 6.12.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 +5 -0
- package/README.md +0 -17
- package/index.d.ts +128 -6
- package/initialize.mjs +28 -17
- package/openfeature.js +2 -2
- package/package.json +27 -23
- package/packages/datadog-esbuild/index.js +0 -34
- package/packages/datadog-instrumentations/src/anthropic.js +210 -15
- package/packages/datadog-instrumentations/src/aws-sdk.js +9 -1
- package/packages/datadog-instrumentations/src/browser-bunyan.js +11 -0
- package/packages/datadog-instrumentations/src/bunyan.js +3 -16
- package/packages/datadog-instrumentations/src/cucumber.js +30 -15
- package/packages/datadog-instrumentations/src/cypress-config.js +182 -16
- package/packages/datadog-instrumentations/src/cypress-legacy-finalizers.js +30 -0
- package/packages/datadog-instrumentations/src/cypress.js +2 -0
- package/packages/datadog-instrumentations/src/fastify.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/bunyan.js +22 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +9 -4
- package/packages/datadog-instrumentations/src/helpers/register.js +10 -8
- package/packages/datadog-instrumentations/src/jest.js +25 -17
- package/packages/datadog-instrumentations/src/mariadb.js +278 -21
- package/packages/datadog-instrumentations/src/mocha/main.js +539 -55
- package/packages/datadog-instrumentations/src/mocha/utils.js +135 -19
- package/packages/datadog-instrumentations/src/playwright-reporter.js +247 -0
- package/packages/datadog-instrumentations/src/playwright.js +182 -35
- package/packages/datadog-instrumentations/src/router.js +2 -0
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +6 -8
- package/packages/datadog-instrumentations/src/vitest-main.js +11 -3
- package/packages/datadog-plugin-aws-sdk/src/base.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +163 -44
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -8
- package/packages/datadog-plugin-azure-functions/src/index.js +1 -1
- package/packages/datadog-plugin-browser-bunyan/src/index.js +9 -0
- package/packages/datadog-plugin-bunyan/src/index.js +5 -8
- package/packages/datadog-plugin-cucumber/src/index.js +11 -0
- package/packages/datadog-plugin-cypress/src/after-run.js +5 -1
- package/packages/datadog-plugin-cypress/src/after-spec.js +5 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +81 -29
- package/packages/datadog-plugin-cypress/src/finalization.js +76 -0
- package/packages/datadog-plugin-cypress/src/index.js +12 -6
- package/packages/datadog-plugin-cypress/src/plugin.js +16 -3
- package/packages/datadog-plugin-dd-trace-api/src/index.js +4 -0
- package/packages/datadog-plugin-electron/src/index.js +2 -0
- package/packages/datadog-plugin-fs/src/index.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +6 -0
- package/packages/datadog-plugin-mocha/src/index.js +56 -1
- package/packages/datadog-plugin-nats/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/tracing.js +41 -30
- package/packages/datadog-plugin-openai-agents/src/integration.js +1 -0
- package/packages/datadog-plugin-playwright/src/index.js +46 -13
- package/packages/datadog-plugin-vitest/src/index.js +6 -0
- package/packages/datadog-webpack/index.js +0 -11
- package/packages/dd-trace/index.js +0 -1
- package/packages/dd-trace/src/agent/info.js +6 -5
- package/packages/dd-trace/src/aiguard/client.js +100 -1
- package/packages/dd-trace/src/aiguard/errors.js +41 -0
- package/packages/dd-trace/src/aiguard/evaluation.js +357 -0
- package/packages/dd-trace/src/aiguard/integrations/anthropic.js +70 -0
- package/packages/dd-trace/src/aiguard/integrations/index.js +4 -0
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +423 -0
- package/packages/dd-trace/src/aiguard/messages/openai.js +1 -24
- package/packages/dd-trace/src/aiguard/messages/utils.js +28 -0
- package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +1 -11
- package/packages/dd-trace/src/aiguard/sdk.js +22 -278
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +9 -12
- package/packages/dd-trace/src/appsec/reporter.js +2 -0
- package/packages/dd-trace/src/appsec/telemetry/index.js +13 -0
- package/packages/dd-trace/src/appsec/telemetry/rasp.js +16 -0
- package/packages/dd-trace/src/appsec/telemetry/waf.js +24 -0
- package/packages/dd-trace/src/carrier.js +107 -48
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +1 -0
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +5 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +29 -3
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +27 -9
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +21 -5
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +164 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +26 -8
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +365 -32
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -4
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +201 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +9 -5
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +7 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -2
- package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +39 -0
- package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -6
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +4 -2
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +10 -4
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +5 -5
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -0
- package/packages/dd-trace/src/config/index.js +13 -2
- package/packages/dd-trace/src/config/major-overrides.js +7 -0
- package/packages/dd-trace/src/config/supported-configurations.json +14 -0
- package/packages/dd-trace/src/datastreams/index.js +2 -0
- package/packages/dd-trace/src/datastreams/manager.js +9 -2
- package/packages/dd-trace/src/datastreams/processor.js +15 -13
- package/packages/dd-trace/src/datastreams/size.js +5 -0
- package/packages/dd-trace/src/debugger/constants.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/index.js +5 -11
- package/packages/dd-trace/src/debugger/index.js +4 -2
- package/packages/dd-trace/src/debugger/inspect-segment.js +154 -0
- package/packages/dd-trace/src/evp_proxy/constants.js +8 -0
- package/packages/dd-trace/src/evp_proxy/direct.js +64 -0
- package/packages/dd-trace/src/evp_proxy/discovery.js +133 -0
- package/packages/dd-trace/src/evp_proxy/path.js +22 -0
- package/packages/dd-trace/src/exporters/agent/writer.js +49 -9
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +6 -4
- package/packages/dd-trace/src/exporters/common/request.js +5 -2
- package/packages/dd-trace/src/exporters/common/writer.js +11 -6
- package/packages/dd-trace/src/llmobs/experiments/client.js +167 -5
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +484 -92
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +302 -29
- package/packages/dd-trace/src/llmobs/experiments/index.js +75 -64
- package/packages/dd-trace/src/llmobs/experiments/noop.js +135 -7
- package/packages/dd-trace/src/llmobs/experiments/result.js +1 -0
- package/packages/dd-trace/src/llmobs/experiments/util.js +101 -9
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +12 -3
- package/packages/dd-trace/src/llmobs/plugins/base.js +4 -2
- package/packages/dd-trace/src/noop/proxy.js +3 -4
- package/packages/dd-trace/src/openfeature/constants/constants.js +0 -18
- package/packages/dd-trace/src/openfeature/flagging_provider.js +18 -2
- package/packages/dd-trace/src/openfeature/index.js +7 -4
- package/packages/dd-trace/src/openfeature/remote_config.js +1 -1
- package/packages/dd-trace/src/openfeature/writers/base.js +153 -11
- package/packages/dd-trace/src/openfeature/writers/exposures.js +62 -14
- package/packages/dd-trace/src/openfeature/writers/util.js +97 -15
- package/packages/dd-trace/src/opentelemetry/context_manager.js +7 -7
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +2 -1
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +67 -11
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +14 -3
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +25 -12
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +2 -5
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +96 -43
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +22 -13
- package/packages/dd-trace/src/opentracing/tracer.js +5 -2
- package/packages/dd-trace/src/otel-thread-ctx.js +387 -0
- package/packages/dd-trace/src/plugin_manager.js +3 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +6 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/jest.js +4 -3
- package/packages/dd-trace/src/plugins/util/test.js +9 -9
- package/packages/dd-trace/src/plugins/util/web.js +3 -0
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +1 -3
- package/packages/dd-trace/src/profiling/profilers/wall.js +37 -90
- package/packages/dd-trace/src/profiling/webspan-utils.js +45 -0
- package/packages/dd-trace/src/proxy.js +38 -29
- package/packages/dd-trace/src/ritm.js +9 -2
- package/packages/dd-trace/src/serverless.js +37 -0
- package/packages/dd-trace/src/span_format.js +1 -0
- package/packages/dd-trace/src/span_stats.js +30 -3
- package/packages/dd-trace/src/storage-channels.js +86 -0
- package/packages/dd-trace/src/telemetry/metrics.js +62 -8
- package/packages/dd-trace/src/telemetry/send-data.js +1 -0
- package/packages/dd-trace/src/tracer.js +9 -2
- package/packages/dd-trace/src/tracer_metadata.js +14 -1
- package/packages/dd-trace/src/web-tags-cache.js +132 -0
- package/vendor/dist/@datadog/openfeature-node-server/LICENSE +201 -0
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -0
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/https-proxy-agent/LICENSE +22 -0
- package/vendor/dist/https-proxy-agent/index.js +4 -0
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/vendor/dist/proxy-from-env/LICENSE +20 -0
- package/vendor/dist/proxy-from-env/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +0 -65
- package/packages/datadog-webpack/src/optional-peer-loader.js +0 -17
- package/packages/dd-trace/src/feature-registry.js +0 -29
- package/packages/dd-trace/src/openfeature/register.js +0 -35
- package/packages/dd-trace/src/openfeature/require-provider.js +0 -18
|
@@ -5,25 +5,17 @@ const pkg = require('../../../../package.json')
|
|
|
5
5
|
|
|
6
6
|
const { LogCollapsingLowestDenseDDSketch } = require('../../../../vendor/dist/@datadog/sketches-js')
|
|
7
7
|
const { PATHWAY_HASH, DSM_TRANSACTION_ID, DSM_TRANSACTION_CHECKPOINT } = require('../../../../ext/tags')
|
|
8
|
-
const { dsmBase64NameLength } = require('../carrier')
|
|
9
8
|
const log = require('../log')
|
|
10
9
|
const processTags = require('../process-tags')
|
|
11
10
|
const propagationHash = require('../propagation-hash')
|
|
12
11
|
const { computePathwayHash } = require('./pathway')
|
|
13
12
|
const { DataStreamsWriter } = require('./writer')
|
|
14
|
-
const { getAmqpMessageSize, getHeadersSize, getMessageSize, getSizeOrZero } = require('./size')
|
|
13
|
+
const { getAmqpMessageSize, getHeadersSize, getMessageSize, getSizeOrZero, PATHWAY_FIELD_BYTES } = require('./size')
|
|
15
14
|
const { SchemaBuilder } = require('./schemas/schema_builder')
|
|
16
15
|
const { SchemaSampler } = require('./schemas/schema_sampler')
|
|
17
16
|
|
|
18
17
|
const ENTRY_PARENT_HASH = Buffer.from('0000000000000000', 'hex')
|
|
19
18
|
|
|
20
|
-
// A direction:out checkpoint estimates the size cost of the header the
|
|
21
|
-
// producer plugin will inject. The pathway context is always 20 binary
|
|
22
|
-
// bytes, encoded as 28 base64 chars; together with the header key and
|
|
23
|
-
// JSON framing (matching the prior `JSON.stringify({key: value})` byte
|
|
24
|
-
// count minus 1), this is a fixed value.
|
|
25
|
-
const PATHWAY_HEADER_BYTES = dsmBase64NameLength + 28 + 6
|
|
26
|
-
|
|
27
19
|
class StatsPoint {
|
|
28
20
|
constructor (hash, parentHash, edgeTags) {
|
|
29
21
|
this.hash = hash.readBigUInt64LE()
|
|
@@ -290,10 +282,19 @@ class DataStreamsProcessor {
|
|
|
290
282
|
if (this.flushInterval === 0) this.onInterval()
|
|
291
283
|
}
|
|
292
284
|
|
|
293
|
-
|
|
285
|
+
/**
|
|
286
|
+
* @param {string[]} edgeTags Direction tag first.
|
|
287
|
+
* @param {import('../opentracing/span')|null} span
|
|
288
|
+
* @param {object|null|undefined} ctx Parent pathway context.
|
|
289
|
+
* @param {number} [payloadSize] Bytes the caller built, before any propagation context.
|
|
290
|
+
* @param {number} [pathwayContextSize] Bytes the pathway context adds to an outbound payload.
|
|
291
|
+
* Most producers size their payload before this call hands them the context to inject, so they
|
|
292
|
+
* cannot measure it and take the default estimate. Pass `0` to report the payload alone.
|
|
293
|
+
* @returns {object|undefined}
|
|
294
|
+
*/
|
|
295
|
+
setCheckpoint (edgeTags, span, ctx, payloadSize = 0, pathwayContextSize = PATHWAY_FIELD_BYTES) {
|
|
294
296
|
if (!this.enabled) return
|
|
295
297
|
const nowNs = Date.now() * 1e6
|
|
296
|
-
// Callers must place the direction tag at index 0.
|
|
297
298
|
const direction = edgeTags[0]
|
|
298
299
|
let pathwayStartNs = nowNs
|
|
299
300
|
let edgeStartNs = nowNs
|
|
@@ -338,14 +339,15 @@ class DataStreamsProcessor {
|
|
|
338
339
|
const pathwayLatencyNs = nowNs - pathwayStartNs
|
|
339
340
|
const dataStreamsContext = {
|
|
340
341
|
hash,
|
|
341
|
-
|
|
342
|
+
// start the next hop's edge clock here so edge latency stays per-hop
|
|
343
|
+
edgeStartNs: nowNs,
|
|
342
344
|
pathwayStartNs,
|
|
343
345
|
previousDirection: direction,
|
|
344
346
|
closestOppositeDirectionHash,
|
|
345
347
|
closestOppositeDirectionEdgeStart,
|
|
346
348
|
}
|
|
347
349
|
if (direction === 'direction:out') {
|
|
348
|
-
payloadSize +=
|
|
350
|
+
payloadSize += pathwayContextSize
|
|
349
351
|
}
|
|
350
352
|
const checkpoint = {
|
|
351
353
|
currentTimestamp: nowNs,
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
const { types } = require('util')
|
|
4
4
|
|
|
5
|
+
// Byte cost of the `,"dd-pathway-ctx-base64":"<28 chars>"` field a producer adds to a JSON carrier.
|
|
6
|
+
// A literal so eager `size` consumers don't pull in `./pathway`; `pathway.spec.js` pins it there.
|
|
7
|
+
const PATHWAY_FIELD_BYTES = 55
|
|
8
|
+
|
|
5
9
|
function getSizeOrZero (obj) {
|
|
6
10
|
if (typeof obj === 'string') {
|
|
7
11
|
return Buffer.byteLength(obj, 'utf8')
|
|
@@ -54,4 +58,5 @@ module.exports = {
|
|
|
54
58
|
getHeadersSize,
|
|
55
59
|
getSizeOrZero,
|
|
56
60
|
getAmqpMessageSize,
|
|
61
|
+
PATHWAY_FIELD_BYTES,
|
|
57
62
|
}
|
|
@@ -55,7 +55,7 @@ function compileSegments (segments) {
|
|
|
55
55
|
? `(() => {
|
|
56
56
|
try {
|
|
57
57
|
const result = ${compile(json)}
|
|
58
|
-
return typeof result === 'string' ? result : $
|
|
58
|
+
return typeof result === 'string' ? result : $dd_inspectSegment(result)
|
|
59
59
|
} catch (e) {
|
|
60
60
|
return { expr: ${JSON.stringify(dsl)}, message: \`\${e.name}: \${e.message}\` }
|
|
61
61
|
}
|
|
@@ -4,6 +4,7 @@ const { randomUUID } = require('crypto')
|
|
|
4
4
|
const { workerData: { probeSamplerBuffer } } = require('worker_threads')
|
|
5
5
|
const { version } = require('../../../../../package.json')
|
|
6
6
|
const processTags = require('../../process-tags')
|
|
7
|
+
const { INSPECT_SEGMENT_GLOBAL_PROPERTY } = require('../constants')
|
|
7
8
|
const {
|
|
8
9
|
MAX_SAMPLED_PROBES_PER_PAUSE,
|
|
9
10
|
SAMPLED_PROBE_COUNT_INDEX,
|
|
@@ -23,19 +24,12 @@ require('./remote_config')
|
|
|
23
24
|
|
|
24
25
|
/** @typedef {import('node:inspector').Debugger.EvaluateOnCallFrameReturnType} EvaluateOnCallFrameResult */
|
|
25
26
|
|
|
27
|
+
const templateExpressionSetupCode = 'const $dd_inspectSegment = ' +
|
|
28
|
+
`globalThis[Symbol.for('dd-trace')][${JSON.stringify(INSPECT_SEGMENT_GLOBAL_PROPERTY)}];`
|
|
29
|
+
|
|
26
30
|
// Expression to run on a call frame of the paused thread to get its active trace and span id.
|
|
27
|
-
const templateExpressionSetupCode = `
|
|
28
|
-
const $dd_inspect = global.require('node:util').inspect;
|
|
29
|
-
const $dd_segmentInspectOptions = {
|
|
30
|
-
depth: 0,
|
|
31
|
-
customInspect: false,
|
|
32
|
-
maxArrayLength: 3,
|
|
33
|
-
maxStringLength: 8 * 1024,
|
|
34
|
-
breakLength: Infinity
|
|
35
|
-
};
|
|
36
|
-
`
|
|
37
31
|
const getDDTagsExpression = `(() => {
|
|
38
|
-
const context =
|
|
32
|
+
const context = globalThis._ddtrace.scope().active()?.context();
|
|
39
33
|
return { trace_id: context?.toTraceId(), span_id: context?.toSpanId() }
|
|
40
34
|
})()`
|
|
41
35
|
|
|
@@ -7,7 +7,7 @@ const { Worker, MessageChannel, threadId: parentThreadId } = require('worker_thr
|
|
|
7
7
|
const log = require('../log')
|
|
8
8
|
const { fetchAgentInfo } = require('../agent/info')
|
|
9
9
|
const getDebuggerConfig = require('./config')
|
|
10
|
-
const { DEBUGGER_DIAGNOSTICS_V1, DEBUGGER_INPUT_V2 } = require('./constants')
|
|
10
|
+
const { DEBUGGER_DIAGNOSTICS_V1, DEBUGGER_INPUT_V2, INSPECT_SEGMENT_GLOBAL_PROPERTY } = require('./constants')
|
|
11
11
|
const { installProbeSampler, uninstallProbeSampler } = require('./probe_sampler')
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -64,7 +64,9 @@ function start (config, rcInstance) {
|
|
|
64
64
|
const logChannel = new MessageChannel()
|
|
65
65
|
configChannel = new MessageChannel()
|
|
66
66
|
|
|
67
|
-
globalThis[Symbol.for('dd-trace')]
|
|
67
|
+
const debuggerGlobals = globalThis[Symbol.for('dd-trace')]
|
|
68
|
+
debuggerGlobals.utilTypes = types
|
|
69
|
+
debuggerGlobals[INSPECT_SEGMENT_GLOBAL_PROPERTY] = require('./inspect-segment')
|
|
68
70
|
|
|
69
71
|
const probeSamplerBuffer = installProbeSampler()
|
|
70
72
|
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { inspect, types } = require('node:util')
|
|
4
|
+
|
|
5
|
+
const { NODE_MAJOR } = require('../../../../version')
|
|
6
|
+
|
|
7
|
+
/** @typedef {NonNullable<ReturnType<typeof globalThis.Object.getOwnPropertyDescriptor>>} PropertyDescriptor */
|
|
8
|
+
/** @typedef {Map<unknown, unknown> | Set<unknown>} Collection */
|
|
9
|
+
|
|
10
|
+
const mapEntries = Map.prototype.entries
|
|
11
|
+
const mapSet = Map.prototype.set
|
|
12
|
+
const mapSizeGetter = Object.getOwnPropertyDescriptor(Map.prototype, 'size').get
|
|
13
|
+
const setAdd = Set.prototype.add
|
|
14
|
+
const setSizeGetter = Object.getOwnPropertyDescriptor(Set.prototype, 'size').get
|
|
15
|
+
const setValues = Set.prototype.values
|
|
16
|
+
const mapIteratorNext = Object.getPrototypeOf(mapEntries.call(new Map())).next
|
|
17
|
+
const setIteratorNext = Object.getPrototypeOf(setValues.call(new Set())).next
|
|
18
|
+
|
|
19
|
+
const maxCollectionEntries = 3
|
|
20
|
+
const maxProperties = 5
|
|
21
|
+
const segmentInspectOptions = {
|
|
22
|
+
depth: 0,
|
|
23
|
+
customInspect: false,
|
|
24
|
+
maxArrayLength: maxCollectionEntries,
|
|
25
|
+
maxStringLength: 8 * 1024,
|
|
26
|
+
breakLength: Infinity,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = inspectSegment
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Inspect a dynamic-instrumentation template value without invoking user code.
|
|
33
|
+
* Unlike collections, `util.inspect` has no option for limiting the number of object properties, so this function
|
|
34
|
+
* truncates objects before inspecting them.
|
|
35
|
+
*
|
|
36
|
+
* @param {unknown} value
|
|
37
|
+
* @returns {string}
|
|
38
|
+
*/
|
|
39
|
+
function inspectSegment (value) {
|
|
40
|
+
if (value === null || (typeof value !== 'object' && typeof value !== 'function')) {
|
|
41
|
+
return inspect(value, segmentInspectOptions)
|
|
42
|
+
}
|
|
43
|
+
if (types.isProxy(value)) return '[Proxy]'
|
|
44
|
+
if (types.isMap(value)) return inspectCollection(value, true)
|
|
45
|
+
if (types.isSet(value)) return inspectCollection(value, false)
|
|
46
|
+
if (
|
|
47
|
+
Array.isArray(value) ||
|
|
48
|
+
types.isTypedArray(value) ||
|
|
49
|
+
types.isAnyArrayBuffer(value) ||
|
|
50
|
+
types.isDataView(value) ||
|
|
51
|
+
types.isWeakMap(value) ||
|
|
52
|
+
types.isWeakSet(value) ||
|
|
53
|
+
types.isMapIterator(value) ||
|
|
54
|
+
types.isSetIterator(value)
|
|
55
|
+
) {
|
|
56
|
+
return inspect(value, segmentInspectOptions)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** @type {(string | symbol)[]} */
|
|
60
|
+
const keys = Object.keys(value)
|
|
61
|
+
let propertyCount = keys.length
|
|
62
|
+
const symbols = Object.getOwnPropertySymbols(value)
|
|
63
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
64
|
+
if (Object.getOwnPropertyDescriptor(value, symbols[i])?.enumerable === true) {
|
|
65
|
+
propertyCount++
|
|
66
|
+
if (keys.length < maxProperties) keys.push(symbols[i])
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (propertyCount <= maxProperties) {
|
|
71
|
+
// TODO: Decide whether allowing util.inspect to invoke Symbol.toStringTag getters is acceptable. If it is,
|
|
72
|
+
// remove inspectionCanRunUserCode and the related omission paths.
|
|
73
|
+
if (inspectionCanRunUserCode(value)) {
|
|
74
|
+
return '[Value omitted: inspection may execute user code]'
|
|
75
|
+
}
|
|
76
|
+
return inspect(value, segmentInspectOptions)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const truncated = {}
|
|
80
|
+
for (let i = 0; i < maxProperties; i++) {
|
|
81
|
+
const descriptor = /** @type {PropertyDescriptor} */ (Object.getOwnPropertyDescriptor(value, keys[i]))
|
|
82
|
+
if (
|
|
83
|
+
(keys[i] === Symbol.toStringTag && descriptor.get !== undefined) ||
|
|
84
|
+
(descriptor.value !== value && inspectionCanRunUserCode(descriptor.value))
|
|
85
|
+
) {
|
|
86
|
+
return '[Value omitted: inspection may execute user code]'
|
|
87
|
+
}
|
|
88
|
+
if (descriptor.value === value) descriptor.value = truncated
|
|
89
|
+
Object.defineProperty(truncated, keys[i], descriptor)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const omitted = propertyCount - maxProperties
|
|
93
|
+
const inspected = inspect(truncated, segmentInspectOptions)
|
|
94
|
+
return `${inspected.slice(0, -2)}, ... ${omitted} more ${omitted === 1 ? 'property' : 'properties'} }`
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Inspect a Map or Set while bounding the number of entries on Node.js 18, where `util.inspect` does not.
|
|
99
|
+
*
|
|
100
|
+
* @param {Collection} value
|
|
101
|
+
* @param {boolean} isMap
|
|
102
|
+
* @returns {string}
|
|
103
|
+
*/
|
|
104
|
+
function inspectCollection (value, isMap) {
|
|
105
|
+
if (NODE_MAJOR !== 18) return inspect(value, segmentInspectOptions)
|
|
106
|
+
|
|
107
|
+
const size = (isMap ? mapSizeGetter : setSizeGetter).call(value)
|
|
108
|
+
if (size <= maxCollectionEntries) return inspect(value, segmentInspectOptions)
|
|
109
|
+
|
|
110
|
+
const truncated = isMap ? new Map() : new Set()
|
|
111
|
+
const iterator = (isMap ? mapEntries : setValues).call(value)
|
|
112
|
+
const iteratorNext = isMap ? mapIteratorNext : setIteratorNext
|
|
113
|
+
|
|
114
|
+
for (let i = 0; i < maxCollectionEntries; i++) {
|
|
115
|
+
const result = iteratorNext.call(iterator)
|
|
116
|
+
if (result.done) break
|
|
117
|
+
|
|
118
|
+
if (isMap) {
|
|
119
|
+
const entry = result.value
|
|
120
|
+
const key = entry[0] === value ? truncated : entry[0]
|
|
121
|
+
const entryValue = entry[1] === value ? truncated : entry[1]
|
|
122
|
+
mapSet.call(truncated, key, entryValue)
|
|
123
|
+
} else {
|
|
124
|
+
const entryValue = result.value === value ? truncated : result.value
|
|
125
|
+
setAdd.call(truncated, entryValue)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const type = isMap ? 'Map' : 'Set'
|
|
130
|
+
const inspected = inspect(truncated, segmentInspectOptions)
|
|
131
|
+
const normalized = inspected.replace(`${type}(${maxCollectionEntries})`, `${type}(${size})`)
|
|
132
|
+
const remaining = size - maxCollectionEntries
|
|
133
|
+
return `${normalized.slice(0, -2)}, ... ${remaining} more item${remaining === 1 ? '' : 's'} }`
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Determine whether inspecting a value could invoke a proxy trap or toStringTag getter.
|
|
138
|
+
*
|
|
139
|
+
* @param {unknown} value
|
|
140
|
+
* @returns {boolean}
|
|
141
|
+
*/
|
|
142
|
+
function inspectionCanRunUserCode (value) {
|
|
143
|
+
const type = typeof value
|
|
144
|
+
if (value === null || (type !== 'object' && type !== 'function')) return false
|
|
145
|
+
if (types.isProxy(value)) return true
|
|
146
|
+
|
|
147
|
+
let current = value
|
|
148
|
+
while (current !== null) {
|
|
149
|
+
if (Object.getOwnPropertyDescriptor(current, Symbol.toStringTag)?.get !== undefined) return true
|
|
150
|
+
current = Object.getPrototypeOf(current)
|
|
151
|
+
if (types.isProxy(current)) return true
|
|
152
|
+
}
|
|
153
|
+
return false
|
|
154
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { format } = require('node:url')
|
|
4
|
+
|
|
5
|
+
const { HttpsProxyAgent } = require('../../../../vendor/dist/https-proxy-agent')
|
|
6
|
+
const { getProxyForUrl } = require('../../../../vendor/dist/proxy-from-env')
|
|
7
|
+
const log = require('../log')
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {object} DirectEVPRoute
|
|
11
|
+
* @property {URL} url - Direct intake URL
|
|
12
|
+
* @property {string} basePath - Direct intake base path
|
|
13
|
+
* @property {object} headers - Direct intake authentication headers
|
|
14
|
+
* @property {import('node:https').Agent} [agent] - Optional HTTPS proxy agent
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Creates an authenticated direct EVP intake route.
|
|
19
|
+
*
|
|
20
|
+
* This helper does not perform local receiver discovery.
|
|
21
|
+
*
|
|
22
|
+
* @param {import('../config/config-base')} config - Tracer configuration
|
|
23
|
+
* @param {string} intake - EVP intake subdomain
|
|
24
|
+
* @returns {DirectEVPRoute|undefined} Direct route when credentials and site are available
|
|
25
|
+
*/
|
|
26
|
+
function createDirectEVPRoute (config, intake) {
|
|
27
|
+
const apiKey = config.DD_API_KEY
|
|
28
|
+
if (!apiKey || !config.site) return
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
const hostname = `${intake}.${config.site}`.toLowerCase()
|
|
32
|
+
const url = new URL(format({
|
|
33
|
+
protocol: 'https:',
|
|
34
|
+
hostname,
|
|
35
|
+
}))
|
|
36
|
+
if (
|
|
37
|
+
url.hostname !== hostname ||
|
|
38
|
+
url.username ||
|
|
39
|
+
url.password ||
|
|
40
|
+
url.port ||
|
|
41
|
+
url.pathname !== '/' ||
|
|
42
|
+
url.search ||
|
|
43
|
+
url.hash
|
|
44
|
+
) {
|
|
45
|
+
throw new Error('Invalid direct EVP intake URL')
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const proxyUrl = getProxyForUrl(url.href)
|
|
49
|
+
const agent = proxyUrl ? new HttpsProxyAgent(proxyUrl) : undefined
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
url,
|
|
53
|
+
basePath: '',
|
|
54
|
+
headers: {
|
|
55
|
+
'DD-API-KEY': apiKey,
|
|
56
|
+
},
|
|
57
|
+
...(agent && { agent }),
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
log.debug('Unable to configure direct EVP intake: %s', error.message)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = { createDirectEVPRoute }
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { fetchAgentInfo } = require('../agent/info')
|
|
4
|
+
const log = require('../log')
|
|
5
|
+
|
|
6
|
+
const TRAILING_SLASHES = /\/+$/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Receiver discovery contract
|
|
10
|
+
*
|
|
11
|
+
* The tracer sends `GET /info` to its configured local Agent URL. An
|
|
12
|
+
* Agent-compatible trace receiver produces the response. The tracer does not.
|
|
13
|
+
*
|
|
14
|
+
* The full Agent and serverless-init embed the same trace receiver. A future
|
|
15
|
+
* in-process receiver can expose the same contract. Callers can therefore
|
|
16
|
+
* select capabilities without detecting the receiver implementation.
|
|
17
|
+
*
|
|
18
|
+
* For EVP discovery, `endpoints` advertises registered proxy paths.
|
|
19
|
+
* `evp_proxy_allowed_headers` advertises headers that the proxy forwards to
|
|
20
|
+
* intake. It does not include routing headers that the proxy consumes, such as
|
|
21
|
+
* `X-Datadog-EVP-Subdomain`.
|
|
22
|
+
*
|
|
23
|
+
* An advertised route is not a health check. The receiver can register an EVP
|
|
24
|
+
* route while configuration disables its handler. The request then returns
|
|
25
|
+
* `405`. The `/info` version also identifies the embedded Agent code, not a
|
|
26
|
+
* serverless-init image or deployment type.
|
|
27
|
+
*
|
|
28
|
+
* This module only discovers a candidate route. A missing or unresponsive
|
|
29
|
+
* `/info` endpoint returns an error through the shared request timeout and
|
|
30
|
+
* retry policy. A valid response without a compatible path returns no route.
|
|
31
|
+
* Discovery sends no events, so the caller can safely select direct intake
|
|
32
|
+
* after either result. The caller also owns later delivery failures. Exposure
|
|
33
|
+
* delivery uses retries and can therefore produce duplicates. After local
|
|
34
|
+
* retries fail, the caller can retry through direct intake and use that route
|
|
35
|
+
* for future batches.
|
|
36
|
+
*
|
|
37
|
+
* Reference implementations:
|
|
38
|
+
*
|
|
39
|
+
* Agent `/info` and EVP proxy:
|
|
40
|
+
* https://github.com/DataDog/datadog-agent/tree/main/pkg/trace/api
|
|
41
|
+
*
|
|
42
|
+
* serverless-init entry point and embedded trace receiver:
|
|
43
|
+
* https://github.com/DataDog/datadog-agent/blob/main/cmd/serverless-init/main.go
|
|
44
|
+
* https://github.com/DataDog/datadog-agent/blob/main/pkg/serverless/trace/trace.go
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Selects the first advertised EVP proxy path that the caller supports.
|
|
49
|
+
*
|
|
50
|
+
* @param {object} agentInfo - Agent `/info` response
|
|
51
|
+
* @param {object} options - Selection options
|
|
52
|
+
* @param {string[]} options.supportedPaths - Supported paths in preference order
|
|
53
|
+
* @param {string[]} [options.requiredHeaders] - Headers that the proxy must forward unchanged to intake. Each
|
|
54
|
+
* header must appear in `evp_proxy_allowed_headers`. Do not include routing headers that the Agent consumes.
|
|
55
|
+
* @returns {string|undefined} Selected normalized path
|
|
56
|
+
*/
|
|
57
|
+
function selectEVPProxyPath (agentInfo, { supportedPaths, requiredHeaders = [] } = {}) {
|
|
58
|
+
if (!Array.isArray(agentInfo?.endpoints) ||
|
|
59
|
+
!Array.isArray(supportedPaths) ||
|
|
60
|
+
!Array.isArray(requiredHeaders) ||
|
|
61
|
+
requiredHeaders.some(header => typeof header !== 'string')) {
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const allowedHeaders = agentInfo.evp_proxy_allowed_headers
|
|
66
|
+
if (allowedHeaders !== undefined) {
|
|
67
|
+
if (!Array.isArray(allowedHeaders)) return
|
|
68
|
+
|
|
69
|
+
const normalizedHeaders = new Set()
|
|
70
|
+
for (const header of allowedHeaders) {
|
|
71
|
+
if (typeof header === 'string') {
|
|
72
|
+
normalizedHeaders.add(header.toLowerCase())
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (requiredHeaders.some(header => !normalizedHeaders.has(header.toLowerCase()))) {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const advertisedPaths = new Set()
|
|
82
|
+
for (const endpoint of agentInfo.endpoints) {
|
|
83
|
+
if (typeof endpoint === 'string') {
|
|
84
|
+
advertisedPaths.add(endpoint.replace(TRAILING_SLASHES, ''))
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
for (const supportedPath of supportedPaths) {
|
|
89
|
+
if (typeof supportedPath !== 'string') continue
|
|
90
|
+
|
|
91
|
+
const normalizedPath = supportedPath.replace(TRAILING_SLASHES, '')
|
|
92
|
+
if (advertisedPaths.has(normalizedPath)) {
|
|
93
|
+
return normalizedPath
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Discovers an EVP proxy route through the configured Agent URL.
|
|
100
|
+
*
|
|
101
|
+
* This function performs discovery only when the caller invokes it. It stores
|
|
102
|
+
* no state. The Agent information client owns its existing response cache.
|
|
103
|
+
*
|
|
104
|
+
* @param {URL} url - Configured Agent URL
|
|
105
|
+
* @param {object} options - Selection options
|
|
106
|
+
* @param {string[]} options.supportedPaths - Supported paths in preference order
|
|
107
|
+
* @param {string[]} [options.requiredHeaders] - Headers that the proxy must forward unchanged to intake. Each
|
|
108
|
+
* header must appear in `evp_proxy_allowed_headers`. Do not include routing headers that the Agent consumes.
|
|
109
|
+
* @param {(error: Error|null, route?: {url: URL, basePath: string}) => void} callback - Result callback
|
|
110
|
+
* @returns {void}
|
|
111
|
+
*/
|
|
112
|
+
function discoverEVPProxy (url, options, callback) {
|
|
113
|
+
fetchAgentInfo(url, (error, agentInfo) => {
|
|
114
|
+
if (error) {
|
|
115
|
+
callback(error)
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const basePath = selectEVPProxyPath(agentInfo, options)
|
|
120
|
+
if (basePath === undefined) {
|
|
121
|
+
callback(null)
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
log.debug('EVP proxy route %s discovered through the configured local receiver', basePath)
|
|
126
|
+
callback(null, { url, basePath })
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
module.exports = {
|
|
131
|
+
discoverEVPProxy,
|
|
132
|
+
selectEVPProxyPath,
|
|
133
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const LEADING_SLASHES = /^\/+/
|
|
4
|
+
const TRAILING_SLASHES = /\/+$/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Joins a caller-supplied EVP proxy path and product endpoint.
|
|
8
|
+
*
|
|
9
|
+
* This utility does not perform EVP proxy discovery.
|
|
10
|
+
*
|
|
11
|
+
* @param {string} basePath - EVP proxy base path
|
|
12
|
+
* @param {string} endpoint - Product intake endpoint
|
|
13
|
+
* @returns {string} Joined request path
|
|
14
|
+
*/
|
|
15
|
+
function joinEVPProxyPath (basePath, endpoint) {
|
|
16
|
+
const normalizedBasePath = basePath.replace(TRAILING_SLASHES, '')
|
|
17
|
+
const normalizedEndpoint = endpoint.replace(LEADING_SLASHES, '')
|
|
18
|
+
|
|
19
|
+
return `${normalizedBasePath}/${normalizedEndpoint}`
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = { joinEVPProxyPath }
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const { inspect } = require('node:util')
|
|
4
4
|
const { channel } = require('dc-polyfill')
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const commonRequest = require('../common/request')
|
|
7
7
|
const { logIntegrations, logAgentError } = require('../../startup-log')
|
|
8
8
|
const runtimeMetrics = require('../../runtime_metrics')
|
|
9
9
|
const log = require('../../log')
|
|
@@ -15,12 +15,15 @@ const METRIC_PREFIX = 'datadog.tracer.node.exporter.agent'
|
|
|
15
15
|
const firstFlushChannel = channel('dd-trace:exporter:first-flush')
|
|
16
16
|
|
|
17
17
|
class AgentWriter extends BaseWriter {
|
|
18
|
+
#request = commonRequest
|
|
19
|
+
#requestTracker
|
|
20
|
+
|
|
18
21
|
constructor (...args) {
|
|
19
22
|
super({
|
|
20
23
|
...args[0],
|
|
21
24
|
beforeFirstFlush: () => firstFlushChannel.publish(),
|
|
22
25
|
})
|
|
23
|
-
const { prioritySampler, lookup, protocolVersion, headers } = args[0]
|
|
26
|
+
const { prioritySampler, lookup, protocolVersion, headers, isTestOptimization } = args[0]
|
|
24
27
|
const AgentEncoder = getEncoder(protocolVersion)
|
|
25
28
|
|
|
26
29
|
this._prioritySampler = prioritySampler
|
|
@@ -28,13 +31,33 @@ class AgentWriter extends BaseWriter {
|
|
|
28
31
|
this._protocolVersion = protocolVersion
|
|
29
32
|
this._headers = headers
|
|
30
33
|
this._encoder = new AgentEncoder(this)
|
|
34
|
+
if (isTestOptimization) {
|
|
35
|
+
this.#request = require('../../ci-visibility/exporters/request')
|
|
36
|
+
const TestOptimizationRequestTracker = require('../../ci-visibility/exporters/agentless/request-tracker')
|
|
37
|
+
this.#requestTracker = new TestOptimizationRequestTracker(this)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Flushes payloads, including requests already in flight during Test Optimization finalization.
|
|
43
|
+
*
|
|
44
|
+
* @param {(error?: Error) => void} [done]
|
|
45
|
+
* @param {{ deadline?: number }} [options]
|
|
46
|
+
* @returns {void}
|
|
47
|
+
*/
|
|
48
|
+
flush (done, options) {
|
|
49
|
+
if (this.#requestTracker) {
|
|
50
|
+
this.#requestTracker.flush(done, options)
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
super.flush(done, options)
|
|
31
54
|
}
|
|
32
55
|
|
|
33
|
-
_sendPayload (data, count, done) {
|
|
56
|
+
_sendPayload (data, count, done, flushOptions) {
|
|
34
57
|
runtimeMetrics.increment(`${METRIC_PREFIX}.requests`, true)
|
|
35
58
|
|
|
36
59
|
const { _headers, _lookup, _protocolVersion, _url } = this
|
|
37
|
-
|
|
60
|
+
const onResponse = (err, res, status, headers) => {
|
|
38
61
|
if (status) {
|
|
39
62
|
runtimeMetrics.increment(`${METRIC_PREFIX}.responses`, true)
|
|
40
63
|
runtimeMetrics.increment(`${METRIC_PREFIX}.responses.by.status`, `status:${status}`, true)
|
|
@@ -49,7 +72,7 @@ class AgentWriter extends BaseWriter {
|
|
|
49
72
|
|
|
50
73
|
if (err) {
|
|
51
74
|
log.errorWithoutTelemetry('Error sending payload to the agent (status code: %s)', err.status, err)
|
|
52
|
-
done()
|
|
75
|
+
done(flushOptions?.deadline === undefined ? undefined : err)
|
|
53
76
|
return
|
|
54
77
|
}
|
|
55
78
|
|
|
@@ -74,7 +97,19 @@ class AgentWriter extends BaseWriter {
|
|
|
74
97
|
runtimeMetrics.increment(`${METRIC_PREFIX}.errors.by.name`, `name:${e.name}`, true)
|
|
75
98
|
}
|
|
76
99
|
done()
|
|
77
|
-
}
|
|
100
|
+
}
|
|
101
|
+
makeRequest(
|
|
102
|
+
_protocolVersion,
|
|
103
|
+
data,
|
|
104
|
+
count,
|
|
105
|
+
_url,
|
|
106
|
+
_headers,
|
|
107
|
+
_lookup,
|
|
108
|
+
flushOptions,
|
|
109
|
+
this.#request,
|
|
110
|
+
this.#requestTracker,
|
|
111
|
+
onResponse
|
|
112
|
+
)
|
|
78
113
|
}
|
|
79
114
|
}
|
|
80
115
|
|
|
@@ -84,7 +119,7 @@ function getEncoder (protocolVersion) {
|
|
|
84
119
|
: require('../../encode/0.4').AgentEncoder
|
|
85
120
|
}
|
|
86
121
|
|
|
87
|
-
function makeRequest (version, data, count, url, headers, lookup, cb) {
|
|
122
|
+
function makeRequest (version, data, count, url, headers, lookup, flushOptions, request, requestTracker, cb) {
|
|
88
123
|
const options = {
|
|
89
124
|
path: `/v${version}/traces`,
|
|
90
125
|
method: 'PUT',
|
|
@@ -100,16 +135,21 @@ function makeRequest (version, data, count, url, headers, lookup, cb) {
|
|
|
100
135
|
lookup,
|
|
101
136
|
url,
|
|
102
137
|
}
|
|
138
|
+
if (flushOptions?.deadline !== undefined) {
|
|
139
|
+
options.deadline = flushOptions.deadline
|
|
140
|
+
}
|
|
103
141
|
|
|
104
142
|
log.debug('Request to the agent: %j', options)
|
|
105
143
|
|
|
106
|
-
|
|
144
|
+
const onResponse = (err, res, status, headers) => {
|
|
107
145
|
logIntegrations()
|
|
108
146
|
if (status !== 404 && status !== 200 && err) {
|
|
109
147
|
logAgentError({ status, message: err.message ?? inspect(err) })
|
|
110
148
|
}
|
|
111
149
|
cb(err, res, status, headers)
|
|
112
|
-
}
|
|
150
|
+
}
|
|
151
|
+
if (requestTracker) requestTracker.send(request, data, options, onResponse)
|
|
152
|
+
else request(data, options, onResponse)
|
|
113
153
|
}
|
|
114
154
|
|
|
115
155
|
module.exports = AgentWriter
|