dd-trace 5.97.0 → 5.99.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 +0 -1
- package/ext/tags.js +1 -0
- package/index.d.ts +35 -3
- package/package.json +48 -46
- package/packages/datadog-instrumentations/src/crypto.js +45 -0
- package/packages/datadog-instrumentations/src/cucumber.js +65 -3
- package/packages/datadog-instrumentations/src/cypress-config.js +153 -53
- package/packages/datadog-instrumentations/src/dns.js +24 -56
- package/packages/datadog-instrumentations/src/graphql.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +74 -0
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +4 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +10 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/modelcontextprotocol-sdk.js +59 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +11 -2
- package/packages/datadog-instrumentations/src/jest.js +104 -12
- package/packages/datadog-instrumentations/src/mocha/utils.js +8 -0
- package/packages/datadog-instrumentations/src/modelcontextprotocol-sdk.js +7 -0
- package/packages/datadog-instrumentations/src/pino.js +4 -28
- package/packages/datadog-instrumentations/src/playwright-browser-scripts.js +27 -0
- package/packages/datadog-instrumentations/src/playwright.js +5 -17
- package/packages/datadog-instrumentations/src/redis.js +12 -6
- package/packages/datadog-instrumentations/src/stripe.js +38 -24
- package/packages/datadog-instrumentations/src/vitest.js +32 -4
- package/packages/datadog-instrumentations/src/zlib.js +29 -0
- package/packages/datadog-plugin-aws-sdk/src/base.js +2 -3
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -0
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +8 -15
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +4 -9
- package/packages/datadog-plugin-cucumber/src/index.js +8 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +114 -6
- package/packages/datadog-plugin-cypress/src/index.js +59 -2
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +48 -1
- package/packages/datadog-plugin-fs/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +2 -7
- package/packages/datadog-plugin-http/src/client.js +1 -1
- package/packages/datadog-plugin-http/src/server.js +21 -13
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-http2/src/server.js +10 -2
- package/packages/datadog-plugin-jest/src/index.js +2 -2
- package/packages/datadog-plugin-mocha/src/index.js +1 -2
- package/packages/datadog-plugin-modelcontextprotocol-sdk/src/index.js +24 -0
- package/packages/datadog-plugin-modelcontextprotocol-sdk/src/tracing.js +55 -0
- package/packages/datadog-plugin-mongodb-core/src/index.js +4 -9
- package/packages/datadog-plugin-mysql/src/index.js +1 -1
- package/packages/datadog-plugin-next/src/index.js +8 -2
- package/packages/datadog-plugin-pg/src/index.js +1 -1
- package/packages/datadog-plugin-playwright/src/index.js +2 -3
- package/packages/datadog-plugin-tedious/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +14 -6
- package/packages/datadog-plugin-ws/src/close.js +3 -1
- package/packages/datadog-plugin-ws/src/producer.js +2 -0
- package/packages/datadog-plugin-ws/src/receiver.js +2 -1
- package/packages/dd-trace/src/aiguard/channels.js +8 -0
- package/packages/dd-trace/src/aiguard/index.js +7 -3
- package/packages/dd-trace/src/aiguard/sdk.js +66 -22
- package/packages/dd-trace/src/aiguard/tags.js +1 -0
- package/packages/dd-trace/src/appsec/blocked_templates.js +4 -3
- package/packages/dd-trace/src/appsec/blocking.js +62 -34
- package/packages/dd-trace/src/appsec/graphql.js +6 -6
- package/packages/dd-trace/src/appsec/index.js +9 -11
- package/packages/dd-trace/src/appsec/rasp/command_injection.js +4 -5
- package/packages/dd-trace/src/appsec/rasp/lfi.js +8 -4
- package/packages/dd-trace/src/appsec/rasp/sql_injection.js +5 -10
- package/packages/dd-trace/src/appsec/rasp/ssrf.js +5 -6
- package/packages/dd-trace/src/appsec/recommended.json +2438 -13
- package/packages/dd-trace/src/appsec/reporter.js +6 -5
- package/packages/dd-trace/src/appsec/sdk/set_user.js +1 -1
- package/packages/dd-trace/src/appsec/sdk/track_event.js +5 -5
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +6 -10
- package/packages/dd-trace/src/appsec/sdk/utils.js +4 -2
- package/packages/dd-trace/src/appsec/store.js +50 -0
- package/packages/dd-trace/src/appsec/waf/index.js +3 -5
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +3 -4
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -2
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -5
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +3 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +6 -6
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +2 -2
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -2
- package/packages/dd-trace/src/config/config-types.d.ts +0 -4
- package/packages/dd-trace/src/config/defaults.js +10 -11
- package/packages/dd-trace/src/config/generated-config-types.d.ts +14 -8
- package/packages/dd-trace/src/config/index.js +49 -32
- package/packages/dd-trace/src/config/parsers.js +26 -9
- package/packages/dd-trace/src/config/supported-configurations.json +86 -33
- package/packages/dd-trace/src/constants.js +1 -0
- package/packages/dd-trace/src/debugger/config.js +2 -0
- package/packages/dd-trace/src/debugger/devtools_client/send.js +25 -5
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +5 -2
- package/packages/dd-trace/src/encode/0.4.js +11 -11
- package/packages/dd-trace/src/encode/span-stats.js +4 -1
- package/packages/dd-trace/src/exporters/agent/index.js +0 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +1 -2
- package/packages/dd-trace/src/exporters/agentless/writer.js +3 -3
- package/packages/dd-trace/src/exporters/common/util.js +2 -2
- package/packages/dd-trace/src/id.js +2 -0
- package/packages/dd-trace/src/index.js +2 -5
- package/packages/dd-trace/src/lambda/handler.js +1 -3
- package/packages/dd-trace/src/llmobs/plugins/{anthropic.js → anthropic/index.js} +5 -63
- package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +106 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +3 -2
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +3 -2
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/embedding.js +2 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +0 -49
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/vectorstore.js +2 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/messages.js +76 -0
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -26
- package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/index.js +68 -0
- package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +57 -0
- package/packages/dd-trace/src/llmobs/sdk.js +2 -2
- package/packages/dd-trace/src/log/index.js +0 -10
- package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +103 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +3 -0
- package/packages/dd-trace/src/openfeature/remote_config.js +6 -1
- package/packages/dd-trace/src/opentelemetry/context_manager.js +6 -4
- package/packages/dd-trace/src/opentelemetry/logs/index.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +3 -2
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +3 -2
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +19 -51
- package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +14 -2
- package/packages/dd-trace/src/opentelemetry/otlp/trace.proto +358 -0
- package/packages/dd-trace/src/opentelemetry/otlp/trace_service.proto +78 -0
- package/packages/dd-trace/src/opentelemetry/trace/index.js +70 -0
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +74 -0
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +342 -0
- package/packages/dd-trace/src/opentelemetry/tracer.js +9 -11
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +17 -10
- package/packages/dd-trace/src/opentracing/span.js +1 -1
- package/packages/dd-trace/src/opentracing/tracer.js +17 -5
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +3 -0
- package/packages/dd-trace/src/plugins/plugin.js +6 -11
- package/packages/dd-trace/src/plugins/storage.js +2 -2
- package/packages/dd-trace/src/plugins/tracing.js +22 -5
- package/packages/dd-trace/src/plugins/util/test.js +128 -5
- package/packages/dd-trace/src/plugins/util/url.js +2 -1
- package/packages/dd-trace/src/plugins/util/web.js +6 -88
- package/packages/dd-trace/src/profiling/profiler.js +34 -77
- package/packages/dd-trace/src/profiling/profilers/event_plugins/crypto.js +32 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/zlib.js +19 -0
- package/packages/dd-trace/src/profiling/profilers/events.js +35 -0
- package/packages/dd-trace/src/proxy.js +3 -4
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +17 -13
- package/packages/dd-trace/src/service-naming/index.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/definition.js +4 -1
- package/packages/dd-trace/src/service-naming/schemas/util.js +15 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +24 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +60 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +21 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/websocket.js +5 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +17 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +15 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/websocket.js +6 -0
- package/packages/dd-trace/src/span_processor.js +1 -2
- package/packages/dd-trace/src/span_stats.js +5 -1
- package/packages/dd-trace/src/tagger.js +2 -2
- package/packages/dd-trace/src/telemetry/send-data.js +5 -7
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +28 -6
- package/vendor/dist/protobufjs/index.js +1 -1
- package/packages/dd-trace/src/log/utils.js +0 -16
- package/vendor/dist/ignore/LICENSE +0 -21
- package/vendor/dist/ignore/index.js +0 -1
|
@@ -9,7 +9,6 @@ const { getEnvironmentVariable } = require('../../config/helper')
|
|
|
9
9
|
const satisfies = require('../../../../../vendor/dist/semifies')
|
|
10
10
|
|
|
11
11
|
const istanbul = require('../../../../../vendor/dist/istanbul-lib-coverage')
|
|
12
|
-
const ignore = require('../../../../../vendor/dist/ignore')
|
|
13
12
|
|
|
14
13
|
const id = require('../../id')
|
|
15
14
|
const {
|
|
@@ -137,6 +136,7 @@ const JEST_WORKER_TRACE_PAYLOAD_CODE = 60
|
|
|
137
136
|
const JEST_WORKER_COVERAGE_PAYLOAD_CODE = 61
|
|
138
137
|
const JEST_WORKER_LOGS_PAYLOAD_CODE = 62
|
|
139
138
|
const JEST_WORKER_TELEMETRY_PAYLOAD_CODE = 63
|
|
139
|
+
const JEST_WORKER_QUARANTINE_PAYLOAD_CODE = 64
|
|
140
140
|
|
|
141
141
|
// cucumber worker variables
|
|
142
142
|
const CUCUMBER_WORKER_TRACE_PAYLOAD_CODE = 70
|
|
@@ -262,6 +262,7 @@ module.exports = {
|
|
|
262
262
|
JEST_WORKER_COVERAGE_PAYLOAD_CODE,
|
|
263
263
|
JEST_WORKER_LOGS_PAYLOAD_CODE,
|
|
264
264
|
JEST_WORKER_TELEMETRY_PAYLOAD_CODE,
|
|
265
|
+
JEST_WORKER_QUARANTINE_PAYLOAD_CODE,
|
|
265
266
|
CUCUMBER_WORKER_TRACE_PAYLOAD_CODE,
|
|
266
267
|
MOCHA_WORKER_TRACE_PAYLOAD_CODE,
|
|
267
268
|
PLAYWRIGHT_WORKER_TRACE_PAYLOAD_CODE,
|
|
@@ -669,24 +670,146 @@ function getCodeOwnersFileEntries (rootDir) {
|
|
|
669
670
|
const trimmed = content.trim()
|
|
670
671
|
if (trimmed === '') continue
|
|
671
672
|
const [pattern, ...owners] = trimmed.split(/\s+/)
|
|
672
|
-
entries.push({ pattern, owners })
|
|
673
|
+
entries.push(setCodeOwnersPatternRegex({ pattern, owners }))
|
|
673
674
|
}
|
|
674
675
|
// Reverse because rules defined last take precedence
|
|
675
676
|
return entries.reverse()
|
|
676
677
|
}
|
|
677
678
|
|
|
678
|
-
const
|
|
679
|
+
const codeOwnersPerEntries = new WeakMap()
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* @param {string} character
|
|
683
|
+
* @returns {string}
|
|
684
|
+
*/
|
|
685
|
+
function escapeRegexCharacter (character) {
|
|
686
|
+
return character.replaceAll(/[|\\{}()[\]^$+*?.]/g, String.raw`\$&`)
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* @param {string} pattern
|
|
691
|
+
* @returns {boolean}
|
|
692
|
+
*/
|
|
693
|
+
function hasUnescapedWildcard (pattern) {
|
|
694
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
695
|
+
const character = pattern[i]
|
|
696
|
+
if (character === '\\') {
|
|
697
|
+
i++
|
|
698
|
+
} else if (character === '*' || character === '?') {
|
|
699
|
+
return true
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
return false
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* @param {string} pattern
|
|
707
|
+
* @returns {string}
|
|
708
|
+
*/
|
|
709
|
+
function codeOwnersPatternToRegexSource (pattern) {
|
|
710
|
+
let source = ''
|
|
711
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
712
|
+
const character = pattern[i]
|
|
713
|
+
|
|
714
|
+
if (character === '\\') {
|
|
715
|
+
const escapedCharacter = pattern[i + 1]
|
|
716
|
+
source += escapedCharacter === undefined
|
|
717
|
+
? escapeRegexCharacter(character)
|
|
718
|
+
: escapeRegexCharacter(escapedCharacter)
|
|
719
|
+
i++
|
|
720
|
+
} else if (character === '*') {
|
|
721
|
+
if (pattern[i + 1] === '*') {
|
|
722
|
+
if (pattern[i + 2] === '/') {
|
|
723
|
+
source += '(?:.*/)?'
|
|
724
|
+
i += 2
|
|
725
|
+
} else {
|
|
726
|
+
source += '.*'
|
|
727
|
+
i++
|
|
728
|
+
}
|
|
729
|
+
} else {
|
|
730
|
+
source += '[^/]*'
|
|
731
|
+
}
|
|
732
|
+
} else if (character === '?') {
|
|
733
|
+
source += '[^/]'
|
|
734
|
+
} else {
|
|
735
|
+
source += escapeRegexCharacter(character)
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
return source
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* @param {string} pattern
|
|
743
|
+
* @returns {RegExp|null}
|
|
744
|
+
*/
|
|
745
|
+
function getCodeOwnersPatternRegex (pattern) {
|
|
746
|
+
if (!pattern || pattern[0] === '!') {
|
|
747
|
+
return null
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
const directoryOnly = pattern.endsWith('/')
|
|
751
|
+
const normalizedPattern = pattern.replace(/^\/+/, '').replace(/\/+$/, '')
|
|
752
|
+
const anchored = pattern.startsWith('/') || normalizedPattern.includes('/')
|
|
753
|
+
|
|
754
|
+
if (!normalizedPattern) {
|
|
755
|
+
return null
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
const lastSlashIndex = normalizedPattern.lastIndexOf('/')
|
|
759
|
+
const lastSegment = lastSlashIndex === -1 ? normalizedPattern : normalizedPattern.slice(lastSlashIndex + 1)
|
|
760
|
+
const descendantSuffix = directoryOnly || !hasUnescapedWildcard(lastSegment) ? '(?:/.*)?' : ''
|
|
761
|
+
const patternSource = codeOwnersPatternToRegexSource(normalizedPattern)
|
|
762
|
+
const regexSource = anchored
|
|
763
|
+
? `^${patternSource}${descendantSuffix}$`
|
|
764
|
+
: `(?:^|/)${patternSource}${descendantSuffix}$`
|
|
765
|
+
|
|
766
|
+
return new RegExp(regexSource)
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
function setCodeOwnersPatternRegex (entry) {
|
|
770
|
+
Object.defineProperty(entry, 'regex', {
|
|
771
|
+
configurable: true,
|
|
772
|
+
value: getCodeOwnersPatternRegex(entry.pattern),
|
|
773
|
+
writable: true,
|
|
774
|
+
})
|
|
775
|
+
return entry
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* Match a repository-relative filename against a CODEOWNERS pattern.
|
|
780
|
+
* See GitHub's CODEOWNERS pattern rules:
|
|
781
|
+
* https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
|
|
782
|
+
*
|
|
783
|
+
* @param {RegExp|null} regex
|
|
784
|
+
* @param {string} filename
|
|
785
|
+
* @returns {boolean}
|
|
786
|
+
*/
|
|
787
|
+
function isCodeOwnersPatternMatch (regex, filename) {
|
|
788
|
+
if (!regex || !filename) {
|
|
789
|
+
return false
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
const normalizedFilename = filename.replaceAll('\\', '/').replace(/^\/+/, '')
|
|
793
|
+
return regex.test(normalizedFilename)
|
|
794
|
+
}
|
|
679
795
|
|
|
680
796
|
function getCodeOwnersForFilename (filename, entries) {
|
|
681
797
|
if (!entries) {
|
|
682
798
|
return null
|
|
683
799
|
}
|
|
684
|
-
|
|
800
|
+
let codeOwnersPerFileName = codeOwnersPerEntries.get(entries)
|
|
801
|
+
|
|
802
|
+
if (!codeOwnersPerFileName) {
|
|
803
|
+
codeOwnersPerFileName = new Map()
|
|
804
|
+
codeOwnersPerEntries.set(entries, codeOwnersPerFileName)
|
|
805
|
+
} else if (codeOwnersPerFileName.has(filename)) {
|
|
685
806
|
return codeOwnersPerFileName.get(filename)
|
|
686
807
|
}
|
|
808
|
+
|
|
687
809
|
for (const entry of entries) {
|
|
688
810
|
try {
|
|
689
|
-
const
|
|
811
|
+
const regex = entry.regex === undefined ? setCodeOwnersPatternRegex(entry).regex : entry.regex
|
|
812
|
+
const isResponsible = isCodeOwnersPatternMatch(regex, filename)
|
|
690
813
|
if (isResponsible) {
|
|
691
814
|
const codeOwners = JSON.stringify(entry.owners)
|
|
692
815
|
codeOwnersPerFileName.set(filename, codeOwners)
|
|
@@ -31,7 +31,8 @@ function extractURL (req) {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
function getProtocol (req) {
|
|
34
|
-
|
|
34
|
+
// Do not check deprecated `req.connection` property.
|
|
35
|
+
return req.socket?.encrypted ? 'https' : 'http'
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
/**
|
|
@@ -7,8 +7,9 @@ const log = require('../../log')
|
|
|
7
7
|
const tags = require('../../../../../ext/tags')
|
|
8
8
|
const types = require('../../../../../ext/types')
|
|
9
9
|
const kinds = require('../../../../../ext/kinds')
|
|
10
|
-
const { ERROR_MESSAGE
|
|
10
|
+
const { ERROR_MESSAGE } = require('../../constants')
|
|
11
11
|
const TracingPlugin = require('../tracing')
|
|
12
|
+
const { storage } = require('../../../../datadog-core')
|
|
12
13
|
const urlFilter = require('./urlfilter')
|
|
13
14
|
const { createInferredProxySpan, finishInferredProxySpan } = require('./inferred_proxy')
|
|
14
15
|
const { extractURL, obfuscateQs, calculateHttpEndpoint } = require('./url')
|
|
@@ -125,33 +126,13 @@ const web = {
|
|
|
125
126
|
context.tracer = tracer
|
|
126
127
|
context.span = span
|
|
127
128
|
context.res = res
|
|
129
|
+
context.store = storage('legacy').getStore()
|
|
128
130
|
|
|
129
131
|
this.setConfig(req, config)
|
|
130
132
|
addRequestTags(context, this.TYPE)
|
|
131
133
|
|
|
132
134
|
return span
|
|
133
135
|
},
|
|
134
|
-
wrap (req) {
|
|
135
|
-
const context = contexts.get(req)
|
|
136
|
-
if (!context.instrumented) {
|
|
137
|
-
this.wrapEnd(context)
|
|
138
|
-
context.instrumented = true
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
|
-
// Start a span and activate a scope for a request.
|
|
142
|
-
instrument (tracer, config, req, res, name, callback) {
|
|
143
|
-
const span = this.startSpan(tracer, config, req, res, name)
|
|
144
|
-
|
|
145
|
-
this.wrap(req)
|
|
146
|
-
|
|
147
|
-
return callback && tracer.scope().activate(span, () => callback(span))
|
|
148
|
-
},
|
|
149
|
-
|
|
150
|
-
// Reactivate the request scope in case it was changed by a middleware.
|
|
151
|
-
reactivate (req, fn) {
|
|
152
|
-
return reactivate(req, fn)
|
|
153
|
-
},
|
|
154
|
-
|
|
155
136
|
// Add a route segment that will be used for the resource name.
|
|
156
137
|
enterRoute (req, path) {
|
|
157
138
|
if (typeof path === 'string') {
|
|
@@ -172,61 +153,6 @@ const web = {
|
|
|
172
153
|
contexts.get(req).paths.pop()
|
|
173
154
|
},
|
|
174
155
|
|
|
175
|
-
// Start a new middleware span and activate a new scope with the span.
|
|
176
|
-
wrapMiddleware (req, middleware, name, fn) {
|
|
177
|
-
if (!this.active(req)) return fn()
|
|
178
|
-
|
|
179
|
-
const context = contexts.get(req)
|
|
180
|
-
const tracer = context.tracer
|
|
181
|
-
const childOf = this.active(req)
|
|
182
|
-
const config = context.config
|
|
183
|
-
const traceCtx = context.traceCtx
|
|
184
|
-
|
|
185
|
-
if (config.middleware === false) return this.bindAndWrapMiddlewareErrors(fn, req, tracer, childOf)
|
|
186
|
-
|
|
187
|
-
const span = startSpanHelper(tracer, name, { childOf }, traceCtx, config)
|
|
188
|
-
|
|
189
|
-
analyticsSampler.sample(span, config.measured)
|
|
190
|
-
|
|
191
|
-
span.addTags({
|
|
192
|
-
[RESOURCE_NAME]: middleware._name || middleware.name || '<anonymous>',
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
context.middleware.push(span)
|
|
196
|
-
|
|
197
|
-
return tracer.scope().activate(span, fn)
|
|
198
|
-
},
|
|
199
|
-
|
|
200
|
-
// catch errors and apply to active span
|
|
201
|
-
bindAndWrapMiddlewareErrors (fn, req, tracer, activeSpan) {
|
|
202
|
-
try {
|
|
203
|
-
return tracer.scope().bind(fn, activeSpan).apply(this, arguments)
|
|
204
|
-
} catch (e) {
|
|
205
|
-
web.addError(req, e) // TODO: remove when error formatting is moved to Span
|
|
206
|
-
throw e
|
|
207
|
-
}
|
|
208
|
-
},
|
|
209
|
-
|
|
210
|
-
// Finish the active middleware span.
|
|
211
|
-
finish (req, error) {
|
|
212
|
-
if (!this.active(req)) return
|
|
213
|
-
|
|
214
|
-
const context = contexts.get(req)
|
|
215
|
-
const span = context.middleware.pop()
|
|
216
|
-
|
|
217
|
-
if (span) {
|
|
218
|
-
if (error) {
|
|
219
|
-
span.addTags({
|
|
220
|
-
[ERROR_TYPE]: error.name,
|
|
221
|
-
[ERROR_MESSAGE]: error.message,
|
|
222
|
-
[ERROR_STACK]: error.stack,
|
|
223
|
-
})
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
span.finish()
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
|
|
230
156
|
// Register a callback to run before res.end() is called.
|
|
231
157
|
beforeEnd (req, callback) {
|
|
232
158
|
contexts.get(req).beforeEnd.push(callback)
|
|
@@ -278,7 +204,6 @@ const web = {
|
|
|
278
204
|
startServerlessSpanWithInferredProxy (tracer, config, name, req, traceCtx) {
|
|
279
205
|
const headers = req.headers
|
|
280
206
|
const reqCtx = contexts.get(req)
|
|
281
|
-
const { storage } = require('../../../../datadog-core')
|
|
282
207
|
const store = storage('legacy').getStore()
|
|
283
208
|
const pubsubSpan = store?.span?._name === 'pubsub.push.receive' ? store.span : null
|
|
284
209
|
|
|
@@ -391,7 +316,6 @@ const web = {
|
|
|
391
316
|
}
|
|
392
317
|
},
|
|
393
318
|
wrapEnd (context) {
|
|
394
|
-
const scope = context.tracer.scope()
|
|
395
319
|
const req = context.req
|
|
396
320
|
const res = context.res
|
|
397
321
|
const end = res.end
|
|
@@ -406,7 +330,9 @@ const web = {
|
|
|
406
330
|
return ends.get(this)
|
|
407
331
|
},
|
|
408
332
|
set (value) {
|
|
409
|
-
ends.set(this,
|
|
333
|
+
ends.set(this, function () {
|
|
334
|
+
return storage('legacy').run(context.store, value, ...arguments)
|
|
335
|
+
})
|
|
410
336
|
},
|
|
411
337
|
})
|
|
412
338
|
},
|
|
@@ -453,14 +379,6 @@ function splitHeader (str) {
|
|
|
453
379
|
return typeof str === 'string' ? str.split(/\s*,\s*/) : []
|
|
454
380
|
}
|
|
455
381
|
|
|
456
|
-
function reactivate (req, fn) {
|
|
457
|
-
const context = contexts.get(req)
|
|
458
|
-
|
|
459
|
-
return context
|
|
460
|
-
? context.tracer.scope().activate(context.span, fn)
|
|
461
|
-
: fn()
|
|
462
|
-
}
|
|
463
|
-
|
|
464
382
|
function addRequestTags (context, spanType) {
|
|
465
383
|
const { req, span, inferredProxySpan, config } = context
|
|
466
384
|
const url = extractURL(req)
|
|
@@ -12,12 +12,6 @@ const { isWebServerSpan, endpointNameFromTags, getStartedSpans } = require('./we
|
|
|
12
12
|
const profileSubmittedChannel = dc.channel('datadog:profiling:profile-submitted')
|
|
13
13
|
const spanFinishedChannel = dc.channel('dd-trace:span:finish')
|
|
14
14
|
|
|
15
|
-
function logError (logger, ...args) {
|
|
16
|
-
if (logger) {
|
|
17
|
-
logger.error(...args)
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
15
|
function findWebSpan (startedSpans, spanId) {
|
|
22
16
|
for (let i = startedSpans.length; --i >= 0;) {
|
|
23
17
|
const ispan = startedSpans[i]
|
|
@@ -71,33 +65,6 @@ class Profiler extends EventEmitter {
|
|
|
71
65
|
return this.#config?.flushInterval
|
|
72
66
|
}
|
|
73
67
|
|
|
74
|
-
/**
|
|
75
|
-
* @param {import('../config/config-base')} config - Tracer configuration
|
|
76
|
-
*/
|
|
77
|
-
start (config) {
|
|
78
|
-
// TODO: Unify with main logger and rewrite template strings to use printf formatting.
|
|
79
|
-
const logger = {
|
|
80
|
-
debug: log.debug.bind(log),
|
|
81
|
-
info: log.info.bind(log),
|
|
82
|
-
warn: log.warn.bind(log),
|
|
83
|
-
error: log.error.bind(log),
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// TODO: Rewrite this to not need to copy the config.
|
|
87
|
-
const options = {
|
|
88
|
-
...config,
|
|
89
|
-
logger,
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
try {
|
|
93
|
-
return this._start(options)
|
|
94
|
-
} catch (err) {
|
|
95
|
-
logError(logger, 'Error starting profiler. For troubleshooting tips, see ' +
|
|
96
|
-
'<https://dtdg.co/nodejs-profiler-troubleshooting>', err)
|
|
97
|
-
return false
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
68
|
get enabled () {
|
|
102
69
|
return this.#enabled
|
|
103
70
|
}
|
|
@@ -141,10 +108,6 @@ class Profiler extends EventEmitter {
|
|
|
141
108
|
return fn()
|
|
142
109
|
}
|
|
143
110
|
|
|
144
|
-
#logError (err) {
|
|
145
|
-
logError(this.#logger, err)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
111
|
#getCompressionFn () {
|
|
149
112
|
if (!this.#compressionFnInitialized) {
|
|
150
113
|
this.#compressionFnInitialized = true
|
|
@@ -181,8 +144,8 @@ class Profiler extends EventEmitter {
|
|
|
181
144
|
}
|
|
182
145
|
break
|
|
183
146
|
}
|
|
184
|
-
} catch (
|
|
185
|
-
|
|
147
|
+
} catch (error) {
|
|
148
|
+
log.error(error)
|
|
186
149
|
}
|
|
187
150
|
}
|
|
188
151
|
return this.#compressionFn
|
|
@@ -191,41 +154,36 @@ class Profiler extends EventEmitter {
|
|
|
191
154
|
/**
|
|
192
155
|
* @param {import('../config/config-base')} options - Tracer configuration
|
|
193
156
|
*/
|
|
194
|
-
|
|
157
|
+
start (options) {
|
|
195
158
|
if (this.enabled) return true
|
|
159
|
+
this.#enabled = true
|
|
196
160
|
|
|
197
161
|
const config = this.#config = new Config(options)
|
|
198
|
-
|
|
199
162
|
this.#logger = config.logger
|
|
200
|
-
this.#enabled = true
|
|
201
|
-
this._setInterval()
|
|
202
163
|
|
|
164
|
+
this._setInterval()
|
|
203
165
|
// Log errors if the source map finder fails, but don't prevent the rest
|
|
204
166
|
// of the profiler from running without source maps.
|
|
205
167
|
let mapper
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
.
|
|
224
|
-
|
|
225
|
-
})
|
|
226
|
-
}
|
|
227
|
-
} catch (err) {
|
|
228
|
-
this.#logError(err)
|
|
168
|
+
const { setLogger, SourceMapper } = require('@datadog/pprof')
|
|
169
|
+
setLogger(config.logger)
|
|
170
|
+
|
|
171
|
+
if (config.sourceMap) {
|
|
172
|
+
mapper = new SourceMapper(config.debugSourceMaps)
|
|
173
|
+
mapper.loadDirectory(process.cwd())
|
|
174
|
+
.then(() => {
|
|
175
|
+
if (config.debugSourceMaps) {
|
|
176
|
+
const count = mapper.infoMap.size
|
|
177
|
+
this.#logger.debug(() => {
|
|
178
|
+
return count === 0
|
|
179
|
+
? 'Found no source maps'
|
|
180
|
+
: `Found source maps for following files: [${[...mapper.infoMap.keys()].join(', ')}]`
|
|
181
|
+
})
|
|
182
|
+
}
|
|
183
|
+
})
|
|
184
|
+
.catch((error) => {
|
|
185
|
+
log.error(error)
|
|
186
|
+
})
|
|
229
187
|
}
|
|
230
188
|
|
|
231
189
|
try {
|
|
@@ -246,12 +204,13 @@ class Profiler extends EventEmitter {
|
|
|
246
204
|
}
|
|
247
205
|
|
|
248
206
|
this._capture(this._timeoutInterval, start)
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
this.#logError(e)
|
|
207
|
+
} catch (error) {
|
|
208
|
+
log.error(error)
|
|
252
209
|
this.#stop()
|
|
253
210
|
return false
|
|
254
211
|
}
|
|
212
|
+
|
|
213
|
+
return true
|
|
255
214
|
}
|
|
256
215
|
|
|
257
216
|
#nearOOMExport (profileType, encodedProfile, info) {
|
|
@@ -389,10 +348,10 @@ class Profiler extends EventEmitter {
|
|
|
389
348
|
return `Collected ${profiler.type} profile: ` + profileJson
|
|
390
349
|
})
|
|
391
350
|
hasEncoded = true
|
|
392
|
-
} catch (
|
|
351
|
+
} catch (error) {
|
|
393
352
|
// If encoding one of the profile types fails, we should still try to
|
|
394
353
|
// encode and submit the other profile types.
|
|
395
|
-
|
|
354
|
+
log.error(error)
|
|
396
355
|
}
|
|
397
356
|
}))
|
|
398
357
|
|
|
@@ -401,8 +360,8 @@ class Profiler extends EventEmitter {
|
|
|
401
360
|
profileSubmittedChannel.publish()
|
|
402
361
|
this.#logger.debug('Submitted profiles')
|
|
403
362
|
}
|
|
404
|
-
} catch (
|
|
405
|
-
|
|
363
|
+
} catch (error) {
|
|
364
|
+
log.error(error)
|
|
406
365
|
this.#stop()
|
|
407
366
|
}
|
|
408
367
|
}
|
|
@@ -424,10 +383,8 @@ class Profiler extends EventEmitter {
|
|
|
424
383
|
: undefined
|
|
425
384
|
const exportSpec = { profiles, infos, start, end, tags, endpointCounts, customAttributes }
|
|
426
385
|
const tasks = this.#config.exporters.map(exporter =>
|
|
427
|
-
exporter.export(exportSpec).catch(
|
|
428
|
-
|
|
429
|
-
this.#logger.warn(err)
|
|
430
|
-
}
|
|
386
|
+
exporter.export(exportSpec).catch(error => {
|
|
387
|
+
log.warn(error)
|
|
431
388
|
})
|
|
432
389
|
)
|
|
433
390
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const EventPlugin = require('./event')
|
|
4
|
+
|
|
5
|
+
// Params captured on the instrumentation context that are safe to forward as pprof labels. Must be
|
|
6
|
+
// a subset of the names declared in asyncParamsByMethod in datadog-instrumentations/src/crypto.js.
|
|
7
|
+
const allowedParams = new Set([
|
|
8
|
+
'algorithm', 'digest', 'iterations', 'keylen', 'offset', 'operation', 'size', 'type',
|
|
9
|
+
])
|
|
10
|
+
|
|
11
|
+
class CryptoPlugin extends EventPlugin {
|
|
12
|
+
static id = 'crypto'
|
|
13
|
+
|
|
14
|
+
static operation = 'operation'
|
|
15
|
+
|
|
16
|
+
static entryType = 'crypto'
|
|
17
|
+
|
|
18
|
+
extendEvent (event, ctx) {
|
|
19
|
+
const detail = {}
|
|
20
|
+
for (const name of allowedParams) {
|
|
21
|
+
const value = ctx[name]
|
|
22
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
23
|
+
detail[name] = value
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
event.detail = detail
|
|
27
|
+
|
|
28
|
+
return event
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = CryptoPlugin
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const EventPlugin = require('./event')
|
|
4
|
+
|
|
5
|
+
class ZlibPlugin extends EventPlugin {
|
|
6
|
+
static id = 'zlib'
|
|
7
|
+
|
|
8
|
+
static operation = 'operation'
|
|
9
|
+
|
|
10
|
+
static entryType = 'zlib'
|
|
11
|
+
|
|
12
|
+
extendEvent (event, ctx) {
|
|
13
|
+
event.detail = { operation: ctx.operation }
|
|
14
|
+
|
|
15
|
+
return event
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = ZlibPlugin
|
|
@@ -194,13 +194,46 @@ class FilesystemDecorator {
|
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
class ZlibDecorator {
|
|
198
|
+
constructor (stringTable) {
|
|
199
|
+
this.stringTable = stringTable
|
|
200
|
+
this.operationNameLabelKey = stringTable.dedup('operation')
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
decorateSample (sampleInput, item) {
|
|
204
|
+
sampleInput.label.push(labelFromStr(this.stringTable, this.operationNameLabelKey, item.detail.operation))
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
class CryptoDecorator {
|
|
209
|
+
constructor (stringTable) {
|
|
210
|
+
this.stringTable = stringTable
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
decorateSample (sampleInput, item) {
|
|
214
|
+
const labels = sampleInput.label
|
|
215
|
+
const stringTable = this.stringTable
|
|
216
|
+
for (const [key, value] of Object.entries(item.detail)) {
|
|
217
|
+
switch (typeof value) {
|
|
218
|
+
case 'string':
|
|
219
|
+
labels.push(labelFromStrStr(stringTable, key, value))
|
|
220
|
+
break
|
|
221
|
+
case 'number':
|
|
222
|
+
labels.push(new Label({ key: stringTable.dedup(key), num: value }))
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
197
228
|
// Keys correspond to PerformanceEntry.entryType, values are constructor
|
|
198
229
|
// functions for type-specific decorators.
|
|
199
230
|
const decoratorTypes = {
|
|
231
|
+
crypto: CryptoDecorator,
|
|
200
232
|
fs: FilesystemDecorator,
|
|
201
233
|
dns: DNSDecorator,
|
|
202
234
|
gc: GCDecorator,
|
|
203
235
|
net: NetDecorator,
|
|
236
|
+
zlib: ZlibDecorator,
|
|
204
237
|
}
|
|
205
238
|
|
|
206
239
|
// Translates performance entries into pprof samples.
|
|
@@ -348,12 +381,14 @@ class DatadogInstrumentationEventSource {
|
|
|
348
381
|
constructor (eventHandler, eventFilter) {
|
|
349
382
|
// List all entries explicitly for bundlers to pick up the require calls correctly.
|
|
350
383
|
const plugins = [
|
|
384
|
+
require('./event_plugins/crypto'),
|
|
351
385
|
require('./event_plugins/dns_lookup'),
|
|
352
386
|
require('./event_plugins/dns_lookupservice'),
|
|
353
387
|
require('./event_plugins/dns_resolve'),
|
|
354
388
|
require('./event_plugins/dns_reverse'),
|
|
355
389
|
require('./event_plugins/fs'),
|
|
356
390
|
require('./event_plugins/net'),
|
|
391
|
+
require('./event_plugins/zlib'),
|
|
357
392
|
]
|
|
358
393
|
this.plugins = plugins.map((Plugin) => {
|
|
359
394
|
return new Plugin(eventHandler, eventFilter)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { getValueFromEnvSources } = require('./config/helper')
|
|
4
3
|
const NoopProxy = require('./noop/proxy')
|
|
5
4
|
const DatadogTracer = require('./tracer')
|
|
6
5
|
const getConfig = require('./config')
|
|
@@ -213,7 +212,7 @@ class Tracer extends NoopProxy {
|
|
|
213
212
|
this._testApiManualPlugin.configure({ ...config, enabled: true }, false)
|
|
214
213
|
}
|
|
215
214
|
if (config.ciVisAgentlessLogSubmissionEnabled) {
|
|
216
|
-
if (
|
|
215
|
+
if (config.apiKey) {
|
|
217
216
|
const LogSubmissionPlugin = require('./ci-visibility/log-submission/log-submission-plugin')
|
|
218
217
|
const automaticLogPlugin = new LogSubmissionPlugin(this)
|
|
219
218
|
automaticLogPlugin.configure({ ...config, enabled: true })
|
|
@@ -255,10 +254,10 @@ class Tracer extends NoopProxy {
|
|
|
255
254
|
// do not stop tracer initialization if the profiler fails to be imported
|
|
256
255
|
try {
|
|
257
256
|
return require('./profiler').start(config)
|
|
258
|
-
} catch (
|
|
257
|
+
} catch (error) {
|
|
259
258
|
log.error(
|
|
260
259
|
'Error starting profiler. For troubleshooting tips, see <https://dtdg.co/nodejs-profiler-troubleshooting>',
|
|
261
|
-
|
|
260
|
+
error
|
|
262
261
|
)
|
|
263
262
|
return false
|
|
264
263
|
}
|