dd-trace 5.0.0-pre-069b62a → 5.0.0-pre-e2df7ec
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/index.d.ts +5 -0
- package/package.json +4 -3
- package/packages/datadog-instrumentations/src/apollo-server-core.js +41 -0
- package/packages/datadog-instrumentations/src/apollo-server.js +83 -0
- package/packages/datadog-instrumentations/src/child-process.js +4 -5
- package/packages/datadog-instrumentations/src/crypto.js +2 -1
- package/packages/datadog-instrumentations/src/dns.js +2 -1
- package/packages/datadog-instrumentations/src/graphql.js +18 -4
- package/packages/datadog-instrumentations/src/helpers/hooks.js +9 -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 +4 -16
- 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 +1 -1
- package/packages/datadog-instrumentations/src/kafkajs.js +27 -0
- package/packages/datadog-instrumentations/src/net.js +10 -2
- package/packages/datadog-instrumentations/src/next.js +15 -5
- package/packages/datadog-instrumentations/src/restify.js +1 -1
- package/packages/datadog-instrumentations/src/rhea.js +15 -9
- package/packages/datadog-plugin-cucumber/src/index.js +34 -2
- package/packages/datadog-plugin-cypress/src/plugin.js +60 -8
- package/packages/datadog-plugin-graphql/src/resolve.js +26 -18
- package/packages/datadog-plugin-http/src/client.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +38 -4
- package/packages/datadog-plugin-kafkajs/src/consumer.js +51 -0
- package/packages/datadog-plugin-kafkajs/src/producer.js +55 -0
- package/packages/datadog-plugin-mocha/src/index.js +32 -1
- package/packages/datadog-plugin-next/src/index.js +32 -6
- package/packages/datadog-plugin-playwright/src/index.js +17 -1
- package/packages/dd-trace/src/appsec/activation.js +29 -0
- package/packages/dd-trace/src/appsec/addresses.js +1 -0
- package/packages/dd-trace/src/appsec/api_security_sampler.js +48 -0
- package/packages/dd-trace/src/appsec/blocked_templates.js +4 -1
- package/packages/dd-trace/src/appsec/blocking.js +95 -43
- package/packages/dd-trace/src/appsec/channels.js +4 -1
- package/packages/dd-trace/src/appsec/graphql.js +146 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/header-injection-analyzer.js +16 -7
- package/packages/dd-trace/src/appsec/index.js +29 -40
- package/packages/dd-trace/src/appsec/recommended.json +1395 -2
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +6 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +40 -15
- package/packages/dd-trace/src/appsec/reporter.js +2 -4
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +1 -1
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +25 -13
- 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 +110 -56
- package/packages/dd-trace/src/datastreams/processor.js +107 -12
- 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/span.js +2 -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/plugins/util/user-provided-git.js +3 -2
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -0
- package/packages/dd-trace/src/profiling/profiler.js +7 -6
- package/packages/dd-trace/src/profiling/profilers/events.js +19 -51
- package/packages/dd-trace/src/profiling/profilers/shared.js +34 -4
- package/packages/dd-trace/src/profiling/profilers/space.js +2 -1
- package/packages/dd-trace/src/profiling/profilers/wall.js +17 -12
- package/packages/dd-trace/src/proxy.js +14 -0
- package/packages/dd-trace/src/spanleak.js +98 -0
- package/packages/dd-trace/src/telemetry/index.js +43 -5
- package/packages/dd-trace/src/tracer.js +4 -0
|
@@ -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,
|
|
@@ -435,6 +407,10 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
435
407
|
maybeFile(appsec.blockedTemplateJson),
|
|
436
408
|
maybeFile(process.env.DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON)
|
|
437
409
|
)
|
|
410
|
+
const DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON = coalesce(
|
|
411
|
+
maybeFile(appsec.blockedTemplateGraphql),
|
|
412
|
+
maybeFile(process.env.DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON)
|
|
413
|
+
)
|
|
438
414
|
const DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING = coalesce(
|
|
439
415
|
appsec.eventTracking && appsec.eventTracking.mode,
|
|
440
416
|
process.env.DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING,
|
|
@@ -540,6 +516,25 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
540
516
|
true
|
|
541
517
|
)
|
|
542
518
|
|
|
519
|
+
// 0: disabled, 1: logging, 2: garbage collection + logging
|
|
520
|
+
const DD_TRACE_SPAN_LEAK_DEBUG = coalesce(
|
|
521
|
+
process.env.DD_TRACE_SPAN_LEAK_DEBUG,
|
|
522
|
+
0
|
|
523
|
+
)
|
|
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
|
+
|
|
543
538
|
const ingestion = options.ingestion || {}
|
|
544
539
|
const dogstatsd = coalesce(options.dogstatsd, {})
|
|
545
540
|
const sampler = {
|
|
@@ -573,7 +568,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
573
568
|
this.dsmEnabled = isTrue(DD_DATA_STREAMS_ENABLED)
|
|
574
569
|
this.openAiLogsEnabled = DD_OPENAI_LOGS_ENABLED
|
|
575
570
|
this.apiKey = DD_API_KEY
|
|
576
|
-
this.env = DD_ENV
|
|
577
571
|
this.url = DD_CIVISIBILITY_AGENTLESS_URL ? new URL(DD_CIVISIBILITY_AGENTLESS_URL)
|
|
578
572
|
: getAgentUrl(DD_TRACE_AGENT_URL, options)
|
|
579
573
|
this.site = coalesce(options.site, process.env.DD_SITE, 'datadoghq.com')
|
|
@@ -585,9 +579,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
585
579
|
this.clientIpEnabled = DD_TRACE_CLIENT_IP_ENABLED
|
|
586
580
|
this.clientIpHeader = DD_TRACE_CLIENT_IP_HEADER
|
|
587
581
|
this.plugins = !!coalesce(options.plugins, true)
|
|
588
|
-
this.service = DD_SERVICE
|
|
589
582
|
this.serviceMapping = DD_SERVICE_MAPPING
|
|
590
|
-
this.version = DD_VERSION
|
|
591
583
|
this.dogstatsd = {
|
|
592
584
|
hostname: coalesce(dogstatsd.hostname, process.env.DD_DOGSTATSD_HOSTNAME, this.hostname),
|
|
593
585
|
port: String(coalesce(dogstatsd.port, process.env.DD_DOGSTATSD_PORT, 8125))
|
|
@@ -638,6 +630,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
638
630
|
obfuscatorValueRegex: DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP,
|
|
639
631
|
blockedTemplateHtml: DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML,
|
|
640
632
|
blockedTemplateJson: DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON,
|
|
633
|
+
blockedTemplateGraphql: DD_APPSEC_GRAPHQL_BLOCKED_TEMPLATE_JSON,
|
|
641
634
|
eventTracking: {
|
|
642
635
|
enabled: ['extended', 'safe'].includes(DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING),
|
|
643
636
|
mode: DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING
|
|
@@ -679,6 +672,37 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
679
672
|
// Requires an accompanying DD_APM_OBFUSCATION_MEMCACHED_KEEP_COMMAND=true in the agent
|
|
680
673
|
this.memcachedCommandEnabled = isTrue(DD_TRACE_MEMCACHED_COMMAND_ENABLED)
|
|
681
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
|
+
|
|
682
706
|
if (this.gitMetadataEnabled) {
|
|
683
707
|
this.repositoryUrl = removeUserSensitiveInfo(
|
|
684
708
|
coalesce(
|
|
@@ -711,29 +735,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
711
735
|
}
|
|
712
736
|
}
|
|
713
737
|
}
|
|
714
|
-
|
|
715
|
-
this.stats = {
|
|
716
|
-
enabled: isTrue(DD_TRACE_STATS_COMPUTATION_ENABLED)
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
this.traceId128BitGenerationEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED)
|
|
720
|
-
this.traceId128BitLoggingEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED)
|
|
721
|
-
|
|
722
|
-
this.isGCPFunction = isGCPFunction
|
|
723
|
-
this.isAzureFunctionConsumptionPlan = isAzureFunctionConsumptionPlan
|
|
724
|
-
|
|
725
|
-
tagger.add(this.tags, {
|
|
726
|
-
service: this.service,
|
|
727
|
-
env: this.env,
|
|
728
|
-
version: this.version,
|
|
729
|
-
'runtime-id': uuid()
|
|
730
|
-
})
|
|
731
|
-
|
|
732
|
-
this._applyDefaults()
|
|
733
|
-
this._applyEnvironment()
|
|
734
|
-
this._applyOptions(options)
|
|
735
|
-
this._applyRemote({})
|
|
736
|
-
this._merge()
|
|
737
738
|
}
|
|
738
739
|
|
|
739
740
|
// Supports only a subset of options for now.
|
|
@@ -748,48 +749,93 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
748
749
|
}
|
|
749
750
|
|
|
750
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
|
+
|
|
751
766
|
const defaults = this._defaults = {}
|
|
752
767
|
|
|
768
|
+
this._setValue(defaults, 'service', service)
|
|
769
|
+
this._setValue(defaults, 'env', undefined)
|
|
770
|
+
this._setValue(defaults, 'version', pkg.version)
|
|
753
771
|
this._setUnit(defaults, 'sampleRate', undefined)
|
|
754
772
|
this._setBoolean(defaults, 'logInjection', false)
|
|
755
773
|
this._setArray(defaults, 'headerTags', [])
|
|
774
|
+
this._setValue(defaults, 'tags', {})
|
|
756
775
|
}
|
|
757
776
|
|
|
758
777
|
_applyEnvironment () {
|
|
759
778
|
const {
|
|
760
|
-
|
|
779
|
+
DD_ENV,
|
|
761
780
|
DD_LOGS_INJECTION,
|
|
762
|
-
|
|
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
|
|
763
789
|
} = process.env
|
|
764
790
|
|
|
791
|
+
const tags = {}
|
|
765
792
|
const env = this._env = {}
|
|
766
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)
|
|
767
801
|
this._setUnit(env, 'sampleRate', DD_TRACE_SAMPLE_RATE)
|
|
768
802
|
this._setBoolean(env, 'logInjection', DD_LOGS_INJECTION)
|
|
769
803
|
this._setArray(env, 'headerTags', DD_TRACE_HEADER_TAGS)
|
|
804
|
+
this._setTags(env, 'tags', tags)
|
|
770
805
|
}
|
|
771
806
|
|
|
772
807
|
_applyOptions (options) {
|
|
773
808
|
const opts = this._options = this._options || {}
|
|
809
|
+
const tags = {}
|
|
774
810
|
|
|
775
811
|
options = Object.assign({ ingestion: {} }, options, opts)
|
|
776
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)
|
|
777
818
|
this._setUnit(opts, 'sampleRate', coalesce(options.sampleRate, options.ingestion.sampleRate))
|
|
778
819
|
this._setBoolean(opts, 'logInjection', options.logInjection)
|
|
779
820
|
this._setArray(opts, 'headerTags', options.headerTags)
|
|
821
|
+
this._setTags(opts, 'tags', tags)
|
|
780
822
|
}
|
|
781
823
|
|
|
782
824
|
_applyRemote (options) {
|
|
783
825
|
const opts = this._remote = this._remote || {}
|
|
826
|
+
const tags = {}
|
|
784
827
|
const headerTags = options.tracing_header_tags
|
|
785
828
|
? options.tracing_header_tags.map(tag => {
|
|
786
829
|
return tag.tag_name ? `${tag.header}:${tag.tag_name}` : tag.header
|
|
787
830
|
})
|
|
788
831
|
: undefined
|
|
789
832
|
|
|
833
|
+
tagger.add(tags, options.tracing_tags)
|
|
834
|
+
|
|
790
835
|
this._setUnit(opts, 'sampleRate', options.tracing_sampling_rate)
|
|
791
836
|
this._setBoolean(opts, 'logInjection', options.log_injection_enabled)
|
|
792
837
|
this._setArray(opts, 'headerTags', headerTags)
|
|
838
|
+
this._setTags(opts, 'tags', tags)
|
|
793
839
|
}
|
|
794
840
|
|
|
795
841
|
_setBoolean (obj, name, value) {
|
|
@@ -829,6 +875,14 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
829
875
|
}
|
|
830
876
|
}
|
|
831
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
|
+
|
|
832
886
|
_setValue (obj, name, value) {
|
|
833
887
|
obj[name] = value
|
|
834
888
|
}
|
|
@@ -45,14 +45,73 @@ class StatsPoint {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
class
|
|
48
|
+
class Backlog {
|
|
49
|
+
constructor ({ offset, ...tags }) {
|
|
50
|
+
this._tags = Object.keys(tags).sort().map(key => `${key}:${tags[key]}`)
|
|
51
|
+
this._hash = this._tags.join(',')
|
|
52
|
+
this._offset = offset
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get hash () { return this._hash }
|
|
56
|
+
|
|
57
|
+
get offset () { return this._offset }
|
|
58
|
+
|
|
59
|
+
get tags () { return this._tags }
|
|
60
|
+
|
|
61
|
+
encode () {
|
|
62
|
+
return {
|
|
63
|
+
Tags: this.tags,
|
|
64
|
+
Value: this.offset
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
class StatsBucket {
|
|
70
|
+
constructor () {
|
|
71
|
+
this._checkpoints = new Map()
|
|
72
|
+
this._backlogs = new Map()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
get checkpoints () {
|
|
76
|
+
return this._checkpoints
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
get backlogs () {
|
|
80
|
+
return this._backlogs
|
|
81
|
+
}
|
|
82
|
+
|
|
49
83
|
forCheckpoint (checkpoint) {
|
|
50
84
|
const key = checkpoint.hash
|
|
51
|
-
if (!this.has(key)) {
|
|
52
|
-
this.set(
|
|
85
|
+
if (!this._checkpoints.has(key)) {
|
|
86
|
+
this._checkpoints.set(
|
|
87
|
+
key, new StatsPoint(checkpoint.hash, checkpoint.parentHash, checkpoint.edgeTags)
|
|
88
|
+
)
|
|
53
89
|
}
|
|
54
90
|
|
|
55
|
-
return this.get(key)
|
|
91
|
+
return this._checkpoints.get(key)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Conditionally add a backlog to the bucket. If there is currently an offset
|
|
96
|
+
* matching the backlog's tags, overwrite the offset IFF the backlog's offset
|
|
97
|
+
* is greater than the recorded offset.
|
|
98
|
+
*
|
|
99
|
+
* @typedef {{[key: string]: string}} BacklogData
|
|
100
|
+
* @property {number} offset
|
|
101
|
+
*
|
|
102
|
+
* @param {BacklogData} backlogData
|
|
103
|
+
* @returns {Backlog}
|
|
104
|
+
*/
|
|
105
|
+
forBacklog (backlogData) {
|
|
106
|
+
const backlog = new Backlog(backlogData)
|
|
107
|
+
const existingBacklog = this._backlogs.get(backlog.hash)
|
|
108
|
+
if (existingBacklog !== undefined) {
|
|
109
|
+
if (existingBacklog.offset > backlog.offset) {
|
|
110
|
+
return existingBacklog
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
this._backlogs.set(backlog.hash, backlog)
|
|
114
|
+
return backlog
|
|
56
115
|
}
|
|
57
116
|
}
|
|
58
117
|
|
|
@@ -122,12 +181,12 @@ class DataStreamsProcessor {
|
|
|
122
181
|
}
|
|
123
182
|
|
|
124
183
|
onInterval () {
|
|
125
|
-
const
|
|
126
|
-
if (
|
|
184
|
+
const { Stats } = this._serializeBuckets()
|
|
185
|
+
if (Stats.length === 0) return
|
|
127
186
|
const payload = {
|
|
128
187
|
Env: this.env,
|
|
129
188
|
Service: this.service,
|
|
130
|
-
Stats
|
|
189
|
+
Stats,
|
|
131
190
|
TracerVersion: pkg.version,
|
|
132
191
|
Version: this.version,
|
|
133
192
|
Lang: 'javascript'
|
|
@@ -135,10 +194,19 @@ class DataStreamsProcessor {
|
|
|
135
194
|
this.writer.flush(payload)
|
|
136
195
|
}
|
|
137
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Given a timestamp in nanoseconds, compute and return the closest TimeBucket
|
|
199
|
+
* @param {number} timestamp
|
|
200
|
+
* @returns {StatsBucket}
|
|
201
|
+
*/
|
|
202
|
+
bucketFromTimestamp (timestamp) {
|
|
203
|
+
const bucketTime = Math.round(timestamp - (timestamp % this.bucketSizeNs))
|
|
204
|
+
return this.buckets.forTime(bucketTime)
|
|
205
|
+
}
|
|
206
|
+
|
|
138
207
|
recordCheckpoint (checkpoint, span = null) {
|
|
139
208
|
if (!this.enabled) return
|
|
140
|
-
|
|
141
|
-
this.buckets.forTime(bucketTime)
|
|
209
|
+
this.bucketFromTimestamp(checkpoint.currentTimestamp)
|
|
142
210
|
.forCheckpoint(checkpoint)
|
|
143
211
|
.addLatencies(checkpoint)
|
|
144
212
|
// set DSM pathway hash on span to enable related traces feature on DSM tab, convert from buffer to uint64
|
|
@@ -207,26 +275,52 @@ class DataStreamsProcessor {
|
|
|
207
275
|
return dataStreamsContext
|
|
208
276
|
}
|
|
209
277
|
|
|
278
|
+
recordOffset ({ timestamp, ...backlogData }) {
|
|
279
|
+
if (!this.enabled) return
|
|
280
|
+
return this.bucketFromTimestamp(timestamp)
|
|
281
|
+
.forBacklog(backlogData)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
setOffset (offsetObj) {
|
|
285
|
+
if (!this.enabled) return
|
|
286
|
+
const nowNs = Date.now() * 1e6
|
|
287
|
+
const backlogData = {
|
|
288
|
+
...offsetObj,
|
|
289
|
+
timestamp: nowNs
|
|
290
|
+
}
|
|
291
|
+
this.recordOffset(backlogData)
|
|
292
|
+
}
|
|
293
|
+
|
|
210
294
|
_serializeBuckets () {
|
|
295
|
+
// TimeBuckets
|
|
211
296
|
const serializedBuckets = []
|
|
212
297
|
|
|
213
298
|
for (const [ timeNs, bucket ] of this.buckets.entries()) {
|
|
214
299
|
const points = []
|
|
215
300
|
|
|
216
|
-
|
|
301
|
+
// bucket: StatsBucket
|
|
302
|
+
// stats: StatsPoint
|
|
303
|
+
for (const stats of bucket._checkpoints.values()) {
|
|
217
304
|
points.push(stats.encode())
|
|
218
305
|
}
|
|
219
306
|
|
|
307
|
+
const backlogs = []
|
|
308
|
+
for (const backlog of bucket._backlogs.values()) {
|
|
309
|
+
backlogs.push(backlog.encode())
|
|
310
|
+
}
|
|
220
311
|
serializedBuckets.push({
|
|
221
312
|
Start: new Uint64(timeNs),
|
|
222
313
|
Duration: new Uint64(this.bucketSizeNs),
|
|
223
|
-
Stats: points
|
|
314
|
+
Stats: points,
|
|
315
|
+
Backlogs: backlogs
|
|
224
316
|
})
|
|
225
317
|
}
|
|
226
318
|
|
|
227
319
|
this.buckets.clear()
|
|
228
320
|
|
|
229
|
-
return
|
|
321
|
+
return {
|
|
322
|
+
Stats: serializedBuckets
|
|
323
|
+
}
|
|
230
324
|
}
|
|
231
325
|
}
|
|
232
326
|
|
|
@@ -234,6 +328,7 @@ module.exports = {
|
|
|
234
328
|
DataStreamsProcessor: DataStreamsProcessor,
|
|
235
329
|
StatsPoint: StatsPoint,
|
|
236
330
|
StatsBucket: StatsBucket,
|
|
331
|
+
Backlog,
|
|
237
332
|
TimeBuckets,
|
|
238
333
|
getMessageSize,
|
|
239
334
|
getHeadersSize,
|
|
@@ -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
|
|
@@ -13,6 +13,7 @@ const log = require('../log')
|
|
|
13
13
|
const { storage } = require('../../../datadog-core')
|
|
14
14
|
const telemetryMetrics = require('../telemetry/metrics')
|
|
15
15
|
const { channel } = require('dc-polyfill')
|
|
16
|
+
const spanleak = require('../spanleak')
|
|
16
17
|
|
|
17
18
|
const tracerMetrics = telemetryMetrics.manager.namespace('tracers')
|
|
18
19
|
|
|
@@ -90,6 +91,7 @@ class DatadogSpan {
|
|
|
90
91
|
|
|
91
92
|
unfinishedRegistry.register(this, operationName, this)
|
|
92
93
|
}
|
|
94
|
+
spanleak.addSpan(this, operationName)
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
toString () {
|
|
@@ -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
|