dd-trace 5.54.0 → 5.56.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 +1 -0
- package/ci/cypress/plugin.js +8 -0
- package/ci/cypress/polyfills.js +23 -0
- package/ci/init.js +8 -7
- package/initialize.mjs +2 -2
- package/package.json +10 -9
- package/packages/datadog-code-origin/index.js +22 -4
- package/packages/datadog-core/src/utils/src/kebabcase.js +3 -3
- package/packages/datadog-core/src/utils/src/set.js +8 -10
- package/packages/datadog-instrumentations/src/cassandra-driver.js +5 -6
- package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +2 -3
- package/packages/datadog-instrumentations/src/cookie-parser.js +1 -1
- package/packages/datadog-instrumentations/src/couchbase.js +3 -6
- package/packages/datadog-instrumentations/src/cucumber.js +21 -28
- package/packages/datadog-instrumentations/src/dns.js +4 -4
- package/packages/datadog-instrumentations/src/elasticsearch.js +9 -10
- package/packages/datadog-instrumentations/src/fastify.js +7 -9
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +14 -16
- package/packages/datadog-instrumentations/src/hapi.js +10 -11
- package/packages/datadog-instrumentations/src/helpers/fetch.js +4 -5
- package/packages/datadog-instrumentations/src/helpers/hook.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/register.js +6 -5
- package/packages/datadog-instrumentations/src/jest.js +421 -376
- package/packages/datadog-instrumentations/src/koa.js +2 -3
- package/packages/datadog-instrumentations/src/mariadb.js +11 -4
- package/packages/datadog-instrumentations/src/mocha/main.js +79 -75
- package/packages/datadog-instrumentations/src/mocha.js +3 -1
- package/packages/datadog-instrumentations/src/mysql.js +11 -2
- package/packages/datadog-instrumentations/src/nyc.js +2 -1
- package/packages/datadog-instrumentations/src/openai.js +2 -2
- package/packages/datadog-instrumentations/src/otel-sdk-trace.js +4 -3
- package/packages/datadog-instrumentations/src/pg.js +2 -3
- package/packages/datadog-instrumentations/src/playwright.js +19 -22
- package/packages/datadog-instrumentations/src/protobufjs.js +3 -4
- package/packages/datadog-instrumentations/src/redis.js +1 -1
- package/packages/datadog-instrumentations/src/restify.js +9 -13
- package/packages/datadog-instrumentations/src/router.js +12 -11
- package/packages/datadog-instrumentations/src/tedious.js +1 -2
- package/packages/datadog-instrumentations/src/vitest.js +15 -29
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +12 -12
- package/packages/datadog-plugin-aws-sdk/src/base.js +12 -8
- package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +12 -20
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -5
- package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +3 -5
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -2
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +7 -10
- package/packages/datadog-plugin-azure-functions/src/index.js +5 -4
- package/packages/datadog-plugin-cucumber/src/index.js +3 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +2 -1
- package/packages/datadog-plugin-dd-trace-api/src/index.js +2 -1
- package/packages/datadog-plugin-elasticsearch/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +1 -1
- package/packages/datadog-plugin-graphql/src/index.js +3 -2
- package/packages/datadog-plugin-graphql/src/resolve.js +17 -10
- package/packages/datadog-plugin-http/src/client.js +5 -6
- package/packages/datadog-plugin-http2/src/client.js +7 -8
- package/packages/datadog-plugin-jest/src/index.js +3 -2
- package/packages/datadog-plugin-mocha/src/index.js +6 -1
- package/packages/datadog-plugin-mongodb-core/src/index.js +2 -1
- package/packages/datadog-plugin-mysql/src/index.js +11 -0
- package/packages/datadog-plugin-next/src/index.js +1 -1
- package/packages/datadog-plugin-openai/src/tracing.js +2 -4
- package/packages/datadog-plugin-oracledb/src/index.js +2 -1
- package/packages/datadog-plugin-playwright/src/index.js +3 -2
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +8 -9
- package/packages/datadog-plugin-redis/src/index.js +1 -3
- package/packages/datadog-plugin-vitest/src/index.js +5 -4
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-rules.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secret-rules.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-secrets-rules.js +0 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +1 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/security-controls/index.js +12 -13
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +44 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +2 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +8 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +1 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/verbosity.js +1 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/range-utils.js +10 -11
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +0 -4
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +0 -1
- package/packages/dd-trace/src/appsec/index.js +16 -5
- package/packages/dd-trace/src/appsec/reporter.js +11 -11
- package/packages/dd-trace/src/appsec/sdk/set_user.js +2 -2
- package/packages/dd-trace/src/appsec/sdk/track_event.js +3 -3
- package/packages/dd-trace/src/appsec/telemetry/index.js +31 -1
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +6 -2
- package/packages/dd-trace/src/azure_metadata.js +8 -3
- package/packages/dd-trace/src/baggage.js +2 -2
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +8 -7
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -1
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +4 -3
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +7 -6
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -1
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -3
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +4 -3
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -1
- package/packages/dd-trace/src/config-helper.js +89 -0
- package/packages/dd-trace/src/config.js +120 -115
- package/packages/dd-trace/src/config_stable.js +7 -4
- package/packages/dd-trace/src/datastreams/fnv.js +1 -1
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +6 -6
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +1 -2
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -2
- package/packages/dd-trace/src/debugger/devtools_client/index.js +2 -1
- package/packages/dd-trace/src/debugger/devtools_client/send.js +8 -3
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +1 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +3 -4
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/status.js +5 -1
- package/packages/dd-trace/src/debugger/index.js +1 -0
- package/packages/dd-trace/src/dogstatsd.js +2 -2
- package/packages/dd-trace/src/encode/0.4.js +5 -2
- package/packages/dd-trace/src/encode/0.5.js +3 -5
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +5 -5
- package/packages/dd-trace/src/exporter.js +2 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +3 -1
- package/packages/dd-trace/src/exporters/common/docker.js +3 -2
- package/packages/dd-trace/src/exporters/common/request.js +4 -1
- package/packages/dd-trace/src/exporters/common/util.js +3 -1
- package/packages/dd-trace/src/id.js +3 -3
- package/packages/dd-trace/src/index.js +4 -3
- package/packages/dd-trace/src/lambda/handler.js +2 -1
- package/packages/dd-trace/src/lambda/index.js +2 -1
- package/packages/dd-trace/src/lambda/runtime/patch.js +3 -2
- package/packages/dd-trace/src/lambda/runtime/ritm.js +3 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
- package/packages/dd-trace/src/llmobs/index.js +21 -5
- package/packages/dd-trace/src/llmobs/noop.js +18 -20
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +11 -13
- package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -2
- package/packages/dd-trace/src/llmobs/sdk.js +2 -1
- package/packages/dd-trace/src/llmobs/span_processor.js +1 -1
- package/packages/dd-trace/src/llmobs/tagger.js +19 -6
- package/packages/dd-trace/src/llmobs/writers/base.js +1 -1
- package/packages/dd-trace/src/log/index.js +5 -4
- package/packages/dd-trace/src/log/writer.js +1 -2
- package/packages/dd-trace/src/msgpack/encoder.js +3 -3
- package/packages/dd-trace/src/noop/span.js +1 -1
- package/packages/dd-trace/src/opentelemetry/tracer.js +1 -1
- package/packages/dd-trace/src/opentracing/propagation/log.js +4 -5
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +35 -42
- package/packages/dd-trace/src/opentracing/span.js +7 -6
- package/packages/dd-trace/src/payload-tagging/config/index.js +17 -21
- package/packages/dd-trace/src/plugin_manager.js +4 -3
- package/packages/dd-trace/src/plugins/ci_plugin.js +25 -1
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/util/ci.js +7 -7
- package/packages/dd-trace/src/plugins/util/git.js +1 -1
- package/packages/dd-trace/src/plugins/util/llm.js +2 -2
- package/packages/dd-trace/src/plugins/util/stacktrace.js +8 -1
- package/packages/dd-trace/src/plugins/util/test.js +4 -3
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +2 -1
- package/packages/dd-trace/src/plugins/util/web.js +3 -4
- package/packages/dd-trace/src/priority_sampler.js +46 -35
- package/packages/dd-trace/src/profiling/config.js +12 -32
- package/packages/dd-trace/src/profiling/exporter_cli.js +20 -20
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +2 -1
- package/packages/dd-trace/src/profiling/index.js +2 -1
- package/packages/dd-trace/src/profiling/profiler.js +7 -4
- package/packages/dd-trace/src/profiling/profilers/events.js +10 -2
- package/packages/dd-trace/src/profiling/ssi-telemetry-mock-profiler.js +3 -1
- package/packages/dd-trace/src/profiling/tagger.js +22 -12
- package/packages/dd-trace/src/proxy.js +2 -1
- package/packages/dd-trace/src/ritm.js +4 -4
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +3 -2
- package/packages/dd-trace/src/sampler.js +10 -2
- package/packages/dd-trace/src/serverless.js +11 -4
- package/packages/dd-trace/src/span_processor.js +2 -1
- package/packages/dd-trace/src/standalone/tracesource.js +1 -2
- package/packages/dd-trace/src/standalone/tracesource_priority_sampler.js +1 -2
- package/packages/dd-trace/src/startup-log.js +5 -17
- package/packages/dd-trace/src/supported-configurations.json +440 -0
- package/packages/dd-trace/src/telemetry/dependencies.js +62 -57
- package/packages/dd-trace/src/telemetry/send-data.js +7 -6
- package/packages/dd-trace/src/telemetry/telemetry.js +16 -26
- package/packages/dd-trace/src/tracer.js +3 -7
- package/packages/dd-trace/src/util.js +0 -5
- package/packages/datadog-core/src/utils/src/get.js +0 -11
- package/packages/datadog-core/src/utils/src/has.js +0 -14
- package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +0 -120
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/header-sensitive-analyzer.js +0 -20
|
@@ -170,7 +170,7 @@ async function updateBreakpointInternal (breakpoint, probe) {
|
|
|
170
170
|
const conditionBeforeNewProbe = compileCompoundCondition([...probesAtLocation.values()])
|
|
171
171
|
|
|
172
172
|
// If a probe is provided, add it to the breakpoint. If not, it's because we're removing a probe, but potentially
|
|
173
|
-
// need to update the
|
|
173
|
+
// need to update the condition of the breakpoint.
|
|
174
174
|
if (probe) {
|
|
175
175
|
probesAtLocation.set(probe.id, probe)
|
|
176
176
|
probeToLocation.set(probe.id, breakpoint.locationKey)
|
|
@@ -194,7 +194,6 @@ async function updateBreakpointInternal (breakpoint, probe) {
|
|
|
194
194
|
} catch (err) {
|
|
195
195
|
throw new Error(`Error setting breakpoint for probe ${probe.id}`, { cause: err })
|
|
196
196
|
}
|
|
197
|
-
breakpoint.id = result.breakpointId
|
|
198
197
|
breakpointToProbes.set(result.breakpointId, probesAtLocation)
|
|
199
198
|
}
|
|
200
199
|
}
|
|
@@ -105,9 +105,8 @@ function compile (node) {
|
|
|
105
105
|
return '$dd_key'
|
|
106
106
|
} else if (value === '@value') {
|
|
107
107
|
return '$dd_value'
|
|
108
|
-
} else {
|
|
109
|
-
return assertIdentifier(value)
|
|
110
108
|
}
|
|
109
|
+
return assertIdentifier(value)
|
|
111
110
|
} else if (Array.isArray(value)) {
|
|
112
111
|
const args = value.map(compile)
|
|
113
112
|
switch (type) {
|
|
@@ -109,6 +109,7 @@ session.on('Debugger.paused', async ({ params }) => {
|
|
|
109
109
|
if (probe.condition !== undefined) {
|
|
110
110
|
// TODO: Bundle all conditions and evaluate them in a single call
|
|
111
111
|
// TODO: Handle errors
|
|
112
|
+
// eslint-disable-next-line no-await-in-loop
|
|
112
113
|
const { result } = await session.post('Debugger.evaluateOnCallFrame', {
|
|
113
114
|
callFrameId: params.callFrames[0].callFrameId,
|
|
114
115
|
expression: probe.condition,
|
|
@@ -134,7 +135,7 @@ session.on('Debugger.paused', async ({ params }) => {
|
|
|
134
135
|
|
|
135
136
|
const timestamp = Date.now()
|
|
136
137
|
|
|
137
|
-
let evalResults
|
|
138
|
+
let evalResults
|
|
138
139
|
const { result } = await session.post('Debugger.evaluateOnCallFrame', {
|
|
139
140
|
callFrameId: params.callFrames[0].callFrameId,
|
|
140
141
|
expression: templateExpressions.length === 0
|
|
@@ -9,6 +9,7 @@ const request = require('../../exporters/common/request')
|
|
|
9
9
|
const { GIT_COMMIT_SHA, GIT_REPOSITORY_URL } = require('../../plugins/util/tags')
|
|
10
10
|
const log = require('../../log')
|
|
11
11
|
const { version } = require('../../../../../package.json')
|
|
12
|
+
const { getEnvironmentVariable } = require('../../config-helper')
|
|
12
13
|
|
|
13
14
|
module.exports = send
|
|
14
15
|
|
|
@@ -21,8 +22,8 @@ const hostname = getHostname()
|
|
|
21
22
|
const service = config.service
|
|
22
23
|
|
|
23
24
|
const ddtags = [
|
|
24
|
-
['env',
|
|
25
|
-
['version',
|
|
25
|
+
['env', getEnvironmentVariable('DD_ENV')],
|
|
26
|
+
['version', getEnvironmentVariable('DD_VERSION')],
|
|
26
27
|
['debugger_version', version],
|
|
27
28
|
['host_name', hostname],
|
|
28
29
|
[GIT_COMMIT_SHA, config.commitSHA],
|
|
@@ -31,7 +32,11 @@ const ddtags = [
|
|
|
31
32
|
|
|
32
33
|
const path = `/debugger/v1/input?${stringify({ ddtags })}`
|
|
33
34
|
|
|
34
|
-
const jsonBuffer = new JSONBuffer({
|
|
35
|
+
const jsonBuffer = new JSONBuffer({
|
|
36
|
+
size: config.maxTotalPayloadSize,
|
|
37
|
+
timeout: config.dynamicInstrumentation.uploadIntervalSeconds * 1000,
|
|
38
|
+
onFlush
|
|
39
|
+
})
|
|
35
40
|
|
|
36
41
|
function send (message, logger, dd, snapshot) {
|
|
37
42
|
const payload = {
|
|
@@ -77,9 +77,8 @@ function getObjectProperties (subtype, objectId, opts, depth) {
|
|
|
77
77
|
return getProxy(objectId, opts, depth)
|
|
78
78
|
} else if (subtype === 'arraybuffer') {
|
|
79
79
|
return getArrayBuffer(objectId, opts, depth)
|
|
80
|
-
} else {
|
|
81
|
-
return getObject(objectId, opts, depth + 1, subtype === 'array' || subtype === 'typedarray')
|
|
82
80
|
}
|
|
81
|
+
return getObject(objectId, opts, depth + 1, subtype === 'array' || subtype === 'typedarray')
|
|
83
82
|
}
|
|
84
83
|
|
|
85
84
|
// TODO: The following extra information from `internalProperties` might be relevant to include for functions:
|
|
@@ -129,11 +129,10 @@ function toFunctionOrClass (value, maxLength) {
|
|
|
129
129
|
// This is a function
|
|
130
130
|
// TODO: Would it make sense to detect if it's an arrow function or not?
|
|
131
131
|
return toObject(value.className, value.properties, maxLength)
|
|
132
|
-
} else {
|
|
133
|
-
// This is a class
|
|
134
|
-
const className = classMatch[1].trim()
|
|
135
|
-
return { type: className ? `class ${className}` : 'class' }
|
|
136
132
|
}
|
|
133
|
+
// This is a class
|
|
134
|
+
const className = classMatch[1].trim()
|
|
135
|
+
return { type: className ? `class ${className}` : 'class' }
|
|
137
136
|
}
|
|
138
137
|
|
|
139
138
|
function toString (str, maxLength) {
|
|
@@ -103,7 +103,7 @@ const REDACTED_IDENTIFIERS = new Set(
|
|
|
103
103
|
|
|
104
104
|
function normalizeName (name, isSymbol) {
|
|
105
105
|
if (isSymbol) name = name.slice(7, -1) // Remove `Symbol(` and `)`
|
|
106
|
-
return name.toLowerCase().
|
|
106
|
+
return name.toLowerCase().replaceAll(/[-_@$.]/g, '')
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
module.exports = {
|
|
@@ -20,7 +20,11 @@ const runtimeId = config.runtimeId
|
|
|
20
20
|
|
|
21
21
|
const cache = new TTLSet(60 * 60 * 1000) // 1 hour
|
|
22
22
|
|
|
23
|
-
const jsonBuffer = new JSONBuffer({
|
|
23
|
+
const jsonBuffer = new JSONBuffer({
|
|
24
|
+
size: config.maxTotalPayloadSize,
|
|
25
|
+
timeout: config.dynamicInstrumentation.uploadIntervalSeconds * 1000,
|
|
26
|
+
onFlush
|
|
27
|
+
})
|
|
24
28
|
|
|
25
29
|
const STATUSES = {
|
|
26
30
|
RECEIVED: 'RECEIVED',
|
|
@@ -169,7 +169,7 @@ class DogStatsDClient {
|
|
|
169
169
|
})
|
|
170
170
|
.forEach(key => {
|
|
171
171
|
// https://docs.datadoghq.com/tagging/#defining-tags
|
|
172
|
-
const value = config.tags[key].
|
|
172
|
+
const value = config.tags[key].replaceAll(/[^a-z0-9_:./-]/ig, '_')
|
|
173
173
|
|
|
174
174
|
tags.push(`${key}:${value}`)
|
|
175
175
|
})
|
|
@@ -244,7 +244,7 @@ class MetricsAggregationClient {
|
|
|
244
244
|
const container = monotonic ? this._counters : this._gauges
|
|
245
245
|
const node = this._ensureTree(container, name, tags, 0)
|
|
246
246
|
|
|
247
|
-
node.value
|
|
247
|
+
node.value += count
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
gauge (name, value, tags) {
|
|
@@ -6,6 +6,7 @@ const log = require('../log')
|
|
|
6
6
|
const { isTrue } = require('../util')
|
|
7
7
|
const coalesce = require('koalas')
|
|
8
8
|
const { memoize } = require('../log/utils')
|
|
9
|
+
const { getEnvironmentVariable } = require('../config-helper')
|
|
9
10
|
|
|
10
11
|
const SOFT_LIMIT = 8 * 1024 * 1024 // 8MB
|
|
11
12
|
|
|
@@ -32,7 +33,7 @@ class AgentEncoder {
|
|
|
32
33
|
this._writer = writer
|
|
33
34
|
this._reset()
|
|
34
35
|
this._debugEncoding = isTrue(coalesce(
|
|
35
|
-
|
|
36
|
+
getEnvironmentVariable('DD_TRACE_ENCODING_DEBUG'),
|
|
36
37
|
false
|
|
37
38
|
))
|
|
38
39
|
this._config = this._writer?._config
|
|
@@ -349,15 +350,17 @@ const memoizedLogDebug = memoize((key, message) => {
|
|
|
349
350
|
function formatSpanEvents (span) {
|
|
350
351
|
for (const spanEvent of span.span_events) {
|
|
351
352
|
if (spanEvent.attributes) {
|
|
353
|
+
let hasAttributes = false
|
|
352
354
|
for (const [key, value] of Object.entries(spanEvent.attributes)) {
|
|
353
355
|
const newValue = convertSpanEventAttributeValues(key, value)
|
|
354
356
|
if (newValue === undefined) {
|
|
355
357
|
delete spanEvent.attributes[key] // delete from attributes if undefined
|
|
356
358
|
} else {
|
|
359
|
+
hasAttributes = true
|
|
357
360
|
spanEvent.attributes[key] = newValue
|
|
358
361
|
}
|
|
359
362
|
}
|
|
360
|
-
if (
|
|
363
|
+
if (!hasAttributes) {
|
|
361
364
|
delete spanEvent.attributes
|
|
362
365
|
}
|
|
363
366
|
}
|
|
@@ -23,12 +23,10 @@ class AgentEncoder extends BaseEncoder {
|
|
|
23
23
|
const traceSize = this._traceBytes.length + 5
|
|
24
24
|
const buffer = Buffer.allocUnsafe(prefixSize + stringSize + traceSize)
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
buffer[0] = ARRAY_OF_TWO
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
offset = this._writeStrings(buffer, offset)
|
|
31
|
-
offset = this._writeTraces(buffer, offset)
|
|
28
|
+
const offset = this._writeStrings(buffer, 1)
|
|
29
|
+
this._writeTraces(buffer, offset)
|
|
32
30
|
|
|
33
31
|
this._reset()
|
|
34
32
|
|
|
@@ -161,20 +161,20 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
161
161
|
_encodeEventContent (bytes, content) {
|
|
162
162
|
let totalKeysLength = TEST_AND_SPAN_KEYS_LENGTH
|
|
163
163
|
if (content.meta.test_session_id) {
|
|
164
|
-
totalKeysLength
|
|
164
|
+
totalKeysLength += 1
|
|
165
165
|
}
|
|
166
166
|
if (content.meta.test_module_id) {
|
|
167
|
-
totalKeysLength
|
|
167
|
+
totalKeysLength += 1
|
|
168
168
|
}
|
|
169
169
|
if (content.meta.test_suite_id) {
|
|
170
|
-
totalKeysLength
|
|
170
|
+
totalKeysLength += 1
|
|
171
171
|
}
|
|
172
172
|
const itrCorrelationId = content.meta[ITR_CORRELATION_ID]
|
|
173
173
|
if (itrCorrelationId) {
|
|
174
|
-
totalKeysLength
|
|
174
|
+
totalKeysLength += 1
|
|
175
175
|
}
|
|
176
176
|
if (content.type) {
|
|
177
|
-
totalKeysLength
|
|
177
|
+
totalKeysLength += 1
|
|
178
178
|
}
|
|
179
179
|
this._encodeMapPrefix(bytes, totalKeysLength)
|
|
180
180
|
if (content.type) {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const exporters = require('../../../ext/exporters')
|
|
4
4
|
const fs = require('fs')
|
|
5
5
|
const constants = require('./constants')
|
|
6
|
+
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
6
7
|
|
|
7
8
|
module.exports = function getExporter (name) {
|
|
8
9
|
switch (name) {
|
|
@@ -20,7 +21,7 @@ module.exports = function getExporter (name) {
|
|
|
20
21
|
case exporters.PLAYWRIGHT_WORKER:
|
|
21
22
|
return require('./ci-visibility/exporters/test-worker')
|
|
22
23
|
default: {
|
|
23
|
-
const inAWSLambda =
|
|
24
|
+
const inAWSLambda = getEnvironmentVariable('AWS_LAMBDA_FUNCTION_NAME') !== undefined
|
|
24
25
|
const usingLambdaExtension = inAWSLambda && fs.existsSync(constants.DATADOG_LAMBDA_EXTENSION_PATH)
|
|
25
26
|
return require(inAWSLambda && !usingLambdaExtension ? './exporters/log' : './exporters/agent')
|
|
26
27
|
}
|
|
@@ -69,7 +69,9 @@ function setHeader (headers, key, value) {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
function getEncoder (protocolVersion) {
|
|
72
|
-
return
|
|
72
|
+
return protocolVersion === '0.5'
|
|
73
|
+
? require('../../encode/0.5').AgentEncoder
|
|
74
|
+
: require('../../encode/0.4').AgentEncoder
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
function makeRequest (version, data, count, url, headers, lookup, needsStartupLog, cb) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const fs = require('fs')
|
|
4
|
+
const { getEnvironmentVariable } = require('../../config-helper')
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
+
const DD_EXTERNAL_ENV = getEnvironmentVariable('DD_EXTERNAL_ENV')
|
|
6
7
|
|
|
7
8
|
// The second part is the PCF / Garden regexp. We currently assume no suffix($) to avoid matching pod UIDs
|
|
8
9
|
// See https://github.com/DataDog/datadog-agent/blob/7.40.x/pkg/util/cgroups/reader.go#L50
|
|
@@ -24,7 +25,7 @@ try {
|
|
|
24
25
|
|
|
25
26
|
const inodePath = cgroup.match(lineReg)?.[3]
|
|
26
27
|
if (inodePath) {
|
|
27
|
-
const strippedPath = inodePath.
|
|
28
|
+
const strippedPath = inodePath.replaceAll(/^\/|\/$/g, '')
|
|
28
29
|
|
|
29
30
|
try {
|
|
30
31
|
inode = fs.statSync(`/sys/fs/cgroup/${strippedPath}`).ino
|
|
@@ -56,9 +56,12 @@ function request (data, options, callback) {
|
|
|
56
56
|
const timeout = options.timeout || 2000
|
|
57
57
|
const isSecure = options.protocol === 'https:'
|
|
58
58
|
const client = isSecure ? https : http
|
|
59
|
-
|
|
59
|
+
let dataArray = data
|
|
60
60
|
|
|
61
61
|
if (!isReadable) {
|
|
62
|
+
if (!Array.isArray(data)) {
|
|
63
|
+
dataArray = [data]
|
|
64
|
+
}
|
|
62
65
|
options.headers['Content-Length'] = byteLength(dataArray)
|
|
63
66
|
}
|
|
64
67
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
const { getEnvironmentVariable } = require('../../config-helper')
|
|
2
|
+
|
|
1
3
|
function safeJSONStringify (value) {
|
|
2
4
|
return JSON.stringify(
|
|
3
5
|
value,
|
|
4
6
|
(key, value) => key === 'dd-api-key' ? undefined : value,
|
|
5
|
-
|
|
7
|
+
getEnvironmentVariable('DD_TRACE_BEAUTIFUL_LOGS') ? 2 : undefined
|
|
6
8
|
)
|
|
7
9
|
}
|
|
8
10
|
|
|
@@ -174,11 +174,11 @@ function readInt32 (buffer, offset) {
|
|
|
174
174
|
// Write unsigned integer bytes to a buffer.
|
|
175
175
|
function writeUInt32BE (buffer, value, offset) {
|
|
176
176
|
buffer[3 + offset] = value & 255
|
|
177
|
-
value
|
|
177
|
+
value >>= 8
|
|
178
178
|
buffer[2 + offset] = value & 255
|
|
179
|
-
value
|
|
179
|
+
value >>= 8
|
|
180
180
|
buffer[1 + offset] = value & 255
|
|
181
|
-
value
|
|
181
|
+
value >>= 8
|
|
182
182
|
buffer[0 + offset] = value & 255
|
|
183
183
|
}
|
|
184
184
|
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { isFalse } = require('./util')
|
|
4
|
+
const { getEnvironmentVariable } = require('../../dd-trace/src/config-helper')
|
|
4
5
|
|
|
5
6
|
// Global `jest` is only present in Jest workers.
|
|
6
7
|
const inJestWorker = typeof jest !== 'undefined'
|
|
7
8
|
|
|
8
|
-
const ddTraceDisabled =
|
|
9
|
-
? isFalse(
|
|
10
|
-
: String(
|
|
9
|
+
const ddTraceDisabled = getEnvironmentVariable('DD_TRACE_ENABLED')
|
|
10
|
+
? isFalse(getEnvironmentVariable('DD_TRACE_ENABLED'))
|
|
11
|
+
: String(getEnvironmentVariable('OTEL_TRACES_EXPORTER')).toLowerCase() === 'none'
|
|
11
12
|
|
|
12
13
|
module.exports = ddTraceDisabled || inJestWorker
|
|
13
14
|
? require('./noop/proxy')
|
|
@@ -4,6 +4,7 @@ const log = require('../log')
|
|
|
4
4
|
const { channel } = require('../../../datadog-instrumentations/src/helpers/instrument')
|
|
5
5
|
const { ERROR_MESSAGE, ERROR_TYPE } = require('../constants')
|
|
6
6
|
const { ImpendingTimeout } = require('./runtime/errors')
|
|
7
|
+
const { getEnvironmentVariable } = require('../config-helper')
|
|
7
8
|
|
|
8
9
|
const globalTracer = global._ddtrace
|
|
9
10
|
const tracer = globalTracer._tracer
|
|
@@ -25,7 +26,7 @@ let __lambdaTimeout
|
|
|
25
26
|
function checkTimeout (context) {
|
|
26
27
|
const remainingTimeInMillis = context.getRemainingTimeInMillis()
|
|
27
28
|
|
|
28
|
-
let apmFlushDeadline = Number.parseInt(
|
|
29
|
+
let apmFlushDeadline = Number.parseInt(getEnvironmentVariable('DD_APM_FLUSH_DEADLINE_MILLISECONDS')) || 100
|
|
29
30
|
apmFlushDeadline = apmFlushDeadline < 0 ? 100 : apmFlushDeadline
|
|
30
31
|
|
|
31
32
|
__lambdaTimeout = setTimeout(() => {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { registerLambdaHook } = require('./runtime/ritm')
|
|
4
|
+
const { getEnvironmentVariable } = require('../config-helper')
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* It is safe to do it this way, since customers will never be expected to disable
|
|
7
8
|
* this specific instrumentation through the init config object.
|
|
8
9
|
*/
|
|
9
|
-
const _DD_TRACE_DISABLED_INSTRUMENTATIONS =
|
|
10
|
+
const _DD_TRACE_DISABLED_INSTRUMENTATIONS = getEnvironmentVariable('DD_TRACE_DISABLED_INSTRUMENTATIONS') || ''
|
|
10
11
|
const _disabledInstrumentations = new Set(
|
|
11
12
|
_DD_TRACE_DISABLED_INSTRUMENTATIONS ? _DD_TRACE_DISABLED_INSTRUMENTATIONS.split(',') : []
|
|
12
13
|
)
|
|
@@ -6,6 +6,7 @@ const { _extractModuleNameAndHandlerPath, _extractModuleRootAndHandler, _getLamb
|
|
|
6
6
|
const { datadog } = require('../handler')
|
|
7
7
|
const { addHook } = require('../../../../datadog-instrumentations/src/helpers/instrument')
|
|
8
8
|
const shimmer = require('../../../../datadog-shimmer')
|
|
9
|
+
const { getEnvironmentVariable } = require('../../config-helper')
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Patches a Datadog Lambda module by calling `patchDatadogLambdaHandler`
|
|
@@ -57,8 +58,8 @@ function patchLambdaHandler (lambdaHandler) {
|
|
|
57
58
|
return datadog(lambdaHandler)
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
const lambdaTaskRoot =
|
|
61
|
-
const originalLambdaHandler =
|
|
61
|
+
const lambdaTaskRoot = getEnvironmentVariable('LAMBDA_TASK_ROOT')
|
|
62
|
+
const originalLambdaHandler = getEnvironmentVariable('DD_LAMBDA_HANDLER')
|
|
62
63
|
|
|
63
64
|
if (originalLambdaHandler === undefined) {
|
|
64
65
|
// Instrumentation is done manually.
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
const path = require('path')
|
|
11
11
|
|
|
12
12
|
const log = require('../../log')
|
|
13
|
+
const { getEnvironmentVariable } = require('../../config-helper')
|
|
13
14
|
const Hook = require('../../../../datadog-instrumentations/src/helpers/hook')
|
|
14
15
|
const instrumentations = require('../../../../datadog-instrumentations/src/helpers/instrumentations')
|
|
15
16
|
const {
|
|
@@ -78,8 +79,8 @@ function _getLambdaFilePaths (lambdaStylePath) {
|
|
|
78
79
|
* the file is required.
|
|
79
80
|
*/
|
|
80
81
|
const registerLambdaHook = () => {
|
|
81
|
-
const lambdaTaskRoot =
|
|
82
|
-
const originalLambdaHandler =
|
|
82
|
+
const lambdaTaskRoot = getEnvironmentVariable('LAMBDA_TASK_ROOT')
|
|
83
|
+
const originalLambdaHandler = getEnvironmentVariable('DD_LAMBDA_HANDLER')
|
|
83
84
|
|
|
84
85
|
if (originalLambdaHandler !== undefined && lambdaTaskRoot !== undefined) {
|
|
85
86
|
const [moduleRoot, moduleAndHandler] = _extractModuleRootAndHandler(originalLambdaHandler)
|
|
@@ -10,6 +10,7 @@ module.exports = {
|
|
|
10
10
|
METRICS: '_ml_obs.metrics',
|
|
11
11
|
ML_APP: '_ml_obs.meta.ml_app',
|
|
12
12
|
PROPAGATED_PARENT_ID_KEY: '_dd.p.llmobs_parent_id',
|
|
13
|
+
PROPAGATED_ML_APP_KEY: '_dd.p.llmobs_ml_app',
|
|
13
14
|
PARENT_ID_KEY: '_ml_obs.llmobs_parent_id',
|
|
14
15
|
TAGS: '_ml_obs.tags',
|
|
15
16
|
NAME: '_ml_obs.name',
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const log = require('../log')
|
|
4
|
-
const {
|
|
4
|
+
const {
|
|
5
|
+
ML_APP,
|
|
6
|
+
PROPAGATED_ML_APP_KEY,
|
|
7
|
+
PROPAGATED_PARENT_ID_KEY
|
|
8
|
+
} = require('./constants/tags')
|
|
5
9
|
const { storage } = require('./storage')
|
|
6
10
|
|
|
7
11
|
const telemetry = require('./telemetry')
|
|
@@ -14,6 +18,7 @@ const flushCh = channel('llmobs:writers:flush')
|
|
|
14
18
|
const injectCh = channel('dd-trace:span:inject')
|
|
15
19
|
|
|
16
20
|
const LLMObsEvalMetricsWriter = require('./writers/evaluations')
|
|
21
|
+
const LLMObsTagger = require('./tagger')
|
|
17
22
|
const LLMObsSpanWriter = require('./writers/spans')
|
|
18
23
|
const { setAgentStrategy } = require('./writers/util')
|
|
19
24
|
|
|
@@ -35,7 +40,12 @@ let spanWriter
|
|
|
35
40
|
/** @type {LLMObsEvalMetricsWriter | null} */
|
|
36
41
|
let evalWriter
|
|
37
42
|
|
|
43
|
+
/** @type {import('../config')} */
|
|
44
|
+
let globalTracerConfig
|
|
45
|
+
|
|
38
46
|
function enable (config) {
|
|
47
|
+
globalTracerConfig = config
|
|
48
|
+
|
|
39
49
|
const startTime = performance.now()
|
|
40
50
|
// create writers and eval writer append and flush channels
|
|
41
51
|
// span writer append is handled by the span processor
|
|
@@ -83,14 +93,20 @@ function disable () {
|
|
|
83
93
|
}
|
|
84
94
|
|
|
85
95
|
// since LLMObs traces can extend between services and be the same trace,
|
|
86
|
-
// we need to
|
|
96
|
+
// we need to propagate the parent id and mlApp.
|
|
87
97
|
function handleLLMObsParentIdInjection ({ carrier }) {
|
|
88
98
|
const parent = storage.getStore()?.span
|
|
89
|
-
|
|
99
|
+
const mlObsSpanTags = LLMObsTagger.tagMap.get(parent)
|
|
90
100
|
|
|
91
|
-
const
|
|
101
|
+
const parentContext = parent?.context()
|
|
102
|
+
const parentId = parentContext?.toSpanId()
|
|
103
|
+
const mlApp =
|
|
104
|
+
mlObsSpanTags?.[ML_APP] ||
|
|
105
|
+
parentContext?._trace?.tags?.[PROPAGATED_ML_APP_KEY] ||
|
|
106
|
+
globalTracerConfig.llmobs.mlApp
|
|
92
107
|
|
|
93
|
-
carrier['x-datadog-tags'] += `,${PROPAGATED_PARENT_ID_KEY}=${parentId}`
|
|
108
|
+
if (parentId) carrier['x-datadog-tags'] += `,${PROPAGATED_PARENT_ID_KEY}=${parentId}`
|
|
109
|
+
if (mlApp) carrier['x-datadog-tags'] += `,${PROPAGATED_ML_APP_KEY}=${mlApp}`
|
|
94
110
|
}
|
|
95
111
|
|
|
96
112
|
function handleFlush () {
|
|
@@ -44,27 +44,25 @@ class NoopLLMObs {
|
|
|
44
44
|
if (ctx.kind !== 'method') return target
|
|
45
45
|
|
|
46
46
|
return llmobs.wrap({ name: ctx.name, _decorator: true, ...options }, target)
|
|
47
|
-
} else {
|
|
48
|
-
const propertyKey = ctxOrPropertyKey
|
|
49
|
-
if (descriptor) {
|
|
50
|
-
if (typeof descriptor.value !== 'function') return descriptor
|
|
51
|
-
|
|
52
|
-
const original = descriptor.value
|
|
53
|
-
descriptor.value = llmobs.wrap({ name: propertyKey, _decorator: true, ...options }, original)
|
|
54
|
-
|
|
55
|
-
return descriptor
|
|
56
|
-
} else {
|
|
57
|
-
if (typeof target[propertyKey] !== 'function') return target[propertyKey]
|
|
58
|
-
|
|
59
|
-
const original = target[propertyKey]
|
|
60
|
-
Object.defineProperty(target, propertyKey, {
|
|
61
|
-
...Object.getOwnPropertyDescriptor(target, propertyKey),
|
|
62
|
-
value: llmobs.wrap({ name: propertyKey, _decorator: true, ...options }, original)
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
return target
|
|
66
|
-
}
|
|
67
47
|
}
|
|
48
|
+
const propertyKey = ctxOrPropertyKey
|
|
49
|
+
if (descriptor) {
|
|
50
|
+
if (typeof descriptor.value !== 'function') return descriptor
|
|
51
|
+
|
|
52
|
+
const original = descriptor.value
|
|
53
|
+
descriptor.value = llmobs.wrap({ name: propertyKey, _decorator: true, ...options }, original)
|
|
54
|
+
|
|
55
|
+
return descriptor
|
|
56
|
+
}
|
|
57
|
+
if (typeof target[propertyKey] !== 'function') return target[propertyKey]
|
|
58
|
+
|
|
59
|
+
const original = target[propertyKey]
|
|
60
|
+
Object.defineProperty(target, propertyKey, {
|
|
61
|
+
...Object.getOwnPropertyDescriptor(target, propertyKey),
|
|
62
|
+
value: llmobs.wrap({ name: propertyKey, _decorator: true, ...options }, original)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
return target
|
|
68
66
|
}
|
|
69
67
|
}
|
|
70
68
|
|
|
@@ -23,26 +23,24 @@ class LangChainLLMObsHandler {
|
|
|
23
23
|
return formatted
|
|
24
24
|
} else if (Array.isArray(messages)) {
|
|
25
25
|
return messages.map(message => this.formatIO(message))
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
}
|
|
26
|
+
} // either a BaseMesage type or a string
|
|
27
|
+
return this.getContentFromMessage(messages)
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
getContentFromMessage (message) {
|
|
32
31
|
if (typeof message === 'string') {
|
|
33
32
|
return message
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const messageContent = {}
|
|
36
|
+
messageContent.content = message.content || ''
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
const role = this.getRole(message)
|
|
39
|
+
if (role) messageContent.role = role
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
41
|
+
return messageContent
|
|
42
|
+
} catch {
|
|
43
|
+
return JSON.stringify(message)
|
|
46
44
|
}
|
|
47
45
|
}
|
|
48
46
|
|
|
@@ -68,9 +68,8 @@ class OpenAiLLMObsPlugin extends LLMObsPlugin {
|
|
|
68
68
|
return { modelProvider: 'azure_openai', client: 'AzureOpenAI' }
|
|
69
69
|
} else if (baseUrl.includes('deepseek')) {
|
|
70
70
|
return { modelProvider: 'deepseek', client: 'DeepSeek' }
|
|
71
|
-
} else {
|
|
72
|
-
return { modelProvider: 'openai', client: 'OpenAI' }
|
|
73
71
|
}
|
|
72
|
+
return { modelProvider: 'openai', client: 'OpenAI' }
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
_extractMetrics (response) {
|
|
@@ -14,6 +14,7 @@ const Span = require('../opentracing/span')
|
|
|
14
14
|
|
|
15
15
|
const tracerVersion = require('../../../../package.json').version
|
|
16
16
|
const logger = require('../log')
|
|
17
|
+
const { getEnvironmentVariable } = require('../config-helper')
|
|
17
18
|
const telemetry = require('./telemetry')
|
|
18
19
|
|
|
19
20
|
const LLMObsTagger = require('./tagger')
|
|
@@ -47,7 +48,7 @@ class LLMObs extends NoopLLMObs {
|
|
|
47
48
|
|
|
48
49
|
const { mlApp, agentlessEnabled } = options
|
|
49
50
|
|
|
50
|
-
const
|
|
51
|
+
const DD_LLMOBS_ENABLED = getEnvironmentVariable('DD_LLMOBS_ENABLED')
|
|
51
52
|
|
|
52
53
|
const llmobsConfig = {
|
|
53
54
|
mlApp,
|
|
@@ -158,7 +158,7 @@ class LLMObsSpanProcessor {
|
|
|
158
158
|
const add = (obj, carrier) => {
|
|
159
159
|
for (const key in obj) {
|
|
160
160
|
const value = obj[key]
|
|
161
|
-
if (!Object.
|
|
161
|
+
if (!Object.hasOwn(obj, key)) continue
|
|
162
162
|
if (typeof value === 'bigint' || isCircular(value)) {
|
|
163
163
|
// mark as unserializable instead of dropping
|
|
164
164
|
logger.warn(`Unserializable property found in metadata: ${key}`)
|