dd-trace 5.54.0 → 5.55.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/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 +6 -6
- package/packages/datadog-code-origin/index.js +22 -4
- package/packages/datadog-core/src/utils/src/kebabcase.js +3 -3
- 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 +67 -98
- 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-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-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/security-controls/index.js +11 -12
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -1
- 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 +4 -4
- package/packages/dd-trace/src/appsec/reporter.js +5 -7
- 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/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 +77 -78
- 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 +3 -2
- 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/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/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 +17 -18
- 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/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 +439 -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 +12 -25
- package/packages/dd-trace/src/tracer.js +3 -7
- package/packages/dd-trace/src/util.js +0 -5
- 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
|
@@ -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
|
}
|
|
@@ -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}`)
|
|
@@ -24,7 +24,8 @@ const {
|
|
|
24
24
|
OUTPUT_TOKENS_METRIC_KEY,
|
|
25
25
|
TOTAL_TOKENS_METRIC_KEY,
|
|
26
26
|
INTEGRATION,
|
|
27
|
-
DECORATOR
|
|
27
|
+
DECORATOR,
|
|
28
|
+
PROPAGATED_ML_APP_KEY
|
|
28
29
|
} = require('./constants/tags')
|
|
29
30
|
|
|
30
31
|
// global registry of LLMObs spans
|
|
@@ -73,12 +74,24 @@ class LLMObsTagger {
|
|
|
73
74
|
if (integration) this._setTag(span, INTEGRATION, integration)
|
|
74
75
|
if (_decorator) this._setTag(span, DECORATOR, _decorator)
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
const spanMlApp =
|
|
78
|
+
mlApp ||
|
|
79
|
+
registry.get(parent)?.[ML_APP] ||
|
|
80
|
+
span.context()._trace.tags[PROPAGATED_ML_APP_KEY] ||
|
|
81
|
+
this._config.llmobs.mlApp
|
|
82
|
+
|
|
83
|
+
if (!spanMlApp) {
|
|
84
|
+
throw new Error(
|
|
85
|
+
'[LLMObs] Cannot start an LLMObs span without an mlApp configured.' +
|
|
86
|
+
'Ensure this configuration is set before running your application.'
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
this._setTag(span, ML_APP, spanMlApp)
|
|
78
91
|
|
|
79
92
|
const parentId =
|
|
80
|
-
parent?.context().toSpanId()
|
|
81
|
-
span.context()._trace.tags[PROPAGATED_PARENT_ID_KEY]
|
|
93
|
+
parent?.context().toSpanId() ??
|
|
94
|
+
span.context()._trace.tags[PROPAGATED_PARENT_ID_KEY] ??
|
|
82
95
|
ROOT_PARENT_ID
|
|
83
96
|
this._setTag(span, PARENT_ID_KEY, parentId)
|
|
84
97
|
}
|
|
@@ -357,7 +370,7 @@ class LLMObsTagger {
|
|
|
357
370
|
}
|
|
358
371
|
|
|
359
372
|
const tagsCarrier = registry.get(span)
|
|
360
|
-
|
|
373
|
+
tagsCarrier[key] = value
|
|
361
374
|
}
|
|
362
375
|
}
|
|
363
376
|
|
|
@@ -157,7 +157,7 @@ class BaseLLMObsWriter {
|
|
|
157
157
|
return encodeUnicode(value) // serialize unicode characters
|
|
158
158
|
}
|
|
159
159
|
return value
|
|
160
|
-
}).
|
|
160
|
+
}).replaceAll(String.raw`\\u`, String.raw`\u`) // remove double escaping
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
@@ -7,6 +7,7 @@ const { traceChannel, debugChannel, infoChannel, warnChannel, errorChannel } = r
|
|
|
7
7
|
const logWriter = require('./writer')
|
|
8
8
|
const { Log } = require('./log')
|
|
9
9
|
const { memoize } = require('./utils')
|
|
10
|
+
const { getEnvironmentVariable } = require('../config-helper')
|
|
10
11
|
|
|
11
12
|
const config = {
|
|
12
13
|
enabled: false,
|
|
@@ -98,8 +99,8 @@ const log = {
|
|
|
98
99
|
isEnabled (fleetStableConfigValue, localStableConfigValue) {
|
|
99
100
|
return isTrue(coalesce(
|
|
100
101
|
fleetStableConfigValue,
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
getEnvironmentVariable('DD_TRACE_DEBUG'),
|
|
103
|
+
getEnvironmentVariable('OTEL_LOG_LEVEL') === 'debug' || undefined,
|
|
103
104
|
localStableConfigValue,
|
|
104
105
|
config.enabled
|
|
105
106
|
))
|
|
@@ -113,8 +114,8 @@ const log = {
|
|
|
113
114
|
return coalesce(
|
|
114
115
|
optionsValue,
|
|
115
116
|
fleetStableConfigValue,
|
|
116
|
-
|
|
117
|
-
|
|
117
|
+
getEnvironmentVariable('DD_TRACE_LOG_LEVEL'),
|
|
118
|
+
getEnvironmentVariable('OTEL_LOG_LEVEL'),
|
|
118
119
|
localStableConfigValue,
|
|
119
120
|
config.logLevel
|
|
120
121
|
)
|
|
@@ -57,9 +57,8 @@ function getErrorLog (err) {
|
|
|
57
57
|
if (typeof err?.delegate === 'function') {
|
|
58
58
|
const result = err.delegate()
|
|
59
59
|
return Array.isArray(result) ? Log.parse(...result) : Log.parse(result)
|
|
60
|
-
} else {
|
|
61
|
-
return err
|
|
62
60
|
}
|
|
61
|
+
return err
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
function setStackTraceLimitFunction (fn) {
|
|
@@ -163,7 +163,7 @@ class MsgpackEncoder {
|
|
|
163
163
|
|
|
164
164
|
encodeLong (bytes, value) {
|
|
165
165
|
const offset = bytes.length
|
|
166
|
-
const hi = (value /
|
|
166
|
+
const hi = (value / 2 ** 32) >> 0
|
|
167
167
|
const lo = value >>> 0
|
|
168
168
|
|
|
169
169
|
bytes.reserve(9)
|
|
@@ -216,7 +216,7 @@ class MsgpackEncoder {
|
|
|
216
216
|
bytes.buffer[offset + 3] = value >> 8
|
|
217
217
|
bytes.buffer[offset + 4] = value
|
|
218
218
|
} else {
|
|
219
|
-
const hi = Math.floor(value /
|
|
219
|
+
const hi = Math.floor(value / 2 ** 32)
|
|
220
220
|
const lo = value >>> 0
|
|
221
221
|
|
|
222
222
|
bytes.reserve(9)
|
|
@@ -255,7 +255,7 @@ class MsgpackEncoder {
|
|
|
255
255
|
bytes.buffer[offset + 3] = value >> 8
|
|
256
256
|
bytes.buffer[offset + 4] = value
|
|
257
257
|
} else {
|
|
258
|
-
const hi = (value /
|
|
258
|
+
const hi = (value / 2 ** 32) >> 0
|
|
259
259
|
const lo = value >>> 0
|
|
260
260
|
|
|
261
261
|
bytes.reserve(9)
|
|
@@ -32,7 +32,7 @@ class Tracer {
|
|
|
32
32
|
spanId: id(),
|
|
33
33
|
parentId: parentSpanContext._spanId,
|
|
34
34
|
sampling: parentSpanContext._sampling,
|
|
35
|
-
baggageItems:
|
|
35
|
+
baggageItems: { ...parentSpanContext._baggageItems },
|
|
36
36
|
trace: parentSpanContext._trace,
|
|
37
37
|
tracestate: parentSpanContext._tracestate
|
|
38
38
|
})
|
|
@@ -43,12 +43,11 @@ class LogPropagator {
|
|
|
43
43
|
spanContext._trace.tags['_dd.p.tid'] = hi
|
|
44
44
|
|
|
45
45
|
return spanContext
|
|
46
|
-
} else {
|
|
47
|
-
return new DatadogSpanContext({
|
|
48
|
-
traceId: id(carrier.dd.trace_id, 10),
|
|
49
|
-
spanId: id(carrier.dd.span_id, 10)
|
|
50
|
-
})
|
|
51
46
|
}
|
|
47
|
+
return new DatadogSpanContext({
|
|
48
|
+
traceId: id(carrier.dd.trace_id, 10),
|
|
49
|
+
spanId: id(carrier.dd.span_id, 10)
|
|
50
|
+
})
|
|
52
51
|
}
|
|
53
52
|
}
|
|
54
53
|
|