dd-trace 5.56.0 → 5.57.1
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/index.d.ts +44 -2
- package/init.js +4 -1
- package/package.json +20 -20
- package/packages/datadog-esbuild/index.js +22 -0
- package/packages/datadog-instrumentations/src/cassandra-driver.js +43 -60
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +12 -12
- package/packages/datadog-instrumentations/src/cucumber.js +4 -6
- package/packages/datadog-instrumentations/src/elasticsearch.js +16 -19
- package/packages/datadog-instrumentations/src/fastify.js +91 -9
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +20 -5
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +2 -2
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +17 -5
- package/packages/datadog-instrumentations/src/ioredis.js +8 -13
- package/packages/datadog-instrumentations/src/iovalkey.js +10 -14
- package/packages/datadog-instrumentations/src/jest.js +28 -6
- package/packages/datadog-instrumentations/src/memcached.js +17 -24
- package/packages/datadog-instrumentations/src/mocha/main.js +7 -6
- package/packages/datadog-instrumentations/src/moleculer/client.js +9 -10
- package/packages/datadog-instrumentations/src/moleculer/server.js +12 -13
- package/packages/datadog-instrumentations/src/openai.js +30 -2
- package/packages/datadog-instrumentations/src/playwright.js +4 -1
- package/packages/datadog-instrumentations/src/prisma.js +116 -0
- package/packages/datadog-instrumentations/src/redis.js +32 -43
- package/packages/datadog-instrumentations/src/router.js +1 -1
- package/packages/datadog-instrumentations/src/sharedb.js +10 -16
- package/packages/datadog-instrumentations/src/vitest.js +4 -4
- package/packages/datadog-plugin-aws-sdk/src/base.js +6 -1
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +9 -4
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +3 -2
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +2 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +2 -2
- package/packages/datadog-plugin-bunyan/src/index.js +2 -2
- package/packages/datadog-plugin-cassandra-driver/src/index.js +6 -2
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/batch-consumer.js +1 -1
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/consumer.js +1 -1
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/index.js +1 -1
- package/packages/datadog-plugin-confluentinc-kafka-javascript/src/producer.js +1 -1
- package/packages/datadog-plugin-cucumber/src/index.js +4 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +9 -5
- package/packages/datadog-plugin-elasticsearch/src/index.js +12 -4
- package/packages/datadog-plugin-http/src/client.js +1 -0
- package/packages/datadog-plugin-http/src/server.js +2 -1
- package/packages/datadog-plugin-http2/src/client.js +1 -0
- package/packages/datadog-plugin-http2/src/server.js +1 -0
- package/packages/datadog-plugin-jest/src/index.js +4 -3
- package/packages/datadog-plugin-memcached/src/index.js +6 -2
- package/packages/datadog-plugin-mocha/src/index.js +3 -2
- package/packages/datadog-plugin-moleculer/src/client.js +15 -9
- package/packages/datadog-plugin-moleculer/src/server.js +9 -5
- package/packages/datadog-plugin-next/src/index.js +2 -1
- package/packages/datadog-plugin-openai/src/tracing.js +127 -80
- package/packages/datadog-plugin-pino/src/index.js +2 -2
- package/packages/datadog-plugin-prisma/src/client.js +62 -0
- package/packages/datadog-plugin-prisma/src/engine.js +81 -0
- package/packages/datadog-plugin-prisma/src/index.js +22 -0
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -1
- package/packages/datadog-plugin-redis/src/index.js +9 -3
- package/packages/datadog-plugin-router/src/index.js +1 -0
- package/packages/datadog-plugin-sharedb/src/index.js +13 -5
- package/packages/datadog-plugin-winston/src/index.js +2 -2
- package/packages/dd-trace/src/appsec/channels.js +26 -21
- package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +13 -20
- package/packages/dd-trace/src/appsec/iast/taint-tracking/source-types.js +0 -1
- package/packages/dd-trace/src/appsec/index.js +16 -1
- package/packages/dd-trace/src/appsec/rasp/utils.js +0 -5
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +3 -3
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -6
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -3
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +3 -3
- package/packages/dd-trace/src/config.js +286 -270
- package/packages/dd-trace/src/constants.js +2 -1
- package/packages/dd-trace/src/crashtracking/crashtracker.js +12 -14
- package/packages/dd-trace/src/datastreams/context.js +1 -1
- package/packages/dd-trace/src/datastreams/processor.js +1 -1
- package/packages/dd-trace/src/datastreams/writer.js +3 -3
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +6 -3
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/index.js +2 -3
- package/packages/dd-trace/src/debugger/devtools_client/state.js +7 -4
- package/packages/dd-trace/src/dogstatsd.js +3 -3
- package/packages/dd-trace/src/exporters/agent/index.js +10 -5
- package/packages/dd-trace/src/exporters/agent/writer.js +1 -1
- package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +2 -2
- package/packages/dd-trace/src/exporters/log/index.js +1 -1
- package/packages/dd-trace/src/exporters/span-stats/writer.js +2 -2
- package/packages/dd-trace/src/guardrails/index.js +3 -1
- package/packages/dd-trace/src/guardrails/telemetry.js +1 -1
- package/packages/dd-trace/src/llmobs/index.js +11 -5
- package/packages/dd-trace/src/llmobs/plugins/base.js +2 -2
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +1 -1
- package/packages/dd-trace/src/llmobs/tagger.js +13 -13
- package/packages/dd-trace/src/llmobs/writers/base.js +2 -2
- package/packages/dd-trace/src/llmobs/writers/spans.js +2 -2
- package/packages/dd-trace/src/opentelemetry/tracer.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +4 -4
- package/packages/dd-trace/src/opentracing/span.js +1 -0
- package/packages/dd-trace/src/plugin_manager.js +3 -3
- package/packages/dd-trace/src/plugins/cache.js +2 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +11 -7
- package/packages/dd-trace/src/plugins/database.js +3 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +5 -1
- package/packages/dd-trace/src/plugins/outbound.js +8 -6
- package/packages/dd-trace/src/plugins/structured_log_plugin.js +9 -0
- package/packages/dd-trace/src/plugins/tracing.js +1 -1
- package/packages/dd-trace/src/plugins/util/ci.js +83 -30
- package/packages/dd-trace/src/plugins/util/git.js +1 -0
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +3 -2
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -0
- package/packages/dd-trace/src/plugins/util/tags.js +4 -1
- package/packages/dd-trace/src/plugins/util/test.js +80 -10
- package/packages/dd-trace/src/plugins/util/web.js +1 -0
- package/packages/dd-trace/src/profiler.js +0 -2
- package/packages/dd-trace/src/profiling/exporter_cli.js +1 -3
- package/packages/dd-trace/src/profiling/ssi-heuristics.js +18 -126
- package/packages/dd-trace/src/proxy.js +12 -27
- package/packages/dd-trace/src/runtime_metrics/index.js +1 -1
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +14 -45
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +2 -2
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +4 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +2 -2
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +4 -0
- package/packages/dd-trace/src/supported-configurations.json +12 -3
- package/packages/dd-trace/src/telemetry/telemetry.js +5 -1
- package/packages/dd-trace/src/tracer.js +11 -0
- package/packages/dd-trace/src/tracer_metadata.js +25 -0
- package/packages/dd-trace/src/util.js +11 -4
- package/version.js +3 -1
- package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +0 -30
|
@@ -9,31 +9,29 @@ const { URL } = require('url')
|
|
|
9
9
|
const pkg = require('../../../../package.json')
|
|
10
10
|
|
|
11
11
|
class Crashtracker {
|
|
12
|
-
|
|
13
|
-
this._started = false
|
|
14
|
-
}
|
|
12
|
+
#started = false
|
|
15
13
|
|
|
16
14
|
configure (config) {
|
|
17
|
-
if (!this
|
|
15
|
+
if (!this.#started) return
|
|
18
16
|
|
|
19
17
|
try {
|
|
20
|
-
binding.updateConfig(this
|
|
21
|
-
binding.updateMetadata(this
|
|
18
|
+
binding.updateConfig(this.#getConfig(config))
|
|
19
|
+
binding.updateMetadata(this.#getMetadata(config))
|
|
22
20
|
} catch (e) {
|
|
23
21
|
log.error('Error configuring crashtracker', e)
|
|
24
22
|
}
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
start (config) {
|
|
28
|
-
if (this
|
|
26
|
+
if (this.#started) return this.configure(config)
|
|
29
27
|
|
|
30
|
-
this
|
|
28
|
+
this.#started = true
|
|
31
29
|
|
|
32
30
|
try {
|
|
33
31
|
binding.init(
|
|
34
|
-
this
|
|
35
|
-
this
|
|
36
|
-
this
|
|
32
|
+
this.#getConfig(config),
|
|
33
|
+
this.#getReceiverConfig(),
|
|
34
|
+
this.#getMetadata(config)
|
|
37
35
|
)
|
|
38
36
|
} catch (e) {
|
|
39
37
|
log.error('Error initialising crashtracker', e)
|
|
@@ -50,7 +48,7 @@ class Crashtracker {
|
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
// TODO: Send only configured values when defaults are fixed.
|
|
53
|
-
|
|
51
|
+
#getConfig (config) {
|
|
54
52
|
const { hostname = '127.0.0.1', port = 8126 } = config
|
|
55
53
|
const url = config.url || new URL(`http://${hostname}:${port}`)
|
|
56
54
|
|
|
@@ -75,7 +73,7 @@ class Crashtracker {
|
|
|
75
73
|
}
|
|
76
74
|
}
|
|
77
75
|
|
|
78
|
-
|
|
76
|
+
#getMetadata (config) {
|
|
79
77
|
const tags = Object.keys(config.tags).map(key => `${key}:${config.tags[key]}`)
|
|
80
78
|
|
|
81
79
|
return {
|
|
@@ -94,7 +92,7 @@ class Crashtracker {
|
|
|
94
92
|
}
|
|
95
93
|
}
|
|
96
94
|
|
|
97
|
-
|
|
95
|
+
#getReceiverConfig () {
|
|
98
96
|
return {
|
|
99
97
|
args: [],
|
|
100
98
|
env: [],
|
|
@@ -7,7 +7,7 @@ function getDataStreamsContext () {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
function setDataStreamsContext (dataStreamsContext) {
|
|
10
|
-
log.debug(
|
|
10
|
+
log.debug('Setting new DSM Context: %j.', dataStreamsContext)
|
|
11
11
|
|
|
12
12
|
if (dataStreamsContext) storage('legacy').enterWith({ ...(storage('legacy').getStore()), dataStreamsContext })
|
|
13
13
|
}
|
|
@@ -204,7 +204,7 @@ class DataStreamsProcessor {
|
|
|
204
204
|
let closestOppositeDirectionHash = ENTRY_PARENT_HASH
|
|
205
205
|
let closestOppositeDirectionEdgeStart = nowNs
|
|
206
206
|
if (ctx == null) {
|
|
207
|
-
log.debug(
|
|
207
|
+
log.debug('Setting DSM Checkpoint with empty parent context.')
|
|
208
208
|
} else {
|
|
209
209
|
pathwayStartNs = ctx.pathwayStartNs
|
|
210
210
|
edgeStartNs = ctx.edgeStartNs
|
|
@@ -20,7 +20,7 @@ function makeRequest (data, url, cb) {
|
|
|
20
20
|
url
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
log.debug(
|
|
23
|
+
log.debug('Request to the intake: %j', options)
|
|
24
24
|
|
|
25
25
|
request(data, options, (err, res) => {
|
|
26
26
|
cb(err, res)
|
|
@@ -39,7 +39,7 @@ class DataStreamsWriter {
|
|
|
39
39
|
|
|
40
40
|
flush (payload) {
|
|
41
41
|
if (!request.writable) {
|
|
42
|
-
log.debug(
|
|
42
|
+
log.debug('Maximum number of active requests reached. Payload discarded: %j', payload)
|
|
43
43
|
return
|
|
44
44
|
}
|
|
45
45
|
const encodedPayload = msgpack.encode(payload)
|
|
@@ -50,7 +50,7 @@ class DataStreamsWriter {
|
|
|
50
50
|
return
|
|
51
51
|
}
|
|
52
52
|
makeRequest(compressedData, this._url, (err, res) => {
|
|
53
|
-
log.debug(
|
|
53
|
+
log.debug('Response from the agent:', res)
|
|
54
54
|
if (err) {
|
|
55
55
|
log.error('Error sending datastream', err)
|
|
56
56
|
}
|
|
@@ -87,7 +87,10 @@ async function addBreakpoint (probe) {
|
|
|
87
87
|
try {
|
|
88
88
|
probe.condition = probe.when?.json && compileCondition(probe.when.json)
|
|
89
89
|
} catch (err) {
|
|
90
|
-
throw new Error(
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Cannot compile expression: ${probe.when.dsl} (probe: ${probe.id}, version: ${probe.version})`,
|
|
92
|
+
{ cause: err }
|
|
93
|
+
)
|
|
91
94
|
}
|
|
92
95
|
|
|
93
96
|
const locationKey = generateLocationKey(scriptId, lineNumber, columnNumber)
|
|
@@ -115,7 +118,7 @@ async function addBreakpoint (probe) {
|
|
|
115
118
|
condition: probe.condition
|
|
116
119
|
})
|
|
117
120
|
} catch (err) {
|
|
118
|
-
throw new Error(`Error setting breakpoint for probe ${probe.id}`, { cause: err })
|
|
121
|
+
throw new Error(`Error setting breakpoint for probe ${probe.id} (version: ${probe.version})`, { cause: err })
|
|
119
122
|
}
|
|
120
123
|
probeToLocation.set(probe.id, locationKey)
|
|
121
124
|
locationToBreakpoint.set(locationKey, { id: result.breakpointId, location, locationKey })
|
|
@@ -192,7 +195,7 @@ async function updateBreakpointInternal (breakpoint, probe) {
|
|
|
192
195
|
condition
|
|
193
196
|
})
|
|
194
197
|
} catch (err) {
|
|
195
|
-
throw new Error(`Error setting breakpoint for probe ${probe.id}`, { cause: err })
|
|
198
|
+
throw new Error(`Error setting breakpoint for probe ${probe.id} (version: ${probe.version})`, { cause: err })
|
|
196
199
|
}
|
|
197
200
|
breakpointToProbes.set(result.breakpointId, probesAtLocation)
|
|
198
201
|
}
|
|
@@ -278,7 +278,7 @@ function guardAgainstCoercionSideEffects (variable) {
|
|
|
278
278
|
|
|
279
279
|
function assertString (variable) {
|
|
280
280
|
return `((val) => {
|
|
281
|
-
if (
|
|
281
|
+
if (${isString('val')}) {
|
|
282
282
|
return val
|
|
283
283
|
} else {
|
|
284
284
|
throw new TypeError('Variable is not a string')
|
|
@@ -160,10 +160,9 @@ session.on('Debugger.paused', async ({ params }) => {
|
|
|
160
160
|
await session.post('Debugger.resume')
|
|
161
161
|
const diff = process.hrtime.bigint() - start // TODO: Recored as telemetry (DEBUG-2858)
|
|
162
162
|
|
|
163
|
-
log.debug(
|
|
164
|
-
'[debugger:devtools_client] Finished processing breakpoints - main thread paused for: %d ms',
|
|
163
|
+
log.debug(() => `[debugger:devtools_client] Finished processing breakpoints - main thread paused for: ${
|
|
165
164
|
Number(diff) / 1_000_000
|
|
166
|
-
)
|
|
165
|
+
} ms`)
|
|
167
166
|
|
|
168
167
|
const logger = {
|
|
169
168
|
// We can safely use `location.file` from the first probe in the array, since all probes hit by `hitBreakpoints`
|
|
@@ -165,9 +165,12 @@ session.on('Debugger.scriptParsed', ({ params }) => {
|
|
|
165
165
|
loadedScripts.push(params)
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
168
|
+
if (reEvaluateProbesTimer === null) {
|
|
169
|
+
reEvaluateProbesTimer = setTimeout(() => {
|
|
170
|
+
session.emit('scriptLoadingStabilized')
|
|
171
|
+
}, 500).unref()
|
|
172
|
+
} else {
|
|
173
|
+
reEvaluateProbesTimer.refresh()
|
|
174
|
+
}
|
|
172
175
|
}
|
|
173
176
|
})
|
|
@@ -63,7 +63,7 @@ class DogStatsDClient {
|
|
|
63
63
|
flush () {
|
|
64
64
|
const queue = this._enqueue()
|
|
65
65
|
|
|
66
|
-
log.debug(
|
|
66
|
+
log.debug('Flushing %s metrics via', queue.length, this._httpOptions ? 'HTTP' : 'UDP')
|
|
67
67
|
|
|
68
68
|
if (this._queue.length === 0) return
|
|
69
69
|
|
|
@@ -108,7 +108,7 @@ class DogStatsDClient {
|
|
|
108
108
|
const socket = family === 6 ? this._udp6 : this._udp4
|
|
109
109
|
|
|
110
110
|
queue.forEach((buffer) => {
|
|
111
|
-
log.debug(
|
|
111
|
+
log.debug('Sending to DogStatsD: %s', buffer)
|
|
112
112
|
socket.send(buffer, 0, buffer.length, this._port, address)
|
|
113
113
|
})
|
|
114
114
|
}
|
|
@@ -165,7 +165,7 @@ class DogStatsDClient {
|
|
|
165
165
|
.filter(key => {
|
|
166
166
|
// Skip runtime-id unless enabled as cardinality may be too high
|
|
167
167
|
if (key !== 'runtime-id') return true
|
|
168
|
-
return
|
|
168
|
+
return config.runtimeMetricsRuntimeId
|
|
169
169
|
})
|
|
170
170
|
.forEach(key => {
|
|
171
171
|
// https://docs.datadoghq.com/tagging/#defining-tags
|
|
@@ -5,6 +5,8 @@ const log = require('../../log')
|
|
|
5
5
|
const Writer = require('./writer')
|
|
6
6
|
|
|
7
7
|
class AgentExporter {
|
|
8
|
+
#timer
|
|
9
|
+
|
|
8
10
|
constructor (config, prioritySampler) {
|
|
9
11
|
this._config = config
|
|
10
12
|
const { url, hostname, port, lookup, protocolVersion, stats = {}, apmTracingEnabled } = config
|
|
@@ -28,8 +30,9 @@ class AgentExporter {
|
|
|
28
30
|
config
|
|
29
31
|
})
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
process.once('beforeExit', () => {
|
|
34
|
+
this.flush()
|
|
35
|
+
})
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
setUrl (url) {
|
|
@@ -49,15 +52,17 @@ class AgentExporter {
|
|
|
49
52
|
|
|
50
53
|
if (flushInterval === 0) {
|
|
51
54
|
this._writer.flush()
|
|
52
|
-
} else if (
|
|
53
|
-
this
|
|
55
|
+
} else if (this.#timer === undefined) {
|
|
56
|
+
this.#timer = setTimeout(() => {
|
|
54
57
|
this._writer.flush()
|
|
55
|
-
this
|
|
58
|
+
this.#timer = undefined
|
|
56
59
|
}, flushInterval).unref()
|
|
57
60
|
}
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
flush (done = () => {}) {
|
|
64
|
+
clearTimeout(this.#timer)
|
|
65
|
+
this.#timer = undefined
|
|
61
66
|
this._writer.flush(done)
|
|
62
67
|
}
|
|
63
68
|
}
|
|
@@ -92,7 +92,7 @@ function makeRequest (version, data, count, url, headers, lookup, needsStartupLo
|
|
|
92
92
|
setHeader(options.headers, 'Datadog-Meta-Lang-Version', process.version)
|
|
93
93
|
setHeader(options.headers, 'Datadog-Meta-Lang-Interpreter', process.jsEngine || 'v8')
|
|
94
94
|
|
|
95
|
-
log.debug(
|
|
95
|
+
log.debug('Request to the agent: %j', options)
|
|
96
96
|
|
|
97
97
|
request(data, options, (err, res, status) => {
|
|
98
98
|
if (needsStartupLog) {
|
|
@@ -59,10 +59,10 @@ class AgentInfoExporter {
|
|
|
59
59
|
|
|
60
60
|
if (flushInterval === 0) {
|
|
61
61
|
writer.flush()
|
|
62
|
-
} else if (
|
|
62
|
+
} else if (this[timerKey] === undefined) {
|
|
63
63
|
this[timerKey] = setTimeout(() => {
|
|
64
64
|
writer.flush()
|
|
65
|
-
this[timerKey] =
|
|
65
|
+
this[timerKey] = undefined
|
|
66
66
|
}, flushInterval).unref()
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -20,7 +20,7 @@ class Writer extends BaseWriter {
|
|
|
20
20
|
done()
|
|
21
21
|
return
|
|
22
22
|
}
|
|
23
|
-
log.debug(
|
|
23
|
+
log.debug('Response from the intake:', res)
|
|
24
24
|
done()
|
|
25
25
|
})
|
|
26
26
|
}
|
|
@@ -41,7 +41,7 @@ function makeRequest (data, url, cb) {
|
|
|
41
41
|
options.hostname = url.hostname
|
|
42
42
|
options.port = url.port
|
|
43
43
|
|
|
44
|
-
log.debug(
|
|
44
|
+
log.debug('Request to the intake: %j', options)
|
|
45
45
|
|
|
46
46
|
request(data, options, (err, res) => {
|
|
47
47
|
cb(err, res)
|
|
@@ -47,13 +47,15 @@ function guard (fn) {
|
|
|
47
47
|
{ name: 'abort.runtime', tags: [] }
|
|
48
48
|
])
|
|
49
49
|
log.info('Aborting application instrumentation due to incompatible_runtime.')
|
|
50
|
-
log.info('Found incompatible runtime nodejs
|
|
50
|
+
log.info('Found incompatible runtime nodejs %s, Supported runtimes: nodejs %s.', version, engines.node)
|
|
51
51
|
if (forced) {
|
|
52
52
|
log.info('DD_INJECT_FORCE enabled, allowing unsupported runtimes and continuing.')
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
if (!clobberBailout && (!initBailout || forced)) {
|
|
57
|
+
// Ensure the instrumentation source is set for the current process and potential
|
|
58
|
+
// child processes.
|
|
57
59
|
var result = fn()
|
|
58
60
|
telemetry('complete', ['injection_forced:' + (forced && initBailout ? 'true' : 'false')])
|
|
59
61
|
log.info('Application instrumentation bootstrapping complete')
|
|
@@ -65,7 +65,7 @@ function sendTelemetry (name, tags) {
|
|
|
65
65
|
})
|
|
66
66
|
proc.on('exit', function (code) {
|
|
67
67
|
if (code !== 0) {
|
|
68
|
-
log.error('Telemetry forwarder exited with code
|
|
68
|
+
log.error('Telemetry forwarder exited with code', code)
|
|
69
69
|
}
|
|
70
70
|
})
|
|
71
71
|
proc.stdin.on('error', function () {
|
|
@@ -22,6 +22,8 @@ const LLMObsTagger = require('./tagger')
|
|
|
22
22
|
const LLMObsSpanWriter = require('./writers/spans')
|
|
23
23
|
const { setAgentStrategy } = require('./writers/util')
|
|
24
24
|
|
|
25
|
+
const util = require('node:util')
|
|
26
|
+
|
|
25
27
|
/**
|
|
26
28
|
* Setting writers and processor globally when LLMObs is enabled
|
|
27
29
|
* We're setting these in this module instead of on the SDK.
|
|
@@ -75,6 +77,7 @@ function enable (config) {
|
|
|
75
77
|
spanWriter?.setAgentless(useAgentless)
|
|
76
78
|
|
|
77
79
|
telemetry.recordLLMObsEnabled(startTime, config)
|
|
80
|
+
log.debug(`[LLMObs] Enabled LLM Observability with configuration: ${util.inspect(config.llmobs)}`)
|
|
78
81
|
})
|
|
79
82
|
}
|
|
80
83
|
|
|
@@ -90,6 +93,8 @@ function disable () {
|
|
|
90
93
|
|
|
91
94
|
spanWriter = null
|
|
92
95
|
evalWriter = null
|
|
96
|
+
|
|
97
|
+
log.debug('[LLMObs] Disabled LLM Observability')
|
|
93
98
|
}
|
|
94
99
|
|
|
95
100
|
// since LLMObs traces can extend between services and be the same trace,
|
|
@@ -116,7 +121,7 @@ function handleFlush () {
|
|
|
116
121
|
evalWriter.flush()
|
|
117
122
|
} catch (e) {
|
|
118
123
|
err = 'writer_flush_error'
|
|
119
|
-
log.warn(
|
|
124
|
+
log.warn('Failed to flush LLMObs spans and evaluation metrics:', e.message)
|
|
120
125
|
}
|
|
121
126
|
telemetry.recordUserFlush(err)
|
|
122
127
|
}
|
|
@@ -129,10 +134,11 @@ function handleEvalMetricAppend (payload) {
|
|
|
129
134
|
try {
|
|
130
135
|
evalWriter.append(payload)
|
|
131
136
|
} catch (e) {
|
|
132
|
-
log.warn(
|
|
133
|
-
|
|
134
|
-
Evaluation metrics won't be sent to LLM Observability:
|
|
135
|
-
|
|
137
|
+
log.warn(
|
|
138
|
+
// eslint-disable-next-line @stylistic/max-len
|
|
139
|
+
'Failed to append evaluation metric to LLM Observability writer, likely due to an unserializable property. Evaluation metrics won\'t be sent to LLM Observability:',
|
|
140
|
+
e.message
|
|
141
|
+
)
|
|
136
142
|
}
|
|
137
143
|
}
|
|
138
144
|
|
|
@@ -70,8 +70,8 @@ class LLMObsPlugin extends TracingPlugin {
|
|
|
70
70
|
const span = apmStore?.span
|
|
71
71
|
if (!span) {
|
|
72
72
|
log.debug(
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
'Tried to start an LLMObs span for %s without an active APM span. Not starting LLMObs span.',
|
|
74
|
+
this.constructor.name
|
|
75
75
|
)
|
|
76
76
|
return
|
|
77
77
|
}
|
|
@@ -63,7 +63,7 @@ class BaseLangChainLLMObsPlugin extends LLMObsPlugin {
|
|
|
63
63
|
const type = ctx.type = this.constructor.lcType // langchain operation type (oneof chain,chat_model,llm,embedding)
|
|
64
64
|
|
|
65
65
|
if (!Object.keys(this._handlers).includes(type)) {
|
|
66
|
-
log.warn(
|
|
66
|
+
log.warn('Unsupported LangChain operation type:', type)
|
|
67
67
|
return
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -61,19 +61,6 @@ class LLMObsTagger {
|
|
|
61
61
|
if (!this._config.llmobs.enabled) return
|
|
62
62
|
if (!kind) return // do not register it in the map if it doesn't have an llmobs span kind
|
|
63
63
|
|
|
64
|
-
this._register(span)
|
|
65
|
-
|
|
66
|
-
if (name) this._setTag(span, NAME, name)
|
|
67
|
-
|
|
68
|
-
this._setTag(span, SPAN_KIND, kind)
|
|
69
|
-
if (modelName) this._setTag(span, MODEL_NAME, modelName)
|
|
70
|
-
if (modelProvider) this._setTag(span, MODEL_PROVIDER, modelProvider)
|
|
71
|
-
|
|
72
|
-
sessionId = sessionId || registry.get(parent)?.[SESSION_ID]
|
|
73
|
-
if (sessionId) this._setTag(span, SESSION_ID, sessionId)
|
|
74
|
-
if (integration) this._setTag(span, INTEGRATION, integration)
|
|
75
|
-
if (_decorator) this._setTag(span, DECORATOR, _decorator)
|
|
76
|
-
|
|
77
64
|
const spanMlApp =
|
|
78
65
|
mlApp ||
|
|
79
66
|
registry.get(parent)?.[ML_APP] ||
|
|
@@ -87,8 +74,21 @@ class LLMObsTagger {
|
|
|
87
74
|
)
|
|
88
75
|
}
|
|
89
76
|
|
|
77
|
+
this._register(span)
|
|
78
|
+
|
|
90
79
|
this._setTag(span, ML_APP, spanMlApp)
|
|
91
80
|
|
|
81
|
+
if (name) this._setTag(span, NAME, name)
|
|
82
|
+
|
|
83
|
+
this._setTag(span, SPAN_KIND, kind)
|
|
84
|
+
if (modelName) this._setTag(span, MODEL_NAME, modelName)
|
|
85
|
+
if (modelProvider) this._setTag(span, MODEL_PROVIDER, modelProvider)
|
|
86
|
+
|
|
87
|
+
sessionId = sessionId || registry.get(parent)?.[SESSION_ID]
|
|
88
|
+
if (sessionId) this._setTag(span, SESSION_ID, sessionId)
|
|
89
|
+
if (integration) this._setTag(span, INTEGRATION, integration)
|
|
90
|
+
if (_decorator) this._setTag(span, DECORATOR, _decorator)
|
|
91
|
+
|
|
92
92
|
const parentId =
|
|
93
93
|
parent?.context().toSpanId() ??
|
|
94
94
|
span.context()._trace.tags[PROPAGATED_PARENT_ID_KEY] ??
|
|
@@ -60,7 +60,7 @@ class BaseLLMObsWriter {
|
|
|
60
60
|
return
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
this._bufferSize += byteLength || Buffer.
|
|
63
|
+
this._bufferSize += byteLength || Buffer.byteLength(JSON.stringify(event))
|
|
64
64
|
this._buffer.push(event)
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -76,7 +76,7 @@ class BaseLLMObsWriter {
|
|
|
76
76
|
this._bufferSize = 0
|
|
77
77
|
const payload = this._encode(this.makePayload(events))
|
|
78
78
|
|
|
79
|
-
log.debug(
|
|
79
|
+
log.debug('Encoded LLMObs payload: %s', payload)
|
|
80
80
|
|
|
81
81
|
const options = this._getOptions()
|
|
82
82
|
|
|
@@ -26,7 +26,7 @@ class LLMObsSpanWriter extends BaseWriter {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
append (event) {
|
|
29
|
-
const eventSizeBytes = Buffer.
|
|
29
|
+
const eventSizeBytes = Buffer.byteLength(JSON.stringify(event))
|
|
30
30
|
telemetry.recordLLMObsRawSpanSize(event, eventSizeBytes)
|
|
31
31
|
|
|
32
32
|
const shouldTruncate = eventSizeBytes > EVP_EVENT_SIZE_LIMIT
|
|
@@ -35,7 +35,7 @@ class LLMObsSpanWriter extends BaseWriter {
|
|
|
35
35
|
if (shouldTruncate) {
|
|
36
36
|
logger.warn(`Dropping event input/output because its size (${eventSizeBytes}) exceeds the 1MB event size limit`)
|
|
37
37
|
event = this._truncateSpanEvent(event)
|
|
38
|
-
processedEventSizeBytes = Buffer.
|
|
38
|
+
processedEventSizeBytes = Buffer.byteLength(JSON.stringify(event))
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
telemetry.recordLLMObsSpanSize(event, processedEventSizeBytes, shouldTruncate)
|
|
@@ -141,7 +141,7 @@ class TextMapPropagator {
|
|
|
141
141
|
for (const [key, value] of Object.entries(baggageItems)) {
|
|
142
142
|
const item = `${this._encodeOtelBaggageKey(String(key).trim())}=${encodeURIComponent(String(value).trim())},`
|
|
143
143
|
itemCounter += 1
|
|
144
|
-
byteCounter += item
|
|
144
|
+
byteCounter += Buffer.byteLength(item)
|
|
145
145
|
if (itemCounter > this._config.baggageMaxItems || byteCounter > this._config.baggageMaxBytes) break
|
|
146
146
|
baggage += item
|
|
147
147
|
}
|
|
@@ -325,7 +325,7 @@ class TextMapPropagator {
|
|
|
325
325
|
extractedContext = this._extractB3MultiContext(carrier)
|
|
326
326
|
break
|
|
327
327
|
default:
|
|
328
|
-
if (extractor !== 'baggage') log.warn(
|
|
328
|
+
if (extractor !== 'baggage') log.warn('Unknown propagation style:', extractor)
|
|
329
329
|
}
|
|
330
330
|
|
|
331
331
|
if (extractedContext === null) { // If the current extractor was invalid, continue to the next extractor
|
|
@@ -514,7 +514,7 @@ class TextMapPropagator {
|
|
|
514
514
|
// If subkey is tid then do nothing because trace header tid should always be preserved
|
|
515
515
|
if (subKey === 'tid') {
|
|
516
516
|
if (!hex16.test(value) || spanContext._trace.tags['_dd.p.tid'] !== transformedValue) {
|
|
517
|
-
log.error(
|
|
517
|
+
log.error('Invalid trace id %s in tracestate, skipping', value)
|
|
518
518
|
}
|
|
519
519
|
continue
|
|
520
520
|
}
|
|
@@ -683,7 +683,7 @@ class TextMapPropagator {
|
|
|
683
683
|
}
|
|
684
684
|
// Check if value is a valid 16 character lower-case hexadecimal encoded number as per spec
|
|
685
685
|
if (key === '_dd.p.tid' && !(hex16.test(value))) {
|
|
686
|
-
log.error(
|
|
686
|
+
log.error('Invalid _dd.p.tid tag %s, skipping', value)
|
|
687
687
|
continue
|
|
688
688
|
}
|
|
689
689
|
tags[key] = value
|
|
@@ -240,6 +240,7 @@ class DatadogSpan {
|
|
|
240
240
|
}
|
|
241
241
|
|
|
242
242
|
getIntegrationCounter('spans_finished', this._integrationName).inc()
|
|
243
|
+
this._spanContext._tags['_dd.integration'] = this._integrationName
|
|
243
244
|
|
|
244
245
|
if (DD_TRACE_EXPERIMENTAL_SPAN_COUNTS && finishedRegistry) {
|
|
245
246
|
runtimeMetrics.decrement('runtime.node.spans.unfinished')
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { channel } = require('dc-polyfill')
|
|
4
|
-
const { isFalse } = require('./util')
|
|
4
|
+
const { isFalse, normalizePluginEnvName } = require('./util')
|
|
5
5
|
const plugins = require('./plugins')
|
|
6
6
|
const log = require('./log')
|
|
7
7
|
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
@@ -33,11 +33,11 @@ function maybeEnable (Plugin) {
|
|
|
33
33
|
if (!Plugin || typeof Plugin !== 'function') return
|
|
34
34
|
if (!pluginClasses[Plugin.id]) {
|
|
35
35
|
const envName = `DD_TRACE_${Plugin.id.toUpperCase()}_ENABLED`
|
|
36
|
-
const enabled = getEnvironmentVariable(envName
|
|
36
|
+
const enabled = getEnvironmentVariable(normalizePluginEnvName(envName))
|
|
37
37
|
|
|
38
38
|
// TODO: remove the need to load the plugin class in order to disable the plugin
|
|
39
39
|
if (isFalse(enabled) || disabledPlugins.has(Plugin.id)) {
|
|
40
|
-
log.debug(
|
|
40
|
+
log.debug('Plugin "%s" was disabled via configuration option.', Plugin.id)
|
|
41
41
|
|
|
42
42
|
pluginClasses[Plugin.id] = null
|
|
43
43
|
} else {
|
|
@@ -5,11 +5,11 @@ const StoragePlugin = require('./storage')
|
|
|
5
5
|
class CachePlugin extends StoragePlugin {
|
|
6
6
|
static get operation () { return 'command' }
|
|
7
7
|
|
|
8
|
-
startSpan (options) {
|
|
8
|
+
startSpan (options, ctx) {
|
|
9
9
|
if (!options.kind) {
|
|
10
10
|
options.kind = this.constructor.kind
|
|
11
11
|
}
|
|
12
|
-
return super.startSpan(this.operationName(), options)
|
|
12
|
+
return super.startSpan(this.operationName(), options, ctx)
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|