dd-trace 5.58.0 → 5.60.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/after-run.js +2 -0
- package/ci/cypress/after-spec.js +2 -0
- package/ci/cypress/plugin.js +2 -0
- package/ci/cypress/polyfills.js +2 -0
- package/ci/cypress/support.js +2 -0
- package/ci/init.js +2 -0
- package/index.d.ts +7 -0
- package/init.js +0 -2
- package/initialize.mjs +2 -0
- package/package.json +40 -8
- package/packages/datadog-code-origin/index.js +14 -9
- package/packages/datadog-instrumentations/src/apollo-server.js +14 -3
- package/packages/datadog-instrumentations/src/apollo.js +7 -10
- package/packages/datadog-instrumentations/src/avsc.js +2 -0
- package/packages/datadog-instrumentations/src/child_process.js +21 -42
- package/packages/datadog-instrumentations/src/cucumber.js +10 -8
- package/packages/datadog-instrumentations/src/cypress.js +2 -0
- package/packages/datadog-instrumentations/src/fastify.js +19 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +1 -1
- package/packages/datadog-instrumentations/src/hono.js +102 -0
- package/packages/datadog-instrumentations/src/langchain.js +21 -0
- package/packages/datadog-instrumentations/src/mocha/common.js +2 -0
- package/packages/datadog-instrumentations/src/mocha.js +2 -0
- package/packages/datadog-instrumentations/src/nyc.js +2 -0
- package/packages/datadog-instrumentations/src/openai.js +13 -114
- package/packages/datadog-instrumentations/src/orchestrion-config/index.js +32 -0
- package/packages/datadog-instrumentations/src/playwright.js +5 -1
- package/packages/datadog-instrumentations/src/protobufjs.js +2 -0
- package/packages/datadog-instrumentations/src/selenium.js +2 -0
- package/packages/datadog-instrumentations/src/vitest.js +2 -0
- package/packages/datadog-plugin-avsc/src/index.js +2 -0
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +2 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +2 -0
- package/packages/datadog-plugin-child_process/src/index.js +30 -10
- package/packages/datadog-plugin-cypress/src/after-run.js +2 -0
- package/packages/datadog-plugin-cypress/src/after-spec.js +2 -0
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +8 -3
- package/packages/datadog-plugin-cypress/src/index.js +2 -0
- package/packages/datadog-plugin-cypress/src/plugin.js +2 -0
- package/packages/datadog-plugin-cypress/src/support.js +4 -2
- package/packages/datadog-plugin-google-cloud-vertexai/src/tracing.js +3 -155
- package/packages/datadog-plugin-google-cloud-vertexai/src/utils.js +2 -0
- package/packages/datadog-plugin-graphql/src/utils.js +2 -0
- package/packages/datadog-plugin-hono/src/index.js +28 -0
- package/packages/datadog-plugin-jest/src/index.js +2 -0
- package/packages/datadog-plugin-jest/src/util.js +2 -0
- package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -0
- package/packages/datadog-plugin-langchain/src/tracing.js +36 -4
- package/packages/datadog-plugin-nyc/src/index.js +2 -0
- package/packages/datadog-plugin-openai/src/stream-helpers.js +114 -0
- package/packages/datadog-plugin-openai/src/tracing.js +38 -0
- package/packages/datadog-plugin-oracledb/src/connection-parser.js +2 -0
- package/packages/datadog-plugin-protobufjs/src/index.js +2 -0
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +2 -0
- package/packages/datadog-plugin-selenium/src/index.js +2 -0
- package/packages/datadog-plugin-vitest/src/index.js +2 -0
- package/packages/dd-trace/src/appsec/iast/iast-context.js +5 -1
- package/packages/dd-trace/src/appsec/iast/index.js +2 -0
- package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +0 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +2 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +2 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +2 -0
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +3 -3
- package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +18 -11
- package/packages/dd-trace/src/appsec/rasp/utils.js +1 -1
- package/packages/dd-trace/src/appsec/recommended.json +88 -2
- package/packages/dd-trace/src/appsec/reporter.js +7 -19
- package/packages/dd-trace/src/appsec/stack_trace.js +11 -11
- package/packages/dd-trace/src/appsec/telemetry/common.js +1 -1
- package/packages/dd-trace/src/appsec/waf/index.js +20 -1
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +2 -2
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +5 -4
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -0
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +3 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -0
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +2 -0
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -0
- package/packages/dd-trace/src/ci-visibility/telemetry.js +2 -0
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +2 -0
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +7 -3
- package/packages/dd-trace/src/config.js +4 -16
- package/packages/dd-trace/src/config_stable.js +2 -0
- package/packages/dd-trace/src/datastreams/checkpointer.js +2 -0
- package/packages/dd-trace/src/datastreams/context.js +2 -0
- package/packages/dd-trace/src/datastreams/encoding.js +2 -0
- package/packages/dd-trace/src/datastreams/fnv.js +2 -0
- package/packages/dd-trace/src/datastreams/pathway.js +11 -9
- package/packages/dd-trace/src/datastreams/processor.js +8 -7
- package/packages/dd-trace/src/datastreams/schemas/schema.js +2 -0
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +45 -36
- package/packages/dd-trace/src/datastreams/schemas/schema_sampler.js +2 -0
- package/packages/dd-trace/src/datastreams/writer.js +2 -0
- package/packages/dd-trace/src/debugger/config.js +16 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -6
- package/packages/dd-trace/src/debugger/devtools_client/index.js +13 -5
- package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +2 -0
- package/packages/dd-trace/src/debugger/devtools_client/log.js +19 -0
- package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +9 -6
- package/packages/dd-trace/src/debugger/devtools_client/send.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/state.js +1 -1
- package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
- package/packages/dd-trace/src/debugger/index.js +48 -11
- package/packages/dd-trace/src/encode/tags-processors.js +2 -0
- package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +2 -0
- package/packages/dd-trace/src/exporters/common/util.js +2 -0
- package/packages/dd-trace/src/exporters/span-stats/index.js +2 -0
- package/packages/dd-trace/src/exporters/span-stats/writer.js +2 -0
- package/packages/dd-trace/src/external-logger/src/index.js +2 -0
- package/packages/dd-trace/src/git_metadata_tagger.js +2 -0
- package/packages/dd-trace/src/git_properties.js +2 -0
- package/packages/dd-trace/src/guardrails/index.js +3 -4
- package/packages/dd-trace/src/guardrails/log.js +2 -2
- package/packages/dd-trace/src/guardrails/telemetry.js +16 -14
- package/packages/dd-trace/src/guardrails/util.js +0 -2
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +2 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +5 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/tool.js +15 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/vectorstore.js +36 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +47 -4
- package/packages/dd-trace/src/llmobs/tagger.js +10 -1
- package/packages/dd-trace/src/noop/dogstatsd.js +2 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +2 -0
- package/packages/dd-trace/src/payload-tagging/config/index.js +2 -0
- package/packages/dd-trace/src/payload-tagging/index.js +2 -0
- package/packages/dd-trace/src/payload-tagging/tagging.js +2 -0
- package/packages/dd-trace/src/plugins/apollo.js +2 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +8 -3
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +17 -7
- package/packages/dd-trace/src/plugins/util/env.js +2 -0
- package/packages/dd-trace/src/plugins/util/git.js +40 -5
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +2 -0
- package/packages/dd-trace/src/plugins/util/llm.js +2 -0
- package/packages/dd-trace/src/plugins/util/serverless.js +2 -0
- package/packages/dd-trace/src/plugins/util/stacktrace.js +178 -50
- package/packages/dd-trace/src/plugins/util/tags.js +19 -1
- package/packages/dd-trace/src/plugins/util/test.js +9 -4
- package/packages/dd-trace/src/plugins/util/url.js +2 -0
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +2 -0
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +4 -0
- package/packages/dd-trace/src/profiling/profiler.js +89 -70
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns.js +2 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookup.js +2 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_lookupservice.js +2 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_resolve.js +2 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/dns_reverse.js +2 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/event.js +2 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/fs.js +2 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/net.js +2 -0
- package/packages/dd-trace/src/profiling/profilers/events.js +2 -0
- package/packages/dd-trace/src/profiling/webspan-utils.js +2 -0
- package/packages/dd-trace/src/remote_config/capabilities.js +4 -1
- package/packages/dd-trace/src/remote_config/index.js +6 -0
- package/packages/dd-trace/src/service-naming/index.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/definition.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/util.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/graphql.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/index.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/serverless.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/graphql.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/index.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/serverless.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +2 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +2 -0
- package/packages/dd-trace/src/span_stats.js +2 -0
- package/packages/dd-trace/src/supported-configurations.json +2 -0
- package/packages/dd-trace/src/telemetry/send-data.js +2 -0
- package/register.js +4 -0
- package/version.js +0 -3
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const RouterPlugin = require('../../datadog-plugin-router/src')
|
|
4
|
+
const web = require('../../dd-trace/src/plugins/util/web')
|
|
5
|
+
|
|
6
|
+
class HonoPlugin extends RouterPlugin {
|
|
7
|
+
static get id () {
|
|
8
|
+
return 'hono'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
constructor (...args) {
|
|
12
|
+
super(...args)
|
|
13
|
+
|
|
14
|
+
this.addSub('apm:hono:request:handle', ({ req }) => {
|
|
15
|
+
this.setFramework(req, 'hono', this.config)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
this.addSub('apm:hono:request:route', ({ req, route }) => {
|
|
19
|
+
web.setRoute(req, route)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
this.addSub('apm:hono:request:error', ({ req, error }) => {
|
|
23
|
+
web.addError(req, error)
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = HonoPlugin
|
|
@@ -40,9 +40,14 @@ class BaseLangChainTracingPlugin extends TracingPlugin {
|
|
|
40
40
|
|
|
41
41
|
// Runnable interfaces have an `lc_namespace` property
|
|
42
42
|
const ns = ctx.self.lc_namespace || ctx.namespace
|
|
43
|
-
const resource = ctx.resource = [...ns, ctx.self.constructor.name].join('.')
|
|
44
43
|
|
|
45
|
-
const
|
|
44
|
+
const resourceParts = [...ns, ctx.self.constructor.name]
|
|
45
|
+
if (type === 'tool') {
|
|
46
|
+
resourceParts.push(ctx.instance.name)
|
|
47
|
+
}
|
|
48
|
+
const resource = ctx.resource = resourceParts.join('.')
|
|
49
|
+
|
|
50
|
+
const handler = this.handlers[type] || this.handlers.default
|
|
46
51
|
|
|
47
52
|
const instance = ctx.instance
|
|
48
53
|
const apiKey = handler.extractApiKey(instance)
|
|
@@ -78,7 +83,7 @@ class BaseLangChainTracingPlugin extends TracingPlugin {
|
|
|
78
83
|
|
|
79
84
|
const { type } = ctx
|
|
80
85
|
|
|
81
|
-
const handler = this.handlers[type]
|
|
86
|
+
const handler = this.handlers[type] || this.handlers.default
|
|
82
87
|
const tags = handler.getSpanEndTags(ctx, span) || {}
|
|
83
88
|
|
|
84
89
|
span.addTags(tags)
|
|
@@ -139,11 +144,38 @@ class EmbeddingsEmbedDocumentsPlugin extends BaseLangChainTracingPlugin {
|
|
|
139
144
|
}
|
|
140
145
|
}
|
|
141
146
|
|
|
147
|
+
class ToolInvokePlugin extends BaseLangChainTracingPlugin {
|
|
148
|
+
static get id () { return 'langchain_tool_invoke' }
|
|
149
|
+
static get lcType () { return 'tool' }
|
|
150
|
+
static get prefix () {
|
|
151
|
+
return 'tracing:orchestrion:@langchain/core:Tool_invoke'
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
class VectorStoreSimilaritySearchPlugin extends BaseLangChainTracingPlugin {
|
|
156
|
+
static get id () { return 'langchain_vectorstore_similarity_search' }
|
|
157
|
+
static get lcType () { return 'similarity_search' }
|
|
158
|
+
static get prefix () {
|
|
159
|
+
return 'tracing:orchestrion:@langchain/core:VectorStore_similaritySearch'
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
class VectorStoreSimilaritySearchWithScorePlugin extends BaseLangChainTracingPlugin {
|
|
164
|
+
static get id () { return 'langchain_vectorstore_similarity_search_with_score' }
|
|
165
|
+
static get lcType () { return 'similarity_search' }
|
|
166
|
+
static get prefix () {
|
|
167
|
+
return 'tracing:orchestrion:@langchain/core:VectorStore_similaritySearchWithScore'
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
142
171
|
module.exports = [
|
|
143
172
|
RunnableSequenceInvokePlugin,
|
|
144
173
|
RunnableSequenceBatchPlugin,
|
|
145
174
|
BaseChatModelGeneratePlugin,
|
|
146
175
|
BaseLLMGeneratePlugin,
|
|
147
176
|
EmbeddingsEmbedQueryPlugin,
|
|
148
|
-
EmbeddingsEmbedDocumentsPlugin
|
|
177
|
+
EmbeddingsEmbedDocumentsPlugin,
|
|
178
|
+
ToolInvokePlugin,
|
|
179
|
+
VectorStoreSimilaritySearchPlugin,
|
|
180
|
+
VectorStoreSimilaritySearchWithScorePlugin
|
|
149
181
|
]
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Combines legacy OpenAI streamed chunks into a single object.
|
|
5
|
+
* These legacy chunks are returned as buffers instead of individual objects.
|
|
6
|
+
* @param {readonly Uint8Array[]} chunks
|
|
7
|
+
* @returns {Array<Record<string, any>>}
|
|
8
|
+
*/
|
|
9
|
+
function convertBuffersToObjects (chunks) {
|
|
10
|
+
return Buffer
|
|
11
|
+
.concat(chunks) // combine the buffers
|
|
12
|
+
.toString() // stringify
|
|
13
|
+
.split(/(?=data:)/) // split on "data:"
|
|
14
|
+
.map(chunk => chunk.replaceAll('\n', '').slice(6)) // remove newlines and 'data: ' from the front
|
|
15
|
+
.slice(0, -1) // remove the last [DONE] message
|
|
16
|
+
.map(JSON.parse) // parse all of the returned objects
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Common function for combining chunks with n choices into a single response body.
|
|
21
|
+
* The shared logic will add a new choice index entry if it doesn't exist, and otherwise
|
|
22
|
+
* hand off to a onChoice handler to add that choice to the previously stored choice.
|
|
23
|
+
*
|
|
24
|
+
* @param {Array<Record<string, any>>} chunks
|
|
25
|
+
* @param {number} n
|
|
26
|
+
* @param {function(Record<string, any>, Record<string, any>): void} onChoice
|
|
27
|
+
* @returns {Record<string, any>}
|
|
28
|
+
*/
|
|
29
|
+
function constructResponseFromStreamedChunks (chunks, n, onChoice) {
|
|
30
|
+
const body = { ...chunks[0], choices: Array.from({ length: n }) }
|
|
31
|
+
|
|
32
|
+
for (const chunk of chunks) {
|
|
33
|
+
body.usage = chunk.usage
|
|
34
|
+
for (const choice of chunk.choices) {
|
|
35
|
+
const choiceIdx = choice.index
|
|
36
|
+
const oldChoice = body.choices.find(choice => choice?.index === choiceIdx)
|
|
37
|
+
|
|
38
|
+
if (!oldChoice) {
|
|
39
|
+
body.choices[choiceIdx] = choice
|
|
40
|
+
continue
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!oldChoice.finish_reason) {
|
|
44
|
+
oldChoice.finish_reason = choice.finish_reason
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
onChoice(choice, oldChoice)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return body
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Constructs the entire response from a stream of OpenAI completion chunks,
|
|
56
|
+
* mainly combining the text choices of each chunk into a single string per choice.
|
|
57
|
+
* @param {Array<Record<string, any>>} chunks
|
|
58
|
+
* @param {number} n the number of choices to expect in the response
|
|
59
|
+
* @returns {Record<string, any>}
|
|
60
|
+
*/
|
|
61
|
+
function constructCompletionResponseFromStreamedChunks (chunks, n) {
|
|
62
|
+
return constructResponseFromStreamedChunks(chunks, n, (choice, oldChoice) => {
|
|
63
|
+
const text = choice.text
|
|
64
|
+
if (text) {
|
|
65
|
+
if (oldChoice.text) {
|
|
66
|
+
oldChoice.text += text
|
|
67
|
+
} else {
|
|
68
|
+
oldChoice.text = text
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Constructs the entire response from a stream of OpenAI chat completion chunks,
|
|
76
|
+
* mainly combining the text choices of each chunk into a single string per choice.
|
|
77
|
+
* @param {Array<Record<string, any>>} chunks
|
|
78
|
+
* @param {number} n the number of choices to expect in the response
|
|
79
|
+
* @returns {Record<string, any>}
|
|
80
|
+
*/
|
|
81
|
+
function constructChatCompletionResponseFromStreamedChunks (chunks, n) {
|
|
82
|
+
return constructResponseFromStreamedChunks(chunks, n, (choice, oldChoice) => {
|
|
83
|
+
const delta = choice.delta
|
|
84
|
+
if (!delta) return
|
|
85
|
+
|
|
86
|
+
const content = delta.content
|
|
87
|
+
if (content) {
|
|
88
|
+
if (oldChoice.delta.content) {
|
|
89
|
+
oldChoice.delta.content += content
|
|
90
|
+
} else {
|
|
91
|
+
oldChoice.delta.content = content
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const tools = delta.tool_calls
|
|
96
|
+
if (!tools) return
|
|
97
|
+
|
|
98
|
+
oldChoice.delta.tool_calls = tools.map((newTool, toolIdx) => {
|
|
99
|
+
const oldTool = oldChoice.delta.tool_calls?.[toolIdx]
|
|
100
|
+
if (oldTool) {
|
|
101
|
+
oldTool.function.arguments += newTool.function.arguments
|
|
102
|
+
return oldTool
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return newTool
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
module.exports = {
|
|
111
|
+
convertBuffersToObjects,
|
|
112
|
+
constructCompletionResponseFromStreamedChunks,
|
|
113
|
+
constructChatCompletionResponseFromStreamedChunks
|
|
114
|
+
}
|
|
@@ -10,6 +10,11 @@ const { MEASURED } = require('../../../ext/tags')
|
|
|
10
10
|
const { estimateTokens } = require('./token-estimator')
|
|
11
11
|
|
|
12
12
|
const makeUtilities = require('../../dd-trace/src/plugins/util/llm')
|
|
13
|
+
const {
|
|
14
|
+
convertBuffersToObjects,
|
|
15
|
+
constructCompletionResponseFromStreamedChunks,
|
|
16
|
+
constructChatCompletionResponseFromStreamedChunks
|
|
17
|
+
} = require('./stream-helpers')
|
|
13
18
|
|
|
14
19
|
let normalize
|
|
15
20
|
|
|
@@ -48,6 +53,39 @@ class OpenAiTracingPlugin extends TracingPlugin {
|
|
|
48
53
|
|
|
49
54
|
normalize = utilities.normalize
|
|
50
55
|
}
|
|
56
|
+
|
|
57
|
+
this.addSub('apm:openai:request:chunk', ({ ctx, chunk, done }) => {
|
|
58
|
+
if (!ctx.chunks) ctx.chunks = []
|
|
59
|
+
|
|
60
|
+
if (chunk) ctx.chunks.push(chunk)
|
|
61
|
+
if (!done) return
|
|
62
|
+
|
|
63
|
+
let chunks = ctx.chunks
|
|
64
|
+
if (chunks.length === 0) return
|
|
65
|
+
|
|
66
|
+
const firstChunk = chunks[0]
|
|
67
|
+
// OpenAI in legacy versions returns chunked buffers instead of objects.
|
|
68
|
+
// These buffers will need to be combined and coalesced into a list of object chunks.
|
|
69
|
+
if (firstChunk instanceof Buffer) {
|
|
70
|
+
chunks = convertBuffersToObjects(chunks)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const methodName = ctx.currentStore.normalizedMethodName
|
|
74
|
+
let n = 1
|
|
75
|
+
const prompt = ctx.args[0].prompt
|
|
76
|
+
if (Array.isArray(prompt) && typeof prompt[0] !== 'number') {
|
|
77
|
+
n *= prompt.length
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let response = {}
|
|
81
|
+
if (methodName === 'createCompletion') {
|
|
82
|
+
response = constructCompletionResponseFromStreamedChunks(chunks, n)
|
|
83
|
+
} else if (methodName === 'createChatCompletion') {
|
|
84
|
+
response = constructChatCompletionResponseFromStreamedChunks(chunks, n)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
ctx.result = { data: response }
|
|
88
|
+
})
|
|
51
89
|
}
|
|
52
90
|
|
|
53
91
|
configure (config) {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
1
3
|
const IAST_CONTEXT_KEY = Symbol('_dd.iast.context')
|
|
2
4
|
const IAST_TRANSACTION_ID = Symbol('_dd.iast.transactionId')
|
|
3
5
|
|
|
@@ -52,7 +54,9 @@ function cleanIastContext (store, context, iastContext) {
|
|
|
52
54
|
context[IAST_CONTEXT_KEY] = null
|
|
53
55
|
}
|
|
54
56
|
if (iastContext) {
|
|
55
|
-
|
|
57
|
+
if (typeof iastContext === 'object') { // eslint-disable-line eslint-rules/eslint-safe-typeof-object
|
|
58
|
+
Object.keys(iastContext).forEach(key => delete iastContext[key])
|
|
59
|
+
}
|
|
56
60
|
return true
|
|
57
61
|
}
|
|
58
62
|
return false
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
1
3
|
// eslint-disable-next-line @stylistic/max-len
|
|
2
4
|
const DEFAULT_IAST_REDACTION_NAME_PATTERN = '(?:p(?:ass)?w(?:or)?d|pass(?:_?phrase)?|secret|(?:api_?|private_?|public_?|access_?|secret_?)key(?:_?id)?|token|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?|(?:sur|last)name|user(?:name)?|address|e?mail)'
|
|
3
5
|
// eslint-disable-next-line @stylistic/max-len
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const { LRUCache } = require('lru-cache')
|
|
4
4
|
const vulnerabilitiesFormatter = require('./vulnerabilities-formatter')
|
|
5
5
|
const { IAST_ENABLED_TAG_KEY, IAST_JSON_TAG_KEY } = require('./tags')
|
|
6
6
|
const { keepTrace } = require('../../priority_sampler')
|
|
@@ -10,7 +10,7 @@ const { ASM } = require('../../standalone/product')
|
|
|
10
10
|
|
|
11
11
|
const VULNERABILITIES_KEY = 'vulnerabilities'
|
|
12
12
|
const VULNERABILITY_HASHES_MAX_SIZE = 1000
|
|
13
|
-
const VULNERABILITY_HASHES = new
|
|
13
|
+
const VULNERABILITY_HASHES = new LRUCache({ max: VULNERABILITY_HASHES_MAX_SIZE })
|
|
14
14
|
const RESET_VULNERABILITY_CACHE_INTERVAL = 60 * 60 * 1000 // 1 hour
|
|
15
15
|
|
|
16
16
|
let tracer
|
|
@@ -114,7 +114,7 @@ function isDuplicatedVulnerability (vulnerability) {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
function getVulnerabilityCallSiteFrames () {
|
|
117
|
-
return getCallsiteFrames(stackTraceMaxDepth)
|
|
117
|
+
return getCallsiteFrames(stackTraceMaxDepth, getVulnerabilityCallSiteFrames)
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
function replaceCallSiteFromSourceMap (callsite) {
|
|
@@ -14,25 +14,31 @@ const enabledFor = {
|
|
|
14
14
|
|
|
15
15
|
let fsPlugin
|
|
16
16
|
|
|
17
|
-
function
|
|
17
|
+
function getStoreToStart (fsProps, store = storage('legacy').getStore()) {
|
|
18
18
|
if (store && !store.fs?.opExcluded) {
|
|
19
|
-
|
|
19
|
+
return {
|
|
20
20
|
...store,
|
|
21
21
|
fs: {
|
|
22
22
|
...store.fs,
|
|
23
23
|
...fsProps,
|
|
24
24
|
parentStore: store
|
|
25
25
|
}
|
|
26
|
-
}
|
|
26
|
+
}
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
return store
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
class AppsecFsPlugin extends Plugin {
|
|
31
33
|
enable () {
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
35
|
-
this.
|
|
34
|
+
this.addBind('apm:fs:operation:start', this._onFsOperationStart)
|
|
35
|
+
this.addBind('apm:fs:operation:finish', this._onFsOperationFinishOrRenderEnd)
|
|
36
|
+
this.addBind('tracing:datadog:express:response:render:start', this._onResponseRenderStart)
|
|
37
|
+
this.addBind('tracing:datadog:express:response:render:end', this._onFsOperationFinishOrRenderEnd)
|
|
38
|
+
// TODO Remove this when dc-polyfill is fixed&updated
|
|
39
|
+
// hack to node 18 and early 20.x
|
|
40
|
+
// with dc-polyfill addBind is not enough to force a channel.hasSubscribers === true
|
|
41
|
+
this.addSub('tracing:datadog:express:response:render:start', () => {})
|
|
36
42
|
|
|
37
43
|
super.configure(true)
|
|
38
44
|
}
|
|
@@ -44,19 +50,20 @@ class AppsecFsPlugin extends Plugin {
|
|
|
44
50
|
_onFsOperationStart () {
|
|
45
51
|
const store = storage('legacy').getStore()
|
|
46
52
|
if (store) {
|
|
47
|
-
|
|
53
|
+
return getStoreToStart({ root: store.fs?.root === undefined }, store)
|
|
48
54
|
}
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
_onResponseRenderStart () {
|
|
52
|
-
|
|
58
|
+
return getStoreToStart({ opExcluded: true })
|
|
53
59
|
}
|
|
54
60
|
|
|
55
61
|
_onFsOperationFinishOrRenderEnd () {
|
|
56
62
|
const store = storage('legacy').getStore()
|
|
57
|
-
if (store?.fs
|
|
58
|
-
|
|
63
|
+
if (store?.fs) {
|
|
64
|
+
return store.fs.parentStore
|
|
59
65
|
}
|
|
66
|
+
return store
|
|
60
67
|
}
|
|
61
68
|
}
|
|
62
69
|
|
|
@@ -41,7 +41,7 @@ function handleResult (result, req, res, abortController, config, raspRule) {
|
|
|
41
41
|
const ruleTriggered = !!result?.events?.length
|
|
42
42
|
|
|
43
43
|
if (generateStackTraceAction && enabled && canReportStackTrace(rootSpan, maxStackTraces)) {
|
|
44
|
-
const frames = getCallsiteFrames(maxDepth)
|
|
44
|
+
const frames = getCallsiteFrames(maxDepth, handleResult)
|
|
45
45
|
|
|
46
46
|
reportStackTrace(
|
|
47
47
|
rootSpan,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "2.2",
|
|
3
3
|
"metadata": {
|
|
4
|
-
"rules_version": "1.
|
|
4
|
+
"rules_version": "1.15.0"
|
|
5
5
|
},
|
|
6
6
|
"rules": [
|
|
7
7
|
{
|
|
@@ -2985,7 +2985,7 @@
|
|
|
2985
2985
|
"address": "graphql.server.resolver"
|
|
2986
2986
|
}
|
|
2987
2987
|
],
|
|
2988
|
-
"regex": "\\b(?:(?:l(?:(?:utimes|chmod)(?:Sync)?|(?:stat|ink)Sync)|w(?:rite(?:(?:File|v)(?:Sync)?|Sync)|atchFile)|u(?:n(?:watchFile|linkSync)|times(?:Sync)?)|s(?:(?:ymlink|tat)Sync|pawn(?:File|Sync))|ex(?:ec(?:File(?:Sync)?|Sync)|istsSync)|a(?:ppendFile|ccess)(?:Sync)?|(?:Caveat|Inode)s|open(?:dir)?Sync|new\\s+Function|Availability|\\beval)\\s*\\(|m(?:ain(?:Module\\s*(?:\\W*\\s*(?:constructor|require)|\\[)|\\s*(?:\\W*\\s*(?:constructor|require)|\\[))|kd(?:temp(?:Sync)?|irSync)\\s*\\(|odule\\.exports\\s*=)|c(?:(?:(?:h(?:mod|own)|lose)Sync|reate(?:Write|Read)Stream|p(?:Sync)?)\\s*\\(|o(?:nstructor\\s*(?:\\W*\\s*_load|\\[)|pyFile(?:Sync)?\\s*\\())|f(?:(?:(?:s(?:(?:yncS)?|tatS)|datas(?:yncS)?)ync|ch(?:mod|own)(?:Sync)?)\\s*\\(|u(?:nction\\s*\\(\\s*\\)\\s*{|times(?:Sync)?\\s*\\())|r(?:e(?:(?:ad(?:(?:File|link|dir)?Sync|v(?:Sync)?)|nameSync)\\s*\\(|quire\\s*(?:\\W*\\s*main|\\[))|m(?:Sync)?\\s*\\()|process\\s*(?:\\W*\\s*(?:mainModule|binding)|\\[)|t(?:his\\.constructor|runcateSync\\s*\\()|_(?:\\$\\$ND_FUNC\\$\\$_|_js_function)|global\\s*(?:\\W*\\s*process|\\[)|String\\s*\\.\\s*fromCharCode|binding\\s*\\[)",
|
|
2988
|
+
"regex": "\\b(?:(?:l(?:(?:utimes|chmod)(?:Sync)?|(?:stat|ink)Sync)|w(?:rite(?:(?:File|v)(?:Sync)?|Sync)|atchFile)|u(?:n(?:watchFile|linkSync)|times(?:Sync)?)|s(?:(?:ymlink|tat)Sync|pawn(?:File|Sync))|ex(?:ec(?:File(?:Sync)?|Sync)|istsSync)|a(?:ppendFile|ccess)(?:Sync)?|(?:Caveat|Inode)s|open(?:dir)?Sync|new\\s+Function|Availability|\\beval)\\s*\\(|m(?:ain(?:Module\\s*(?:\\W*\\s*(?:constructor|require)|\\[)|\\s*(?:\\W*\\s*(?:constructor|require)|\\[))|kd(?:temp(?:Sync)?|irSync)\\s*\\(|odule\\.exports\\s*=)|c(?:(?:(?:h(?:mod|own)|lose)Sync|reate(?:Write|Read)Stream|p(?:Sync)?)\\s*\\(|o(?:nstructor\\s*(?:\\W*\\s*_load|\\[)|pyFile(?:Sync)?\\s*\\())|f(?:(?:(?:s(?:(?:yncS)?|tatS)|datas(?:yncS)?)ync|ch(?:mod|own)(?:Sync)?)\\s*\\(|u(?:nction\\s*\\(\\s*\\)\\s*{|times(?:Sync)?\\s*\\())|r(?:e(?:(?:ad(?:(?:File|link|dir)?Sync|v(?:Sync)?)|nameSync)\\s*\\(|quire\\s*(?:\\W*\\s*main\\b|\\[))|m(?:Sync)?\\s*\\()|process\\s*(?:\\W*\\s*(?:mainModule|binding)|\\[)|t(?:his\\.constructor|runcateSync\\s*\\()|_(?:\\$\\$ND_FUNC\\$\\$_|_js_function)|global\\s*(?:\\W*\\s*process|\\[)|String\\s*\\.\\s*fromCharCode|binding\\s*\\[)",
|
|
2989
2989
|
"options": {
|
|
2990
2990
|
"case_sensitive": true,
|
|
2991
2991
|
"min_length": 3
|
|
@@ -5656,6 +5656,52 @@
|
|
|
5656
5656
|
],
|
|
5657
5657
|
"transformers": []
|
|
5658
5658
|
},
|
|
5659
|
+
{
|
|
5660
|
+
"id": "dog-932-110",
|
|
5661
|
+
"name": "Python: Subprocess-based command injection",
|
|
5662
|
+
"tags": {
|
|
5663
|
+
"type": "command_injection",
|
|
5664
|
+
"category": "attack_attempt",
|
|
5665
|
+
"confidence": "0",
|
|
5666
|
+
"module": "waf"
|
|
5667
|
+
},
|
|
5668
|
+
"conditions": [
|
|
5669
|
+
{
|
|
5670
|
+
"parameters": {
|
|
5671
|
+
"inputs": [
|
|
5672
|
+
{
|
|
5673
|
+
"address": "server.request.query"
|
|
5674
|
+
},
|
|
5675
|
+
{
|
|
5676
|
+
"address": "server.request.body"
|
|
5677
|
+
},
|
|
5678
|
+
{
|
|
5679
|
+
"address": "server.request.path_params"
|
|
5680
|
+
},
|
|
5681
|
+
{
|
|
5682
|
+
"address": "server.request.headers.no_cookies"
|
|
5683
|
+
},
|
|
5684
|
+
{
|
|
5685
|
+
"address": "grpc.server.request.message"
|
|
5686
|
+
},
|
|
5687
|
+
{
|
|
5688
|
+
"address": "graphql.server.all_resolvers"
|
|
5689
|
+
},
|
|
5690
|
+
{
|
|
5691
|
+
"address": "graphql.server.resolver"
|
|
5692
|
+
}
|
|
5693
|
+
],
|
|
5694
|
+
"regex": "(?s)\\bsubprocess\\b.*\\b(?:check_output|run|Popen|call|check_call)\\b",
|
|
5695
|
+
"options": {
|
|
5696
|
+
"case_sensitive": true,
|
|
5697
|
+
"min_length": 14
|
|
5698
|
+
}
|
|
5699
|
+
},
|
|
5700
|
+
"operator": "match_regex"
|
|
5701
|
+
}
|
|
5702
|
+
],
|
|
5703
|
+
"transformers": []
|
|
5704
|
+
},
|
|
5659
5705
|
{
|
|
5660
5706
|
"id": "dog-934-001",
|
|
5661
5707
|
"name": "XXE - XML file loads external entity",
|
|
@@ -9074,6 +9120,28 @@
|
|
|
9074
9120
|
"evaluate": true,
|
|
9075
9121
|
"output": true
|
|
9076
9122
|
},
|
|
9123
|
+
{
|
|
9124
|
+
"id": "decode-auth-jwt",
|
|
9125
|
+
"generator": "jwt_decode",
|
|
9126
|
+
"min_version": "1.25.0",
|
|
9127
|
+
"parameters": {
|
|
9128
|
+
"mappings": [
|
|
9129
|
+
{
|
|
9130
|
+
"inputs": [
|
|
9131
|
+
{
|
|
9132
|
+
"address": "server.request.headers.no_cookies",
|
|
9133
|
+
"key_path": [
|
|
9134
|
+
"authorization"
|
|
9135
|
+
]
|
|
9136
|
+
}
|
|
9137
|
+
],
|
|
9138
|
+
"output": "server.request.jwt"
|
|
9139
|
+
}
|
|
9140
|
+
]
|
|
9141
|
+
},
|
|
9142
|
+
"evaluate": true,
|
|
9143
|
+
"output": false
|
|
9144
|
+
},
|
|
9077
9145
|
{
|
|
9078
9146
|
"id": "http-network-fingerprint",
|
|
9079
9147
|
"generator": "http_network_fingerprint",
|
|
@@ -9918,6 +9986,24 @@
|
|
|
9918
9986
|
"category": "payment"
|
|
9919
9987
|
}
|
|
9920
9988
|
},
|
|
9989
|
+
{
|
|
9990
|
+
"id": "c542c147-3883-43d6-a067-178e4a7bd65d",
|
|
9991
|
+
"name": "Password",
|
|
9992
|
+
"key": {
|
|
9993
|
+
"operator": "match_regex",
|
|
9994
|
+
"parameters": {
|
|
9995
|
+
"regex": "\\bpass(?:[_-]?word|wd)?\\b|\\bpwd\\b",
|
|
9996
|
+
"options": {
|
|
9997
|
+
"case_sensitive": false,
|
|
9998
|
+
"min_length": 3
|
|
9999
|
+
}
|
|
10000
|
+
}
|
|
10001
|
+
},
|
|
10002
|
+
"tags": {
|
|
10003
|
+
"type": "password",
|
|
10004
|
+
"category": "credentials"
|
|
10005
|
+
}
|
|
10006
|
+
},
|
|
9921
10007
|
{
|
|
9922
10008
|
"id": "18b608bd7a764bff5b2344c0",
|
|
9923
10009
|
"name": "Phone number",
|