dd-trace 3.43.0 → 3.45.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/package.json +6 -6
- package/packages/datadog-instrumentations/src/child-process.js +4 -5
- package/packages/datadog-instrumentations/src/couchbase.js +5 -4
- package/packages/datadog-instrumentations/src/crypto.js +2 -1
- package/packages/datadog-instrumentations/src/dns.js +2 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +7 -2
- package/packages/datadog-instrumentations/src/helpers/instrument.js +8 -3
- package/packages/datadog-instrumentations/src/helpers/register.js +18 -2
- package/packages/datadog-instrumentations/src/http/client.js +2 -2
- package/packages/datadog-instrumentations/src/http/server.js +7 -4
- package/packages/datadog-instrumentations/src/http2/client.js +3 -1
- package/packages/datadog-instrumentations/src/http2/server.js +3 -1
- package/packages/datadog-instrumentations/src/jest.js +3 -1
- package/packages/datadog-instrumentations/src/net.js +10 -2
- package/packages/datadog-plugin-cucumber/src/index.js +34 -2
- package/packages/datadog-plugin-cypress/src/plugin.js +60 -8
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -0
- package/packages/datadog-plugin-jest/src/index.js +60 -6
- package/packages/datadog-plugin-jest/src/util.js +38 -16
- package/packages/datadog-plugin-mocha/src/index.js +32 -1
- package/packages/datadog-plugin-playwright/src/index.js +17 -1
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +5 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +4 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +30 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +30 -1
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +36 -4
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +18 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +26 -1
- package/packages/dd-trace/src/ci-visibility/telemetry.js +130 -0
- package/packages/dd-trace/src/config.js +100 -59
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +14 -1
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +14 -0
- package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +4 -0
- package/packages/dd-trace/src/exporters/common/form-data.js +4 -0
- package/packages/dd-trace/src/opentracing/tracer.js +2 -2
- package/packages/dd-trace/src/plugins/ci_plugin.js +44 -8
- package/packages/dd-trace/src/plugins/index.js +5 -0
- package/packages/dd-trace/src/plugins/util/exec.js +23 -2
- package/packages/dd-trace/src/plugins/util/git.js +94 -19
- package/packages/dd-trace/src/priority_sampler.js +30 -38
- package/packages/dd-trace/src/profiling/config.js +17 -2
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -0
- package/packages/dd-trace/src/profiling/exporters/file.js +2 -1
- package/packages/dd-trace/src/profiling/profiler.js +18 -14
- package/packages/dd-trace/src/profiling/profilers/events.js +11 -5
- package/packages/dd-trace/src/profiling/profilers/shared.js +7 -1
- package/packages/dd-trace/src/profiling/profilers/space.js +17 -2
- package/packages/dd-trace/src/profiling/profilers/wall.js +34 -21
- package/packages/dd-trace/src/sampling_rule.js +130 -0
- package/packages/dd-trace/src/span_sampler.js +6 -64
- package/packages/dd-trace/src/telemetry/index.js +43 -5
- package/packages/dd-trace/src/telemetry/send-data.js +35 -16
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
const telemetryMetrics = require('../telemetry/metrics')
|
|
2
|
+
|
|
3
|
+
const ciVisibilityMetrics = telemetryMetrics.manager.namespace('civisibility')
|
|
4
|
+
|
|
5
|
+
const formattedTags = {
|
|
6
|
+
testLevel: 'event_type',
|
|
7
|
+
testFramework: 'test_framework',
|
|
8
|
+
errorType: 'error_type',
|
|
9
|
+
exitCode: 'exit_code',
|
|
10
|
+
isCodeCoverageEnabled: 'coverage_enabled',
|
|
11
|
+
isSuitesSkippingEnabled: 'itrskip_enabled',
|
|
12
|
+
hasCodeOwners: 'has_code_owners',
|
|
13
|
+
isUnsupportedCIProvider: 'is_unsupported_ci'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Transform tags dictionary to array of strings.
|
|
17
|
+
// If tag value is true, then only tag key is added to the array.
|
|
18
|
+
function formatMetricTags (tagsDictionary) {
|
|
19
|
+
return Object.keys(tagsDictionary).reduce((acc, tagKey) => {
|
|
20
|
+
const formattedTagKey = formattedTags[tagKey] || tagKey
|
|
21
|
+
if (tagsDictionary[tagKey] === true) {
|
|
22
|
+
acc.push(formattedTagKey)
|
|
23
|
+
} else if (tagsDictionary[tagKey] !== undefined && tagsDictionary[tagKey] !== null) {
|
|
24
|
+
acc.push(`${formattedTagKey}:${tagsDictionary[tagKey]}`)
|
|
25
|
+
}
|
|
26
|
+
return acc
|
|
27
|
+
}, [])
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function incrementCountMetric (name, tags = {}, value = 1) {
|
|
31
|
+
ciVisibilityMetrics.count(name, formatMetricTags(tags)).inc(value)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function distributionMetric (name, tags, measure) {
|
|
35
|
+
ciVisibilityMetrics.distribution(name, formatMetricTags(tags)).track(measure)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// CI Visibility telemetry events
|
|
39
|
+
const TELEMETRY_EVENT_CREATED = 'event_created'
|
|
40
|
+
const TELEMETRY_EVENT_FINISHED = 'event_finished'
|
|
41
|
+
const TELEMETRY_CODE_COVERAGE_STARTED = 'code_coverage_started'
|
|
42
|
+
const TELEMETRY_CODE_COVERAGE_FINISHED = 'code_coverage_finished'
|
|
43
|
+
const TELEMETRY_ITR_SKIPPED = 'itr_skipped'
|
|
44
|
+
const TELEMETRY_ITR_UNSKIPPABLE = 'itr_unskippable'
|
|
45
|
+
const TELEMETRY_ITR_FORCED_TO_RUN = 'itr_forced_run'
|
|
46
|
+
const TELEMETRY_CODE_COVERAGE_EMPTY = 'code_coverage.is_empty'
|
|
47
|
+
const TELEMETRY_CODE_COVERAGE_NUM_FILES = 'code_coverage.files'
|
|
48
|
+
const TELEMETRY_EVENTS_ENQUEUED_FOR_SERIALIZATION = 'events_enqueued_for_serialization'
|
|
49
|
+
const TELEMETRY_ENDPOINT_PAYLOAD_SERIALIZATION_MS = 'endpoint_payload.events_serialization_ms'
|
|
50
|
+
const TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS = 'endpoint_payload.requests'
|
|
51
|
+
const TELEMETRY_ENDPOINT_PAYLOAD_BYTES = 'endpoint_payload.bytes'
|
|
52
|
+
const TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT = 'endpoint_payload.events_count'
|
|
53
|
+
const TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS = 'endpoint_payload.requests_ms'
|
|
54
|
+
const TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS = 'endpoint_payload.requests_errors'
|
|
55
|
+
const TELEMETRY_ENDPOINT_PAYLOAD_DROPPED = 'endpoint_payload.dropped'
|
|
56
|
+
const TELEMETRY_GIT_COMMAND = 'git.command'
|
|
57
|
+
const TELEMETRY_GIT_COMMAND_MS = 'git.command_ms'
|
|
58
|
+
const TELEMETRY_GIT_COMMAND_ERRORS = 'git.command_errors'
|
|
59
|
+
const TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS = 'git_requests.search_commits'
|
|
60
|
+
const TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_MS = 'git_requests.search_commits_ms'
|
|
61
|
+
const TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_ERRORS = 'git_requests.search_commits_errors'
|
|
62
|
+
const TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES = 'git_requests.objects_pack'
|
|
63
|
+
const TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_MS = 'git_requests.objects_pack_ms'
|
|
64
|
+
const TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_ERRORS = 'git_requests.objects_pack_errors'
|
|
65
|
+
const TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_NUM = 'git_requests.objects_pack_files'
|
|
66
|
+
const TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_BYTES = 'git_requests.objects_pack_bytes'
|
|
67
|
+
const TELEMETRY_GIT_REQUESTS_SETTINGS = 'git_requests.settings'
|
|
68
|
+
const TELEMETRY_GIT_REQUESTS_SETTINGS_MS = 'git_requests.settings_ms'
|
|
69
|
+
const TELEMETRY_GIT_REQUESTS_SETTINGS_ERRORS = 'git_requests.settings_errors'
|
|
70
|
+
const TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE = 'git_requests.settings_response'
|
|
71
|
+
const TELEMETRY_ITR_SKIPPABLE_TESTS = 'itr_skippable_tests.request'
|
|
72
|
+
const TELEMETRY_ITR_SKIPPABLE_TESTS_MS = 'itr_skippable_tests.request_ms'
|
|
73
|
+
const TELEMETRY_ITR_SKIPPABLE_TESTS_ERRORS = 'itr_skippable_tests.request_errors'
|
|
74
|
+
const TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_SUITES = 'itr_skippable_tests.response_suites'
|
|
75
|
+
const TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS = 'itr_skippable_tests.response_tests'
|
|
76
|
+
const TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES = 'itr_skippable_tests.response_bytes'
|
|
77
|
+
|
|
78
|
+
function getErrorTypeFromStatusCode (statusCode) {
|
|
79
|
+
if (statusCode >= 400 && statusCode < 500) {
|
|
80
|
+
return 'status_code_4xx_response'
|
|
81
|
+
}
|
|
82
|
+
if (statusCode >= 500) {
|
|
83
|
+
return 'status_code_5xx_response'
|
|
84
|
+
}
|
|
85
|
+
return 'network'
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = {
|
|
89
|
+
incrementCountMetric,
|
|
90
|
+
distributionMetric,
|
|
91
|
+
TELEMETRY_EVENT_CREATED,
|
|
92
|
+
TELEMETRY_EVENT_FINISHED,
|
|
93
|
+
TELEMETRY_CODE_COVERAGE_STARTED,
|
|
94
|
+
TELEMETRY_CODE_COVERAGE_FINISHED,
|
|
95
|
+
TELEMETRY_ITR_SKIPPED,
|
|
96
|
+
TELEMETRY_ITR_UNSKIPPABLE,
|
|
97
|
+
TELEMETRY_ITR_FORCED_TO_RUN,
|
|
98
|
+
TELEMETRY_CODE_COVERAGE_EMPTY,
|
|
99
|
+
TELEMETRY_CODE_COVERAGE_NUM_FILES,
|
|
100
|
+
TELEMETRY_EVENTS_ENQUEUED_FOR_SERIALIZATION,
|
|
101
|
+
TELEMETRY_ENDPOINT_PAYLOAD_SERIALIZATION_MS,
|
|
102
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS,
|
|
103
|
+
TELEMETRY_ENDPOINT_PAYLOAD_BYTES,
|
|
104
|
+
TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT,
|
|
105
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_MS,
|
|
106
|
+
TELEMETRY_ENDPOINT_PAYLOAD_REQUESTS_ERRORS,
|
|
107
|
+
TELEMETRY_ENDPOINT_PAYLOAD_DROPPED,
|
|
108
|
+
TELEMETRY_GIT_COMMAND,
|
|
109
|
+
TELEMETRY_GIT_COMMAND_MS,
|
|
110
|
+
TELEMETRY_GIT_COMMAND_ERRORS,
|
|
111
|
+
TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS,
|
|
112
|
+
TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_MS,
|
|
113
|
+
TELEMETRY_GIT_REQUESTS_SEARCH_COMMITS_ERRORS,
|
|
114
|
+
TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_NUM,
|
|
115
|
+
TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_BYTES,
|
|
116
|
+
TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES,
|
|
117
|
+
TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_MS,
|
|
118
|
+
TELEMETRY_GIT_REQUESTS_OBJECT_PACKFILES_ERRORS,
|
|
119
|
+
TELEMETRY_GIT_REQUESTS_SETTINGS,
|
|
120
|
+
TELEMETRY_GIT_REQUESTS_SETTINGS_MS,
|
|
121
|
+
TELEMETRY_GIT_REQUESTS_SETTINGS_ERRORS,
|
|
122
|
+
TELEMETRY_GIT_REQUESTS_SETTINGS_RESPONSE,
|
|
123
|
+
TELEMETRY_ITR_SKIPPABLE_TESTS,
|
|
124
|
+
TELEMETRY_ITR_SKIPPABLE_TESTS_MS,
|
|
125
|
+
TELEMETRY_ITR_SKIPPABLE_TESTS_ERRORS,
|
|
126
|
+
TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_SUITES,
|
|
127
|
+
TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_TESTS,
|
|
128
|
+
TELEMETRY_ITR_SKIPPABLE_TESTS_RESPONSE_BYTES,
|
|
129
|
+
getErrorTypeFromStatusCode
|
|
130
|
+
}
|
|
@@ -109,13 +109,6 @@ class Config {
|
|
|
109
109
|
log.use(this.logger)
|
|
110
110
|
log.toggle(this.debug, this.logLevel, this)
|
|
111
111
|
|
|
112
|
-
this.tags = {}
|
|
113
|
-
|
|
114
|
-
tagger.add(this.tags, process.env.DD_TAGS)
|
|
115
|
-
tagger.add(this.tags, process.env.DD_TRACE_TAGS)
|
|
116
|
-
tagger.add(this.tags, process.env.DD_TRACE_GLOBAL_TAGS)
|
|
117
|
-
tagger.add(this.tags, options.tags)
|
|
118
|
-
|
|
119
112
|
const DD_TRACING_ENABLED = coalesce(
|
|
120
113
|
process.env.DD_TRACING_ENABLED,
|
|
121
114
|
true
|
|
@@ -184,33 +177,12 @@ class Config {
|
|
|
184
177
|
false
|
|
185
178
|
)
|
|
186
179
|
|
|
187
|
-
const DD_SERVICE = options.service ||
|
|
188
|
-
process.env.DD_SERVICE ||
|
|
189
|
-
process.env.DD_SERVICE_NAME ||
|
|
190
|
-
this.tags.service ||
|
|
191
|
-
process.env.AWS_LAMBDA_FUNCTION_NAME ||
|
|
192
|
-
process.env.FUNCTION_NAME || // Google Cloud Function Name set by deprecated runtimes
|
|
193
|
-
process.env.K_SERVICE || // Google Cloud Function Name set by newer runtimes
|
|
194
|
-
process.env.WEBSITE_SITE_NAME || // set by Azure Functions
|
|
195
|
-
pkg.name ||
|
|
196
|
-
'node'
|
|
197
180
|
const DD_SERVICE_MAPPING = coalesce(
|
|
198
181
|
options.serviceMapping,
|
|
199
182
|
process.env.DD_SERVICE_MAPPING ? fromEntries(
|
|
200
183
|
process.env.DD_SERVICE_MAPPING.split(',').map(x => x.trim().split(':'))
|
|
201
184
|
) : {}
|
|
202
185
|
)
|
|
203
|
-
const DD_ENV = coalesce(
|
|
204
|
-
options.env,
|
|
205
|
-
process.env.DD_ENV,
|
|
206
|
-
this.tags.env
|
|
207
|
-
)
|
|
208
|
-
const DD_VERSION = coalesce(
|
|
209
|
-
options.version,
|
|
210
|
-
process.env.DD_VERSION,
|
|
211
|
-
this.tags.version,
|
|
212
|
-
pkg.version
|
|
213
|
-
)
|
|
214
186
|
const DD_TRACE_STARTUP_LOGS = coalesce(
|
|
215
187
|
options.startupLogs,
|
|
216
188
|
process.env.DD_TRACE_STARTUP_LOGS,
|
|
@@ -550,6 +522,19 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
550
522
|
0
|
|
551
523
|
)
|
|
552
524
|
|
|
525
|
+
const DD_INSTRUMENTATION_INSTALL_ID = coalesce(
|
|
526
|
+
process.env.DD_INSTRUMENTATION_INSTALL_ID,
|
|
527
|
+
null
|
|
528
|
+
)
|
|
529
|
+
const DD_INSTRUMENTATION_INSTALL_TIME = coalesce(
|
|
530
|
+
process.env.DD_INSTRUMENTATION_INSTALL_TIME,
|
|
531
|
+
null
|
|
532
|
+
)
|
|
533
|
+
const DD_INSTRUMENTATION_INSTALL_TYPE = coalesce(
|
|
534
|
+
process.env.DD_INSTRUMENTATION_INSTALL_TYPE,
|
|
535
|
+
null
|
|
536
|
+
)
|
|
537
|
+
|
|
553
538
|
const ingestion = options.ingestion || {}
|
|
554
539
|
const dogstatsd = coalesce(options.dogstatsd, {})
|
|
555
540
|
const sampler = {
|
|
@@ -583,7 +568,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
583
568
|
this.dsmEnabled = isTrue(DD_DATA_STREAMS_ENABLED)
|
|
584
569
|
this.openAiLogsEnabled = DD_OPENAI_LOGS_ENABLED
|
|
585
570
|
this.apiKey = DD_API_KEY
|
|
586
|
-
this.env = DD_ENV
|
|
587
571
|
this.url = DD_CIVISIBILITY_AGENTLESS_URL ? new URL(DD_CIVISIBILITY_AGENTLESS_URL)
|
|
588
572
|
: getAgentUrl(DD_TRACE_AGENT_URL, options)
|
|
589
573
|
this.site = coalesce(options.site, process.env.DD_SITE, 'datadoghq.com')
|
|
@@ -595,9 +579,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
595
579
|
this.clientIpEnabled = DD_TRACE_CLIENT_IP_ENABLED
|
|
596
580
|
this.clientIpHeader = DD_TRACE_CLIENT_IP_HEADER
|
|
597
581
|
this.plugins = !!coalesce(options.plugins, true)
|
|
598
|
-
this.service = DD_SERVICE
|
|
599
582
|
this.serviceMapping = DD_SERVICE_MAPPING
|
|
600
|
-
this.version = DD_VERSION
|
|
601
583
|
this.dogstatsd = {
|
|
602
584
|
hostname: coalesce(dogstatsd.hostname, process.env.DD_DOGSTATSD_HOSTNAME, this.hostname),
|
|
603
585
|
port: String(coalesce(dogstatsd.port, process.env.DD_DOGSTATSD_PORT, 8125))
|
|
@@ -629,7 +611,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
629
611
|
this.startupLogs = isTrue(DD_TRACE_STARTUP_LOGS)
|
|
630
612
|
// Disabled for CI Visibility's agentless
|
|
631
613
|
this.telemetry = {
|
|
632
|
-
enabled:
|
|
614
|
+
enabled: isTrue(DD_INSTRUMENTATION_TELEMETRY_ENABLED),
|
|
633
615
|
heartbeatInterval: DD_TELEMETRY_HEARTBEAT_INTERVAL,
|
|
634
616
|
debug: isTrue(DD_TELEMETRY_DEBUG),
|
|
635
617
|
logCollection: isTrue(DD_TELEMETRY_LOG_COLLECTION_ENABLED),
|
|
@@ -690,6 +672,37 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
690
672
|
// Requires an accompanying DD_APM_OBFUSCATION_MEMCACHED_KEEP_COMMAND=true in the agent
|
|
691
673
|
this.memcachedCommandEnabled = isTrue(DD_TRACE_MEMCACHED_COMMAND_ENABLED)
|
|
692
674
|
|
|
675
|
+
this.stats = {
|
|
676
|
+
enabled: isTrue(DD_TRACE_STATS_COMPUTATION_ENABLED)
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
this.traceId128BitGenerationEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED)
|
|
680
|
+
this.traceId128BitLoggingEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED)
|
|
681
|
+
|
|
682
|
+
this.isGCPFunction = isGCPFunction
|
|
683
|
+
this.isAzureFunctionConsumptionPlan = isAzureFunctionConsumptionPlan
|
|
684
|
+
|
|
685
|
+
this.spanLeakDebug = Number(DD_TRACE_SPAN_LEAK_DEBUG)
|
|
686
|
+
|
|
687
|
+
this.installSignature = {
|
|
688
|
+
id: DD_INSTRUMENTATION_INSTALL_ID,
|
|
689
|
+
time: DD_INSTRUMENTATION_INSTALL_TIME,
|
|
690
|
+
type: DD_INSTRUMENTATION_INSTALL_TYPE
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
this._applyDefaults()
|
|
694
|
+
this._applyEnvironment()
|
|
695
|
+
this._applyOptions(options)
|
|
696
|
+
this._applyRemote({})
|
|
697
|
+
this._merge()
|
|
698
|
+
|
|
699
|
+
tagger.add(this.tags, {
|
|
700
|
+
service: this.service,
|
|
701
|
+
env: this.env,
|
|
702
|
+
version: this.version,
|
|
703
|
+
'runtime-id': uuid()
|
|
704
|
+
})
|
|
705
|
+
|
|
693
706
|
if (this.gitMetadataEnabled) {
|
|
694
707
|
this.repositoryUrl = removeUserSensitiveInfo(
|
|
695
708
|
coalesce(
|
|
@@ -722,31 +735,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
722
735
|
}
|
|
723
736
|
}
|
|
724
737
|
}
|
|
725
|
-
|
|
726
|
-
this.stats = {
|
|
727
|
-
enabled: isTrue(DD_TRACE_STATS_COMPUTATION_ENABLED)
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
this.traceId128BitGenerationEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED)
|
|
731
|
-
this.traceId128BitLoggingEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED)
|
|
732
|
-
|
|
733
|
-
this.isGCPFunction = isGCPFunction
|
|
734
|
-
this.isAzureFunctionConsumptionPlan = isAzureFunctionConsumptionPlan
|
|
735
|
-
|
|
736
|
-
this.spanLeakDebug = Number(DD_TRACE_SPAN_LEAK_DEBUG)
|
|
737
|
-
|
|
738
|
-
tagger.add(this.tags, {
|
|
739
|
-
service: this.service,
|
|
740
|
-
env: this.env,
|
|
741
|
-
version: this.version,
|
|
742
|
-
'runtime-id': uuid()
|
|
743
|
-
})
|
|
744
|
-
|
|
745
|
-
this._applyDefaults()
|
|
746
|
-
this._applyEnvironment()
|
|
747
|
-
this._applyOptions(options)
|
|
748
|
-
this._applyRemote({})
|
|
749
|
-
this._merge()
|
|
750
738
|
}
|
|
751
739
|
|
|
752
740
|
// Supports only a subset of options for now.
|
|
@@ -761,48 +749,93 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
761
749
|
}
|
|
762
750
|
|
|
763
751
|
_applyDefaults () {
|
|
752
|
+
const {
|
|
753
|
+
AWS_LAMBDA_FUNCTION_NAME,
|
|
754
|
+
FUNCTION_NAME,
|
|
755
|
+
K_SERVICE,
|
|
756
|
+
WEBSITE_SITE_NAME
|
|
757
|
+
} = process.env
|
|
758
|
+
|
|
759
|
+
const service = AWS_LAMBDA_FUNCTION_NAME ||
|
|
760
|
+
FUNCTION_NAME || // Google Cloud Function Name set by deprecated runtimes
|
|
761
|
+
K_SERVICE || // Google Cloud Function Name set by newer runtimes
|
|
762
|
+
WEBSITE_SITE_NAME || // set by Azure Functions
|
|
763
|
+
pkg.name ||
|
|
764
|
+
'node'
|
|
765
|
+
|
|
764
766
|
const defaults = this._defaults = {}
|
|
765
767
|
|
|
768
|
+
this._setValue(defaults, 'service', service)
|
|
769
|
+
this._setValue(defaults, 'env', undefined)
|
|
770
|
+
this._setValue(defaults, 'version', pkg.version)
|
|
766
771
|
this._setUnit(defaults, 'sampleRate', undefined)
|
|
767
772
|
this._setBoolean(defaults, 'logInjection', false)
|
|
768
773
|
this._setArray(defaults, 'headerTags', [])
|
|
774
|
+
this._setValue(defaults, 'tags', {})
|
|
769
775
|
}
|
|
770
776
|
|
|
771
777
|
_applyEnvironment () {
|
|
772
778
|
const {
|
|
773
|
-
|
|
779
|
+
DD_ENV,
|
|
774
780
|
DD_LOGS_INJECTION,
|
|
775
|
-
|
|
781
|
+
DD_SERVICE,
|
|
782
|
+
DD_SERVICE_NAME,
|
|
783
|
+
DD_TAGS,
|
|
784
|
+
DD_TRACE_GLOBAL_TAGS,
|
|
785
|
+
DD_TRACE_HEADER_TAGS,
|
|
786
|
+
DD_TRACE_SAMPLE_RATE,
|
|
787
|
+
DD_TRACE_TAGS,
|
|
788
|
+
DD_VERSION
|
|
776
789
|
} = process.env
|
|
777
790
|
|
|
791
|
+
const tags = {}
|
|
778
792
|
const env = this._env = {}
|
|
779
793
|
|
|
794
|
+
tagger.add(tags, DD_TAGS)
|
|
795
|
+
tagger.add(tags, DD_TRACE_TAGS)
|
|
796
|
+
tagger.add(tags, DD_TRACE_GLOBAL_TAGS)
|
|
797
|
+
|
|
798
|
+
this._setValue(env, 'service', DD_SERVICE || DD_SERVICE_NAME || tags.service)
|
|
799
|
+
this._setValue(env, 'env', DD_ENV || tags.env)
|
|
800
|
+
this._setValue(env, 'version', DD_VERSION || tags.version)
|
|
780
801
|
this._setUnit(env, 'sampleRate', DD_TRACE_SAMPLE_RATE)
|
|
781
802
|
this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
|
|
782
803
|
this._setArray(env, 'headerTags', DD_TRACE_HEADER_TAGS)
|
|
804
|
+
this._setTags(env, 'tags', tags)
|
|
783
805
|
}
|
|
784
806
|
|
|
785
807
|
_applyOptions (options) {
|
|
786
808
|
const opts = this._options = this._options || {}
|
|
809
|
+
const tags = {}
|
|
787
810
|
|
|
788
811
|
options = Object.assign({ ingestion: {} }, options, opts)
|
|
789
812
|
|
|
813
|
+
tagger.add(tags, options.tags)
|
|
814
|
+
|
|
815
|
+
this._setValue(opts, 'service', options.service || tags.service)
|
|
816
|
+
this._setValue(opts, 'env', options.env || tags.env)
|
|
817
|
+
this._setValue(opts, 'version', options.version || tags.version)
|
|
790
818
|
this._setUnit(opts, 'sampleRate', coalesce(options.sampleRate, options.ingestion.sampleRate))
|
|
791
819
|
this._setBoolean(opts, 'logInjection', options.logInjection)
|
|
792
820
|
this._setArray(opts, 'headerTags', options.headerTags)
|
|
821
|
+
this._setTags(opts, 'tags', tags)
|
|
793
822
|
}
|
|
794
823
|
|
|
795
824
|
_applyRemote (options) {
|
|
796
825
|
const opts = this._remote = this._remote || {}
|
|
826
|
+
const tags = {}
|
|
797
827
|
const headerTags = options.tracing_header_tags
|
|
798
828
|
? options.tracing_header_tags.map(tag => {
|
|
799
829
|
return tag.tag_name ? `${tag.header}:${tag.tag_name}` : tag.header
|
|
800
830
|
})
|
|
801
831
|
: undefined
|
|
802
832
|
|
|
833
|
+
tagger.add(tags, options.tracing_tags)
|
|
834
|
+
|
|
803
835
|
this._setUnit(opts, 'sampleRate', options.tracing_sampling_rate)
|
|
804
836
|
this._setBoolean(opts, 'logInjection', options.log_injection_enabled)
|
|
805
837
|
this._setArray(opts, 'headerTags', headerTags)
|
|
838
|
+
this._setTags(opts, 'tags', tags)
|
|
806
839
|
}
|
|
807
840
|
|
|
808
841
|
_setBoolean (obj, name, value) {
|
|
@@ -842,6 +875,14 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
842
875
|
}
|
|
843
876
|
}
|
|
844
877
|
|
|
878
|
+
_setTags (obj, name, value) {
|
|
879
|
+
if (!value || Object.keys(value).length === 0) {
|
|
880
|
+
return this._setValue(obj, name, null)
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
this._setValue(obj, name, value)
|
|
884
|
+
}
|
|
885
|
+
|
|
845
886
|
_setValue (obj, name, value) {
|
|
846
887
|
obj[name] = value
|
|
847
888
|
}
|
|
@@ -3,8 +3,13 @@ const { truncateSpan, normalizeSpan } = require('./tags-processors')
|
|
|
3
3
|
const { AgentEncoder } = require('./0.4')
|
|
4
4
|
const { version: ddTraceVersion } = require('../../../../package.json')
|
|
5
5
|
const id = require('../../../dd-trace/src/id')
|
|
6
|
-
const
|
|
6
|
+
const {
|
|
7
|
+
distributionMetric,
|
|
8
|
+
TELEMETRY_ENDPOINT_PAYLOAD_SERIALIZATION_MS,
|
|
9
|
+
TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT
|
|
10
|
+
} = require('../ci-visibility/telemetry')
|
|
7
11
|
|
|
12
|
+
const ENCODING_VERSION = 1
|
|
8
13
|
const ALLOWED_CONTENT_TYPES = ['test_session_end', 'test_module_end', 'test_suite_end', 'test']
|
|
9
14
|
|
|
10
15
|
const TEST_SUITE_KEYS_LENGTH = 12
|
|
@@ -247,6 +252,8 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
247
252
|
}
|
|
248
253
|
|
|
249
254
|
_encode (bytes, trace) {
|
|
255
|
+
const startTime = Date.now()
|
|
256
|
+
|
|
250
257
|
const rawEvents = trace.map(formatSpan)
|
|
251
258
|
|
|
252
259
|
const testSessionEvents = rawEvents.filter(
|
|
@@ -261,9 +268,15 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
|
|
|
261
268
|
for (const event of events) {
|
|
262
269
|
this._encodeEvent(bytes, event)
|
|
263
270
|
}
|
|
271
|
+
distributionMetric(
|
|
272
|
+
TELEMETRY_ENDPOINT_PAYLOAD_SERIALIZATION_MS,
|
|
273
|
+
{ endpoint: 'test_cycle' },
|
|
274
|
+
Date.now() - startTime
|
|
275
|
+
)
|
|
264
276
|
}
|
|
265
277
|
|
|
266
278
|
makePayload () {
|
|
279
|
+
distributionMetric(TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT, { endpoint: 'test_cycle' }, this._eventCount)
|
|
267
280
|
const bytes = this._traceBytes
|
|
268
281
|
const eventsOffset = this._eventsOffset
|
|
269
282
|
const eventsCount = this._eventCount
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
const { AgentEncoder } = require('./0.4')
|
|
3
3
|
const Chunk = require('./chunk')
|
|
4
4
|
|
|
5
|
+
const {
|
|
6
|
+
distributionMetric,
|
|
7
|
+
TELEMETRY_ENDPOINT_PAYLOAD_SERIALIZATION_MS,
|
|
8
|
+
TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT
|
|
9
|
+
} = require('../ci-visibility/telemetry')
|
|
5
10
|
const FormData = require('../exporters/common/form-data')
|
|
6
11
|
|
|
7
12
|
const COVERAGE_PAYLOAD_VERSION = 2
|
|
@@ -21,8 +26,16 @@ class CoverageCIVisibilityEncoder extends AgentEncoder {
|
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
encode (coverage) {
|
|
29
|
+
const startTime = Date.now()
|
|
30
|
+
|
|
24
31
|
this._coveragesCount++
|
|
25
32
|
this.encodeCodeCoverage(this._coverageBytes, coverage)
|
|
33
|
+
|
|
34
|
+
distributionMetric(
|
|
35
|
+
TELEMETRY_ENDPOINT_PAYLOAD_SERIALIZATION_MS,
|
|
36
|
+
{ endpoint: 'code_coverage' },
|
|
37
|
+
Date.now() - startTime
|
|
38
|
+
)
|
|
26
39
|
}
|
|
27
40
|
|
|
28
41
|
encodeCodeCoverage (bytes, coverage) {
|
|
@@ -73,6 +86,7 @@ class CoverageCIVisibilityEncoder extends AgentEncoder {
|
|
|
73
86
|
}
|
|
74
87
|
|
|
75
88
|
makePayload () {
|
|
89
|
+
distributionMetric(TELEMETRY_ENDPOINT_PAYLOAD_EVENTS_COUNT, { endpoint: 'code_coverage' }, this._coveragesCount)
|
|
76
90
|
const bytes = this._coverageBytes
|
|
77
91
|
|
|
78
92
|
const coveragesOffset = this._coveragesOffset
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const { URL, format } = require('url')
|
|
2
2
|
|
|
3
3
|
const request = require('./request')
|
|
4
|
+
const { incrementCountMetric, TELEMETRY_EVENTS_ENQUEUED_FOR_SERIALIZATION } = require('../../ci-visibility/telemetry')
|
|
4
5
|
|
|
5
6
|
function fetchAgentInfo (url, callback) {
|
|
6
7
|
request('', {
|
|
@@ -49,6 +50,9 @@ class AgentInfoExporter {
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
_export (payload, writer = this._writer, timerKey = '_timer') {
|
|
53
|
+
if (this._config.isCiVisibility) {
|
|
54
|
+
incrementCountMetric(TELEMETRY_EVENTS_ENQUEUED_FOR_SERIALIZATION, {}, payload.length)
|
|
55
|
+
}
|
|
52
56
|
writer.append(payload)
|
|
53
57
|
|
|
54
58
|
const { flushInterval } = this._config
|
|
@@ -22,10 +22,10 @@ class DatadogTracer {
|
|
|
22
22
|
constructor (config) {
|
|
23
23
|
const Exporter = getExporter(config.experimental.exporter)
|
|
24
24
|
|
|
25
|
+
this._config = config
|
|
25
26
|
this._service = config.service
|
|
26
27
|
this._version = config.version
|
|
27
28
|
this._env = config.env
|
|
28
|
-
this._tags = config.tags
|
|
29
29
|
this._logInjection = config.logInjection
|
|
30
30
|
this._debug = config.debug
|
|
31
31
|
this._prioritySampler = new PrioritySampler(config.env, config.sampler)
|
|
@@ -64,7 +64,7 @@ class DatadogTracer {
|
|
|
64
64
|
integrationName: options.integrationName
|
|
65
65
|
}, this._debug)
|
|
66
66
|
|
|
67
|
-
span.addTags(this.
|
|
67
|
+
span.addTags(this._config.tags)
|
|
68
68
|
span.addTags(options.tags)
|
|
69
69
|
|
|
70
70
|
return span
|
|
@@ -20,6 +20,14 @@ const {
|
|
|
20
20
|
const Plugin = require('./plugin')
|
|
21
21
|
const { COMPONENT } = require('../constants')
|
|
22
22
|
const log = require('../log')
|
|
23
|
+
const {
|
|
24
|
+
incrementCountMetric,
|
|
25
|
+
distributionMetric,
|
|
26
|
+
TELEMETRY_EVENT_CREATED,
|
|
27
|
+
TELEMETRY_ITR_SKIPPED
|
|
28
|
+
} = require('../ci-visibility/telemetry')
|
|
29
|
+
const { CI_PROVIDER_NAME, GIT_REPOSITORY_URL, GIT_COMMIT_SHA, GIT_BRANCH } = require('./util/tags')
|
|
30
|
+
const { OS_VERSION, OS_PLATFORM, OS_ARCHITECTURE, RUNTIME_NAME, RUNTIME_VERSION } = require('./util/env')
|
|
23
31
|
|
|
24
32
|
module.exports = class CiPlugin extends Plugin {
|
|
25
33
|
constructor (...args) {
|
|
@@ -71,6 +79,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
71
79
|
...testSessionSpanMetadata
|
|
72
80
|
}
|
|
73
81
|
})
|
|
82
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'session')
|
|
74
83
|
this.testModuleSpan = this.tracer.startSpan(`${this.constructor.id}.test_module`, {
|
|
75
84
|
childOf: this.testSessionSpan,
|
|
76
85
|
tags: {
|
|
@@ -79,6 +88,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
79
88
|
...testModuleSpanMetadata
|
|
80
89
|
}
|
|
81
90
|
})
|
|
91
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'module')
|
|
82
92
|
})
|
|
83
93
|
|
|
84
94
|
this.addSub(`ci:${this.constructor.id}:itr:skipped-suites`, ({ skippedSuites, frameworkVersion }) => {
|
|
@@ -97,25 +107,49 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
97
107
|
}
|
|
98
108
|
}).finish()
|
|
99
109
|
})
|
|
110
|
+
this.telemetry.count(TELEMETRY_ITR_SKIPPED, { testLevel: 'suite' }, skippedSuites.length)
|
|
100
111
|
})
|
|
101
112
|
}
|
|
102
113
|
|
|
114
|
+
get telemetry () {
|
|
115
|
+
const testFramework = this.constructor.id
|
|
116
|
+
return {
|
|
117
|
+
ciVisEvent: function (name, testLevel, tags = {}) {
|
|
118
|
+
incrementCountMetric(name, {
|
|
119
|
+
testLevel,
|
|
120
|
+
testFramework,
|
|
121
|
+
isUnsupportedCIProvider: this.isUnsupportedCIProvider,
|
|
122
|
+
...tags
|
|
123
|
+
})
|
|
124
|
+
},
|
|
125
|
+
count: function (name, tags, value = 1) {
|
|
126
|
+
incrementCountMetric(name, tags, value)
|
|
127
|
+
},
|
|
128
|
+
distribution: function (name, tags, measure) {
|
|
129
|
+
distributionMetric(name, tags, measure)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
103
134
|
configure (config) {
|
|
104
135
|
super.configure(config)
|
|
105
136
|
this.testEnvironmentMetadata = getTestEnvironmentMetadata(this.constructor.id, this.config)
|
|
106
137
|
this.codeOwnersEntries = getCodeOwnersFileEntries()
|
|
107
138
|
|
|
108
139
|
const {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
140
|
+
[GIT_REPOSITORY_URL]: repositoryUrl,
|
|
141
|
+
[GIT_COMMIT_SHA]: sha,
|
|
142
|
+
[OS_VERSION]: osVersion,
|
|
143
|
+
[OS_PLATFORM]: osPlatform,
|
|
144
|
+
[OS_ARCHITECTURE]: osArchitecture,
|
|
145
|
+
[RUNTIME_NAME]: runtimeName,
|
|
146
|
+
[RUNTIME_VERSION]: runtimeVersion,
|
|
147
|
+
[GIT_BRANCH]: branch,
|
|
148
|
+
[CI_PROVIDER_NAME]: ciProviderName
|
|
117
149
|
} = this.testEnvironmentMetadata
|
|
118
150
|
|
|
151
|
+
this.isUnsupportedCIProvider = !ciProviderName
|
|
152
|
+
|
|
119
153
|
this.testConfiguration = {
|
|
120
154
|
repositoryUrl,
|
|
121
155
|
sha,
|
|
@@ -170,6 +204,8 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
170
204
|
}
|
|
171
205
|
}
|
|
172
206
|
|
|
207
|
+
this.telemetry.ciVisEvent(TELEMETRY_EVENT_CREATED, 'test', { hasCodeOwners: !!codeOwners })
|
|
208
|
+
|
|
173
209
|
const testSpan = this.tracer
|
|
174
210
|
.startSpan(`${this.constructor.id}.test`, {
|
|
175
211
|
childOf,
|
|
@@ -59,6 +59,11 @@ module.exports = {
|
|
|
59
59
|
get 'mysql2' () { return require('../../../datadog-plugin-mysql2/src') },
|
|
60
60
|
get 'net' () { return require('../../../datadog-plugin-net/src') },
|
|
61
61
|
get 'next' () { return require('../../../datadog-plugin-next/src') },
|
|
62
|
+
get 'node:dns' () { return require('../../../datadog-plugin-dns/src') },
|
|
63
|
+
get 'node:http' () { return require('../../../datadog-plugin-http/src') },
|
|
64
|
+
get 'node:http2' () { return require('../../../datadog-plugin-http2/src') },
|
|
65
|
+
get 'node:https' () { return require('../../../datadog-plugin-http/src') },
|
|
66
|
+
get 'node:net' () { return require('../../../datadog-plugin-net/src') },
|
|
62
67
|
get 'oracledb' () { return require('../../../datadog-plugin-oracledb/src') },
|
|
63
68
|
get 'openai' () { return require('../../../datadog-plugin-openai/src') },
|
|
64
69
|
get 'paperplane' () { return require('../../../datadog-plugin-paperplane/src') },
|
|
@@ -1,10 +1,31 @@
|
|
|
1
1
|
const cp = require('child_process')
|
|
2
2
|
const log = require('../../log')
|
|
3
|
+
const { distributionMetric, incrementCountMetric } = require('../../ci-visibility/telemetry')
|
|
3
4
|
|
|
4
|
-
const sanitizedExec = (
|
|
5
|
+
const sanitizedExec = (
|
|
6
|
+
cmd,
|
|
7
|
+
flags,
|
|
8
|
+
operationMetric,
|
|
9
|
+
durationMetric,
|
|
10
|
+
errorMetric
|
|
11
|
+
) => {
|
|
12
|
+
let startTime
|
|
13
|
+
if (operationMetric) {
|
|
14
|
+
incrementCountMetric(operationMetric.name, operationMetric.tags)
|
|
15
|
+
}
|
|
16
|
+
if (durationMetric) {
|
|
17
|
+
startTime = Date.now()
|
|
18
|
+
}
|
|
5
19
|
try {
|
|
6
|
-
|
|
20
|
+
const result = cp.execFileSync(cmd, flags, { stdio: 'pipe' }).toString().replace(/(\r\n|\n|\r)/gm, '')
|
|
21
|
+
if (durationMetric) {
|
|
22
|
+
distributionMetric(durationMetric.name, durationMetric.tags, Date.now() - startTime)
|
|
23
|
+
}
|
|
24
|
+
return result
|
|
7
25
|
} catch (e) {
|
|
26
|
+
if (errorMetric) {
|
|
27
|
+
incrementCountMetric(errorMetric.name, { ...errorMetric.tags, exitCode: e.status })
|
|
28
|
+
}
|
|
8
29
|
log.error(e)
|
|
9
30
|
return ''
|
|
10
31
|
}
|