dd-trace 6.13.0 → 6.14.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 +3 -1
- package/ci/init.js +8 -3
- package/ci/test-optimization-validation/ci-package-scripts.js +2 -2
- package/ci/test-optimization-validation/ci-remediation.js +6 -6
- package/ci/test-optimization-validation/command-blocker.js +7 -5
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +1 -1
- package/ci/test-optimization-validation/framework-adapters/vitest.js +3 -3
- package/ci/test-optimization-validation/package-check.js +1 -1
- package/ci/test-optimization-validation/report-writer.js +7 -5
- package/ci/vitest-no-worker-init-runner-setup.mjs +8 -0
- package/ci/vitest-no-worker-init-setup.mjs +13 -13
- package/ci/vitest-no-worker-init-v5-setup.mjs +4 -0
- package/package.json +13 -10
- package/packages/datadog-esbuild/index.js +3 -1
- package/packages/datadog-instrumentations/src/cypress-config.js +19 -17
- package/packages/datadog-instrumentations/src/fs.js +24 -20
- package/packages/datadog-instrumentations/src/google-cloud-vertexai.js +2 -2
- package/packages/datadog-instrumentations/src/graphql.js +16 -16
- package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +504 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +265 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +95 -30
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/ai.js +0 -25
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql-jit.js +83 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql.js +85 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/mercurius.js +30 -12
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +13 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +251 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +11 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +562 -27
- package/packages/datadog-instrumentations/src/jest.js +25 -20
- package/packages/datadog-instrumentations/src/knex.js +76 -0
- package/packages/datadog-instrumentations/src/mariadb.js +6 -0
- package/packages/datadog-instrumentations/src/mocha/common.js +59 -2
- package/packages/datadog-instrumentations/src/mocha/main.js +25 -15
- package/packages/datadog-instrumentations/src/mocha/utils.js +2 -1
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +98 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +12 -8
- package/packages/datadog-instrumentations/src/net.js +14 -17
- package/packages/datadog-instrumentations/src/next.js +212 -62
- package/packages/datadog-instrumentations/src/openai.js +42 -40
- package/packages/datadog-instrumentations/src/pg.js +15 -0
- package/packages/datadog-instrumentations/src/playwright.js +109 -13
- package/packages/datadog-instrumentations/src/rum-browser-scripts.js +40 -0
- package/packages/datadog-instrumentations/src/sequelize.js +94 -2
- package/packages/datadog-instrumentations/src/undici.js +53 -4
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +37 -3
- package/packages/datadog-instrumentations/src/vitest-main.js +92 -9
- package/packages/datadog-instrumentations/src/vitest-worker.js +71 -14
- package/packages/datadog-instrumentations/src/webdriverio.js +965 -6
- package/packages/datadog-plugin-amqp10/src/consumer.js +3 -1
- package/packages/datadog-plugin-amqp10/src/producer.js +3 -1
- package/packages/datadog-plugin-amqp10/src/util.js +2 -1
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +6 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +16 -5
- package/packages/datadog-plugin-cassandra-driver/src/index.js +8 -3
- package/packages/datadog-plugin-cucumber/src/index.js +0 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +262 -48
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +4 -1
- package/packages/datadog-plugin-graphql/src/execute.js +998 -196
- package/packages/datadog-plugin-graphql/src/index.js +27 -7
- package/packages/datadog-plugin-graphql/src/jit.js +136 -0
- package/packages/datadog-plugin-graphql/src/request.js +18 -27
- package/packages/datadog-plugin-graphql/src/resolve-error.js +108 -0
- package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -2
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +45 -3
- package/packages/datadog-plugin-graphql/src/utils.js +208 -120
- package/packages/datadog-plugin-graphql/src/validate.js +10 -23
- package/packages/datadog-plugin-jest/src/index.js +0 -6
- package/packages/datadog-plugin-langchain/src/tracing.js +7 -0
- package/packages/datadog-plugin-mocha/src/index.js +403 -75
- package/packages/datadog-plugin-mongodb-core/src/query.js +6 -0
- package/packages/datadog-plugin-mysql/src/index.js +41 -15
- package/packages/datadog-plugin-net/src/tcp.js +3 -1
- package/packages/datadog-plugin-next/src/index.js +63 -29
- package/packages/datadog-plugin-playwright/src/index.js +167 -27
- package/packages/datadog-plugin-undici/src/index.js +27 -41
- package/packages/datadog-plugin-vitest/src/index.js +6 -12
- package/packages/dd-trace/src/aiguard/evaluation.js +2 -1
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +8 -1
- package/packages/dd-trace/src/aiguard/messages/openai.js +8 -1
- package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +20 -6
- package/packages/dd-trace/src/appsec/api_security/index.js +23 -6
- package/packages/dd-trace/src/appsec/api_security/sampler.js +99 -40
- package/packages/dd-trace/src/appsec/graphql.js +6 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +3 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +8 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +11 -36
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/lambda.js +44 -26
- package/packages/dd-trace/src/ci-visibility/encode/json-encoder.js +32 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +8 -8
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +6 -4
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +20 -4
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +5 -173
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +7 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agents.js +54 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/writer.js +1 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +394 -225
- package/packages/dd-trace/src/ci-visibility/exporters/limits.js +9 -0
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +323 -31
- package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +42 -0
- package/packages/dd-trace/src/ci-visibility/final-flush.js +2 -1
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +57 -18
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +0 -3
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +164 -71
- package/packages/dd-trace/src/ci-visibility/requests/video-request.js +176 -0
- package/packages/dd-trace/src/ci-visibility/telemetry.js +10 -7
- package/packages/dd-trace/src/ci-visibility/test-video.js +61 -0
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -0
- package/packages/dd-trace/src/config/index.js +73 -13
- package/packages/dd-trace/src/config/parsers.js +11 -1
- package/packages/dd-trace/src/config/stable.js +3 -3
- package/packages/dd-trace/src/config/supported-configurations.json +20 -2
- package/packages/dd-trace/src/crashtracking/crashtracker.js +82 -18
- package/packages/dd-trace/src/debugger/config.js +12 -1
- package/packages/dd-trace/src/debugger/constants.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +2 -1
- package/packages/dd-trace/src/debugger/devtools_client/request-options.js +33 -0
- package/packages/dd-trace/src/debugger/devtools_client/send.js +7 -40
- package/packages/dd-trace/src/debugger/devtools_client/status.js +11 -6
- package/packages/dd-trace/src/debugger/devtools_client/tags.js +41 -0
- package/packages/dd-trace/src/debugger/index.js +23 -3
- package/packages/dd-trace/src/dogstatsd.js +510 -76
- package/packages/dd-trace/src/encode/0.4-cross-payload.js +170 -0
- package/packages/dd-trace/src/encode/0.4.js +5 -5
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +9 -8
- package/packages/dd-trace/src/evp_proxy/direct.js +27 -23
- package/packages/dd-trace/src/exporters/agent/index.js +2 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +24 -7
- package/packages/dd-trace/src/exporters/agentless/index.js +7 -9
- package/packages/dd-trace/src/exporters/agentless/writer.js +100 -118
- package/packages/dd-trace/src/exporters/common/agents.js +28 -6
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -2
- package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +191 -0
- package/packages/dd-trace/src/exporters/common/request.js +31 -11
- package/packages/dd-trace/src/exporters/common/url.js +40 -1
- package/packages/dd-trace/src/exporters/common/writer.js +9 -7
- package/packages/dd-trace/src/flush.js +6 -3
- package/packages/dd-trace/src/id.js +14 -0
- package/packages/dd-trace/src/index.js +5 -2
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +2 -1
- package/packages/dd-trace/src/llmobs/index.js +32 -32
- package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +22 -71
- package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +23 -13
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +7 -0
- package/packages/dd-trace/src/llmobs/util.js +0 -33
- package/packages/dd-trace/src/llmobs/writers/base.js +49 -32
- package/packages/dd-trace/src/log/index.js +7 -1
- package/packages/dd-trace/src/{ci-visibility/log-submission → log-submission}/log-submission-plugin.js +48 -19
- package/packages/dd-trace/src/openfeature/writers/base.js +14 -12
- package/packages/dd-trace/src/openfeature/writers/util.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/index.js +5 -24
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +14 -4
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +15 -22
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +14 -4
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +10 -0
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +19 -4
- package/packages/dd-trace/src/opentelemetry/resource-attributes.js +55 -0
- package/packages/dd-trace/src/opentelemetry/trace/index.js +6 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +10 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +93 -18
- package/packages/dd-trace/src/payload-tagging/index.js +2 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +1 -6
- package/packages/dd-trace/src/plugins/tracing.js +12 -10
- package/packages/dd-trace/src/plugins/util/ci.js +3 -1
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +16 -15
- package/packages/dd-trace/src/plugins/util/test.js +83 -20
- package/packages/dd-trace/src/plugins/util/url.js +2 -2
- package/packages/dd-trace/src/plugins/util/web.js +4 -9
- package/packages/dd-trace/src/profiling/config.js +1 -0
- package/packages/dd-trace/src/profiling/oom.js +7 -2
- package/packages/dd-trace/src/profiling/profiler.js +23 -13
- package/packages/dd-trace/src/profiling/profilers/space.js +38 -11
- package/packages/dd-trace/src/profiling/webspan-utils.js +7 -4
- package/packages/dd-trace/src/proxy.js +75 -5
- package/packages/dd-trace/src/remote_config/index.js +319 -101
- package/packages/dd-trace/src/remote_config/scheduler.js +37 -12
- package/packages/dd-trace/src/runtime_metrics/client.js +37 -8
- package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +5 -1
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -1
- package/packages/dd-trace/src/sampling_rule.js +36 -9
- package/packages/dd-trace/src/serverless/telemetry-delivery-tracker.js +4 -8
- package/packages/dd-trace/src/serverless/vercel.js +53 -20
- package/packages/dd-trace/src/serverless.js +10 -3
- package/packages/dd-trace/src/service-naming/schemas/util.js +1 -1
- package/packages/dd-trace/src/span_stats.js +24 -28
- package/packages/dd-trace/src/startup-log.js +3 -2
- package/packages/dd-trace/src/telemetry/agentless-url.js +28 -0
- package/packages/dd-trace/src/telemetry/send-data.js +18 -16
- package/packages/dd-trace/src/telemetry/session-propagation.js +3 -2
- package/packages/dd-trace/src/tracer.js +4 -5
- package/packages/dd-trace/src/tracer_metadata.js +11 -3
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/packages/datadog-instrumentations/src/playwright-browser-scripts.js +0 -27
- package/packages/dd-trace/src/encode/agentless-json.js +0 -210
|
@@ -85,6 +85,18 @@ const percentByte = /%([0-9A-Fa-f]{2})/g
|
|
|
85
85
|
* @property {string} [traceId]
|
|
86
86
|
*/
|
|
87
87
|
|
|
88
|
+
/**
|
|
89
|
+
* @param {Array<string | undefined>} traceTagReplacements
|
|
90
|
+
* @param {string} key
|
|
91
|
+
* @returns {boolean}
|
|
92
|
+
*/
|
|
93
|
+
function hasTraceTagReplacement (traceTagReplacements, key) {
|
|
94
|
+
for (let index = 0; index < traceTagReplacements.length; index += 2) {
|
|
95
|
+
if (traceTagReplacements[index] === key) return true
|
|
96
|
+
}
|
|
97
|
+
return false
|
|
98
|
+
}
|
|
99
|
+
|
|
88
100
|
/**
|
|
89
101
|
* @param {string | undefined} traceId
|
|
90
102
|
* @param {string | undefined} spanId
|
|
@@ -314,18 +326,31 @@ class TextMapPropagator {
|
|
|
314
326
|
|
|
315
327
|
const injectTraceContext = this.#config.apmTracingEnabled !== false ||
|
|
316
328
|
hasTraceSourcePropagationTag(spanContext._trace.tags)
|
|
329
|
+
let traceTagReplacements
|
|
330
|
+
let optionalTraceTagCount = 0
|
|
331
|
+
if (injectTraceContext && injectCh.hasSubscribers && (
|
|
332
|
+
this.#hasPropagationStyle('inject', 'datadog') || this.#hasPropagationStyle('inject', 'tracecontext')
|
|
333
|
+
)) {
|
|
334
|
+
const injection = { spanContext }
|
|
335
|
+
injectCh.publish(injection)
|
|
336
|
+
traceTagReplacements = injection.traceTagReplacements
|
|
337
|
+
optionalTraceTagCount = injection.optionalTraceTagCount ?? 0
|
|
338
|
+
}
|
|
317
339
|
if (injectTraceContext) {
|
|
318
|
-
injectedCarrier = this.#injectDatadog(
|
|
340
|
+
injectedCarrier = this.#injectDatadog(
|
|
341
|
+
spanContext, injectedCarrier ?? carrier, traceTagReplacements, optionalTraceTagCount
|
|
342
|
+
) ?? injectedCarrier
|
|
319
343
|
injectedCarrier = this.#injectB3MultipleHeaders(spanContext, injectedCarrier ?? carrier) ?? injectedCarrier
|
|
320
344
|
injectedCarrier = this.#injectB3SingleHeader(spanContext, injectedCarrier ?? carrier) ?? injectedCarrier
|
|
321
345
|
}
|
|
322
346
|
injectedCarrier = this
|
|
323
|
-
.#injectTraceparent(
|
|
347
|
+
.#injectTraceparent(
|
|
348
|
+
spanContext, injectedCarrier ?? carrier, injectTraceContext, traceTagReplacements
|
|
349
|
+
) ?? injectedCarrier
|
|
324
350
|
|
|
325
351
|
if (injectedCarrier === undefined) return
|
|
326
352
|
|
|
327
353
|
carrier = injectedCarrier
|
|
328
|
-
if (injectCh.hasSubscribers) injectCh.publish({ spanContext, carrier })
|
|
329
354
|
|
|
330
355
|
// eslint-disable-next-line eslint-rules/eslint-log-printf-style
|
|
331
356
|
log.debug(() => `Inject into carrier: ${JSON.stringify(pickTextMap(carrier))}.`)
|
|
@@ -359,9 +384,11 @@ class TextMapPropagator {
|
|
|
359
384
|
/**
|
|
360
385
|
* @param {DatadogSpanContext} spanContext
|
|
361
386
|
* @param {Record<string, string>} [carrier]
|
|
387
|
+
* @param {Array<string | undefined>} [traceTagReplacements]
|
|
388
|
+
* @param {number} optionalTraceTagCount
|
|
362
389
|
* @returns {Record<string, string> | undefined}
|
|
363
390
|
*/
|
|
364
|
-
#injectDatadog (spanContext, carrier) {
|
|
391
|
+
#injectDatadog (spanContext, carrier, traceTagReplacements, optionalTraceTagCount) {
|
|
365
392
|
if (!this.#hasPropagationStyle('inject', 'datadog')) return
|
|
366
393
|
|
|
367
394
|
carrier ??= {}
|
|
@@ -374,7 +401,7 @@ class TextMapPropagator {
|
|
|
374
401
|
const priority = spanContext._sampling.priority
|
|
375
402
|
if (Number.isInteger(priority)) writeDatadogSamplingPriority(carrier, priority.toString())
|
|
376
403
|
|
|
377
|
-
this.#injectTags(spanContext,
|
|
404
|
+
this.#injectTags(carrier, spanContext._trace.tags, traceTagReplacements, optionalTraceTagCount)
|
|
378
405
|
|
|
379
406
|
return carrier
|
|
380
407
|
}
|
|
@@ -449,23 +476,27 @@ class TextMapPropagator {
|
|
|
449
476
|
}
|
|
450
477
|
|
|
451
478
|
/**
|
|
452
|
-
* @param {DatadogSpanContext} spanContext
|
|
453
479
|
* @param {Record<string, string>} carrier
|
|
480
|
+
* @param {Record<string, string>} traceTags
|
|
481
|
+
* @param {Array<string | undefined>} [traceTagReplacements]
|
|
482
|
+
* @param {number} optionalTraceTagCount
|
|
454
483
|
* @returns {void}
|
|
455
484
|
*/
|
|
456
|
-
#injectTags (
|
|
457
|
-
const trace = spanContext._trace
|
|
458
|
-
|
|
485
|
+
#injectTags (carrier, traceTags, traceTagReplacements, optionalTraceTagCount) {
|
|
459
486
|
if (this.#config.DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH === 0) {
|
|
460
487
|
log.debug('Trace tag propagation is disabled, skipping injection.')
|
|
461
488
|
return
|
|
462
489
|
}
|
|
463
490
|
|
|
491
|
+
const maxLength = this.#config.DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH
|
|
464
492
|
let header = ''
|
|
465
493
|
|
|
466
|
-
for (const key of Object.keys(
|
|
467
|
-
const value =
|
|
468
|
-
if (!value || !key.startsWith('_dd.p.')
|
|
494
|
+
for (const key of Object.keys(traceTags)) {
|
|
495
|
+
const value = traceTags[key]
|
|
496
|
+
if (!value || !key.startsWith('_dd.p.') ||
|
|
497
|
+
traceTagReplacements && hasTraceTagReplacement(traceTagReplacements, key)) {
|
|
498
|
+
continue
|
|
499
|
+
}
|
|
469
500
|
if (!tagKeyExpr.test(key) || !tagValueExpr.test(value)) {
|
|
470
501
|
log.error('Trace tags from span are invalid, skipping injection.')
|
|
471
502
|
return
|
|
@@ -475,7 +506,24 @@ class TextMapPropagator {
|
|
|
475
506
|
header += `${key}=${value}`
|
|
476
507
|
}
|
|
477
508
|
|
|
478
|
-
if (
|
|
509
|
+
if (traceTagReplacements) {
|
|
510
|
+
const requiredEntryCount = traceTagReplacements.length - optionalTraceTagCount * 2
|
|
511
|
+
for (let index = 0; index < traceTagReplacements.length; index += 2) {
|
|
512
|
+
const key = traceTagReplacements[index]
|
|
513
|
+
const value = traceTagReplacements[index + 1]
|
|
514
|
+
if (!value || !key.startsWith('_dd.p.')) continue
|
|
515
|
+
if (!tagKeyExpr.test(key) || !tagValueExpr.test(value)) {
|
|
516
|
+
log.error('Trace tags from span are invalid, skipping injection.')
|
|
517
|
+
return
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const entry = `${header ? ',' : ''}${key}=${value}`
|
|
521
|
+
if (index >= requiredEntryCount && header.length + entry.length > maxLength) break
|
|
522
|
+
header += entry
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
if (header.length > maxLength) {
|
|
479
527
|
log.error('Trace tags from span are too large, skipping injection.')
|
|
480
528
|
} else if (header) {
|
|
481
529
|
writeDatadogTags(carrier, header)
|
|
@@ -538,9 +586,10 @@ class TextMapPropagator {
|
|
|
538
586
|
* @param {DatadogSpanContext} spanContext
|
|
539
587
|
* @param {Record<string, string> | undefined} carrier
|
|
540
588
|
* @param {boolean} injectTraceContext
|
|
589
|
+
* @param {Array<string | undefined>} [traceTagReplacements]
|
|
541
590
|
* @returns {Record<string, string> | undefined}
|
|
542
591
|
*/
|
|
543
|
-
#injectTraceparent (spanContext, carrier, injectTraceContext) {
|
|
592
|
+
#injectTraceparent (spanContext, carrier, injectTraceContext, traceTagReplacements) {
|
|
544
593
|
if (!this.#hasPropagationStyle('inject', 'tracecontext')) return
|
|
545
594
|
|
|
546
595
|
if (!injectTraceContext) {
|
|
@@ -556,9 +605,12 @@ class TextMapPropagator {
|
|
|
556
605
|
carrier ??= {}
|
|
557
606
|
const {
|
|
558
607
|
_sampling: { priority, mechanism },
|
|
559
|
-
_tracestate
|
|
560
|
-
_trace: { origin
|
|
608
|
+
_tracestate,
|
|
609
|
+
_trace: { origin },
|
|
561
610
|
} = spanContext
|
|
611
|
+
const ts = traceTagReplacements
|
|
612
|
+
? TraceState.fromString(_tracestate?.toString())
|
|
613
|
+
: _tracestate ?? new TraceState()
|
|
562
614
|
|
|
563
615
|
writeTraceparent(carrier, spanContext.toTraceparent())
|
|
564
616
|
|
|
@@ -584,8 +636,9 @@ class TextMapPropagator {
|
|
|
584
636
|
state.set('o', originValue)
|
|
585
637
|
}
|
|
586
638
|
|
|
587
|
-
for (const key of Object.keys(
|
|
588
|
-
|
|
639
|
+
for (const key of Object.keys(spanContext._trace.tags)) {
|
|
640
|
+
if (traceTagReplacements && hasTraceTagReplacement(traceTagReplacements, key)) continue
|
|
641
|
+
const tagValueRaw = spanContext._trace.tags[key]
|
|
589
642
|
if (!tagValueRaw || !key.startsWith('_dd.p.')) continue
|
|
590
643
|
|
|
591
644
|
const tagKey = 't.' + key.slice(6)
|
|
@@ -598,6 +651,28 @@ class TextMapPropagator {
|
|
|
598
651
|
|
|
599
652
|
state.set(tagKey, tagValue)
|
|
600
653
|
}
|
|
654
|
+
|
|
655
|
+
if (traceTagReplacements) {
|
|
656
|
+
for (let index = 0; index < traceTagReplacements.length; index += 2) {
|
|
657
|
+
const key = traceTagReplacements[index]
|
|
658
|
+
if (!key.startsWith('_dd.p.')) continue
|
|
659
|
+
|
|
660
|
+
const tagKey = 't.' + key.slice(6)
|
|
661
|
+
.replaceAll(tracestateTagKeyFilter, '_')
|
|
662
|
+
const tagValueRaw = traceTagReplacements[index + 1]
|
|
663
|
+
if (!tagValueRaw) {
|
|
664
|
+
state.delete(tagKey)
|
|
665
|
+
continue
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
const tagValue = tagValueRaw
|
|
669
|
+
.toString()
|
|
670
|
+
.replaceAll(tracestateTagValueFilter, '_')
|
|
671
|
+
.replaceAll('=', '~')
|
|
672
|
+
|
|
673
|
+
state.set(tagKey, tagValue)
|
|
674
|
+
}
|
|
675
|
+
}
|
|
601
676
|
})
|
|
602
677
|
|
|
603
678
|
writeTracestate(carrier, ts.toString())
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const createRfdc = require('../../../../vendor/dist/rfdc')
|
|
4
|
+
const rfdc = createRfdc({ proto: false, circles: false })
|
|
4
5
|
|
|
5
6
|
const {
|
|
6
7
|
PAYLOAD_TAG_REQUEST_PREFIX,
|
|
@@ -728,12 +728,7 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
728
728
|
this._bufferWorkerTrace(missingTestSuite, trace)
|
|
729
729
|
return
|
|
730
730
|
}
|
|
731
|
-
|
|
732
|
-
if (exporter.exportTraceWithDeferredTestSuite) {
|
|
733
|
-
exporter.exportTraceWithDeferredTestSuite(trace)
|
|
734
|
-
} else {
|
|
735
|
-
exporter.export(trace)
|
|
736
|
-
}
|
|
731
|
+
this.tracer._exporter.export(trace)
|
|
737
732
|
}
|
|
738
733
|
|
|
739
734
|
/**
|
|
@@ -243,19 +243,21 @@ class TracingPlugin extends Plugin {
|
|
|
243
243
|
serviceSource = undefined
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
+
const tags = {
|
|
247
|
+
[COMPONENT]: component,
|
|
248
|
+
'service.name': serviceName || tracer._service,
|
|
249
|
+
'resource.name': resource,
|
|
250
|
+
'span.kind': kind,
|
|
251
|
+
'span.type': type,
|
|
252
|
+
...meta,
|
|
253
|
+
...metrics,
|
|
254
|
+
}
|
|
255
|
+
if (serviceSource !== undefined && !Object.hasOwn(tags, SVC_SRC_KEY)) tags[SVC_SRC_KEY] = serviceSource
|
|
256
|
+
|
|
246
257
|
const span = tracer.startSpan(name, {
|
|
247
258
|
startTime,
|
|
248
259
|
childOf,
|
|
249
|
-
tags
|
|
250
|
-
[COMPONENT]: component,
|
|
251
|
-
'service.name': serviceName || tracer._service,
|
|
252
|
-
'resource.name': resource,
|
|
253
|
-
'span.kind': kind,
|
|
254
|
-
'span.type': type,
|
|
255
|
-
...(serviceSource === undefined ? undefined : { [SVC_SRC_KEY]: serviceSource }),
|
|
256
|
-
...meta,
|
|
257
|
-
...metrics,
|
|
258
|
-
},
|
|
260
|
+
tags,
|
|
259
261
|
integrationName: integrationName || component,
|
|
260
262
|
links: childOf?._links,
|
|
261
263
|
})
|
|
@@ -45,7 +45,9 @@ function parseEmailAndName (emailAndName) {
|
|
|
45
45
|
}
|
|
46
46
|
let name = ''
|
|
47
47
|
let email = ''
|
|
48
|
-
|
|
48
|
+
// Untrusted git author metadata (a fork PR controls it). The anchor fixes the start position, the
|
|
49
|
+
// email classes cannot overlap around `@`, and the slice bounds the optional name part.
|
|
50
|
+
const matchNameAndEmail = emailAndName.slice(0, 1024).match(/^(?:"?([^"]*)"?\s)?<?([^\s@]+@[^\s>]+)>?/)
|
|
49
51
|
if (matchNameAndEmail) {
|
|
50
52
|
name = matchNameAndEmail[1]
|
|
51
53
|
email = matchNameAndEmail[2]
|
|
@@ -69,26 +69,27 @@ function createInferredProxySpan (headers, childOf, tracer, reqCtx, traceCtx, co
|
|
|
69
69
|
|
|
70
70
|
log.debug('Successfully extracted inferred span info %s for proxy:', proxyContext, proxyContext.proxySystemName)
|
|
71
71
|
|
|
72
|
+
const meta = {
|
|
73
|
+
service: proxyContext.domainName || tracer._config.service,
|
|
74
|
+
component: proxySpanInfo.component,
|
|
75
|
+
[SPAN_TYPE]: 'web',
|
|
76
|
+
[SPAN_KIND]: 'server',
|
|
77
|
+
[HTTP_METHOD]: proxyContext.method,
|
|
78
|
+
[HTTP_URL]: 'https://' + proxyContext.domainName + proxyContext.path,
|
|
79
|
+
stage: proxyContext.stage,
|
|
80
|
+
region: proxyContext.region,
|
|
81
|
+
}
|
|
82
|
+
if (proxyContext.resourcePath) meta[HTTP_ROUTE] = proxyContext.resourcePath
|
|
83
|
+
if (proxyContext.accountId) meta.account_id = proxyContext.accountId
|
|
84
|
+
if (proxyContext.apiId) meta.apiid = proxyContext.apiId
|
|
85
|
+
if (proxyContext.awsUser) meta.aws_user = proxyContext.awsUser
|
|
86
|
+
|
|
72
87
|
const span = startSpanHelper(tracer, proxySpanInfo.spanName, {
|
|
73
88
|
childOf,
|
|
74
89
|
type: 'web',
|
|
75
90
|
startTime: proxyContext.requestTime,
|
|
76
91
|
integrationName: proxySpanInfo.component,
|
|
77
|
-
meta
|
|
78
|
-
service: proxyContext.domainName || tracer._config.service,
|
|
79
|
-
component: proxySpanInfo.component,
|
|
80
|
-
[SPAN_TYPE]: 'web',
|
|
81
|
-
[SPAN_KIND]: 'server',
|
|
82
|
-
[HTTP_METHOD]: proxyContext.method,
|
|
83
|
-
[HTTP_URL]: 'https://' + proxyContext.domainName + proxyContext.path,
|
|
84
|
-
stage: proxyContext.stage,
|
|
85
|
-
region: proxyContext.region,
|
|
86
|
-
...(proxyContext.resourcePath && { [HTTP_ROUTE]: proxyContext.resourcePath }),
|
|
87
|
-
...(proxyContext.accountId && { account_id: proxyContext.accountId }),
|
|
88
|
-
...(proxyContext.apiId && { apiid: proxyContext.apiId }),
|
|
89
|
-
...(proxyContext.region && { region: proxyContext.region }),
|
|
90
|
-
...(proxyContext.awsUser && { aws_user: proxyContext.awsUser }),
|
|
91
|
-
},
|
|
92
|
+
meta,
|
|
92
93
|
}, traceCtx, config)
|
|
93
94
|
|
|
94
95
|
reqCtx.inferredProxySpan = span
|
|
@@ -108,6 +108,9 @@ const TEST_SOURCE_FILE = 'test.source.file'
|
|
|
108
108
|
const TEST_SOURCE_START = 'test.source.start'
|
|
109
109
|
const TEST_FAILURE_SCREENSHOT_UPLOADED = 'test.failure_screenshot.uploaded'
|
|
110
110
|
const TEST_FAILURE_SCREENSHOT_UPLOAD_ERROR = 'test.failure_screenshot.upload_error'
|
|
111
|
+
const TEST_FAILURE_VIDEO_UPLOADED = 'test.failure_video.uploaded'
|
|
112
|
+
const TEST_FAILURE_VIDEO_UPLOAD_ERROR = 'test.failure_video.upload_error'
|
|
113
|
+
const TEST_FAILURE_VIDEO_SCOPE = 'test.failure_video.scope'
|
|
111
114
|
const LIBRARY_VERSION = 'library_version'
|
|
112
115
|
const TEST_COMMAND = 'test.command'
|
|
113
116
|
const TEST_MODULE = 'test.module'
|
|
@@ -127,7 +130,7 @@ const TEST_IS_MODIFIED = 'test.is_modified'
|
|
|
127
130
|
const TEST_HAS_DYNAMIC_NAME = '_dd.has_dynamic_name'
|
|
128
131
|
const CI_APP_ORIGIN = 'ciapp-test'
|
|
129
132
|
// eslint-disable-next-line no-control-regex
|
|
130
|
-
const TEST_OPTIMIZATION_NAME_CONTROL_RE = /[\u0000-\u0008\
|
|
133
|
+
const TEST_OPTIMIZATION_NAME_CONTROL_RE = /[\u0000-\u0008\v\f\u000E-\u001F\u007F-\u009F]/g
|
|
131
134
|
const TEST_OPTIMIZATION_NAME_WHITESPACE_RE = /\s+/g
|
|
132
135
|
|
|
133
136
|
// Matches patterns that are almost certainly runtime-generated values in test names:
|
|
@@ -474,6 +477,9 @@ module.exports = {
|
|
|
474
477
|
TEST_SOURCE_FILE,
|
|
475
478
|
TEST_FAILURE_SCREENSHOT_UPLOADED,
|
|
476
479
|
TEST_FAILURE_SCREENSHOT_UPLOAD_ERROR,
|
|
480
|
+
TEST_FAILURE_VIDEO_UPLOADED,
|
|
481
|
+
TEST_FAILURE_VIDEO_UPLOAD_ERROR,
|
|
482
|
+
TEST_FAILURE_VIDEO_SCOPE,
|
|
477
483
|
CI_APP_ORIGIN,
|
|
478
484
|
LIBRARY_VERSION,
|
|
479
485
|
JEST_WORKER_TRACE_PAYLOAD_CODE,
|
|
@@ -1605,19 +1611,77 @@ function fromCoverageMapToCoverage (coverageMap) {
|
|
|
1605
1611
|
}, {})
|
|
1606
1612
|
}
|
|
1607
1613
|
|
|
1614
|
+
/**
|
|
1615
|
+
* @param {number} code
|
|
1616
|
+
* @returns {boolean}
|
|
1617
|
+
*/
|
|
1618
|
+
function isAsciiDigit (code) {
|
|
1619
|
+
return code >= 0x30 && code <= 0x39
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
/**
|
|
1623
|
+
* Parse a V8 stack frame into its file path and 1-based line number.
|
|
1624
|
+
*
|
|
1625
|
+
* Stack text includes caller-controlled function names and can be overwritten. Scan numeric suffixes
|
|
1626
|
+
* right-to-left and discard V8's trailing anonymous location for eval frames.
|
|
1627
|
+
* @param {string} frame
|
|
1628
|
+
* @param {string} expectedPath A known path contained in the frame.
|
|
1629
|
+
* @returns {{ file: string, line: number } | null}
|
|
1630
|
+
*/
|
|
1631
|
+
function parseStackFrameLocation (frame, expectedPath) {
|
|
1632
|
+
let pathStart = frame.lastIndexOf(expectedPath)
|
|
1633
|
+
while (frame.charCodeAt(pathStart - 1) !== 0x28 /* ( */ &&
|
|
1634
|
+
!frame.startsWith('at ', pathStart - 3) &&
|
|
1635
|
+
!frame.startsWith('file://', pathStart - 7)) {
|
|
1636
|
+
const previousPathStart = frame.lastIndexOf(expectedPath, pathStart - 1)
|
|
1637
|
+
if (previousPathStart === -1) break
|
|
1638
|
+
pathStart = previousPathStart
|
|
1639
|
+
}
|
|
1640
|
+
const scope = frame.slice(pathStart)
|
|
1641
|
+
let end = scope.length
|
|
1642
|
+
if (scope.charCodeAt(end - 1) === 0x29 /* ) */) end--
|
|
1643
|
+
|
|
1644
|
+
while (true) {
|
|
1645
|
+
let lastNumberStart = end
|
|
1646
|
+
while (lastNumberStart > 0 && isAsciiDigit(scope.charCodeAt(lastNumberStart - 1))) {
|
|
1647
|
+
lastNumberStart--
|
|
1648
|
+
}
|
|
1649
|
+
if (lastNumberStart === end || scope.charCodeAt(lastNumberStart - 1) !== 0x3A /* : */) {
|
|
1650
|
+
return null
|
|
1651
|
+
}
|
|
1652
|
+
const colonBeforeLast = lastNumberStart - 1
|
|
1653
|
+
let lineStart = colonBeforeLast
|
|
1654
|
+
while (lineStart > 0 && isAsciiDigit(scope.charCodeAt(lineStart - 1))) {
|
|
1655
|
+
lineStart--
|
|
1656
|
+
}
|
|
1657
|
+
if (lineStart < colonBeforeLast && scope.charCodeAt(lineStart - 1) === 0x3A /* : */) {
|
|
1658
|
+
const fileEnd = lineStart - 1
|
|
1659
|
+
const anonymousStart = fileEnd - 11
|
|
1660
|
+
if (scope.charCodeAt(fileEnd - 1) === 0x3E /* > */ && anonymousStart >= 3 &&
|
|
1661
|
+
scope.startsWith('<anonymous>', anonymousStart) &&
|
|
1662
|
+
scope.charCodeAt(anonymousStart - 1) === 0x20 /* space */ &&
|
|
1663
|
+
scope.charCodeAt(anonymousStart - 2) === 0x2C /* , */ &&
|
|
1664
|
+
scope.charCodeAt(anonymousStart - 3) === 0x29 /* ) */) {
|
|
1665
|
+
end = anonymousStart - 3
|
|
1666
|
+
while (scope.charCodeAt(end - 1) === 0x29 /* ) */) end--
|
|
1667
|
+
continue
|
|
1668
|
+
}
|
|
1669
|
+
return { file: scope.slice(0, fileEnd), line: Number(scope.slice(lineStart, colonBeforeLast)) }
|
|
1670
|
+
}
|
|
1671
|
+
return { file: scope.slice(0, colonBeforeLast), line: Number(scope.slice(lastNumberStart, end)) }
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1608
1675
|
// Get the start line of a test by inspecting a given error's stack trace
|
|
1609
1676
|
function getTestLineStart (err, testSuitePath) {
|
|
1610
1677
|
if (!err.stack) {
|
|
1611
1678
|
return null
|
|
1612
1679
|
}
|
|
1613
|
-
// From https://github.com/felixge/node-stack-trace/blob/ba06dcdb50d465cd440d84a563836e293b360427/index.js#L40
|
|
1614
1680
|
const testFileLine = err.stack.split('\n').find(line => line.includes(testSuitePath))
|
|
1615
|
-
|
|
1616
|
-
const testFileLineMatch = testFileLine.match(/at (?:(.+?)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/)
|
|
1617
|
-
return Number.parseInt(testFileLineMatch[3], 10) || null
|
|
1618
|
-
} catch {
|
|
1681
|
+
if (!testFileLine) {
|
|
1619
1682
|
return null
|
|
1620
1683
|
}
|
|
1684
|
+
return parseStackFrameLocation(testFileLine, testSuitePath)?.line || null
|
|
1621
1685
|
}
|
|
1622
1686
|
|
|
1623
1687
|
// Get the end line of a test by inspecting a given function's source code
|
|
@@ -1640,7 +1704,7 @@ function parseAnnotations (annotations) {
|
|
|
1640
1704
|
}
|
|
1641
1705
|
const { type, description } = annotation
|
|
1642
1706
|
if (type.startsWith('DD_TAGS')) {
|
|
1643
|
-
const regex =
|
|
1707
|
+
const regex = /^DD_TAGS\[([^\]]*)\]/
|
|
1644
1708
|
const match = regex.exec(type)
|
|
1645
1709
|
let tagValue = ''
|
|
1646
1710
|
if (match) {
|
|
@@ -1744,15 +1808,9 @@ function getFileAndLineNumberFromError (error, repositoryRoot) {
|
|
|
1744
1808
|
}
|
|
1745
1809
|
|
|
1746
1810
|
const topFrame = frames[topRelevantFrameIndex]
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
if (match) {
|
|
1752
|
-
const filePath = match[1]
|
|
1753
|
-
const lineNumber = Number(match[2])
|
|
1754
|
-
|
|
1755
|
-
return [filePath, lineNumber, topRelevantFrameIndex]
|
|
1811
|
+
const location = parseStackFrameLocation(topFrame, repositoryRoot)
|
|
1812
|
+
if (location) {
|
|
1813
|
+
return [location.file, location.line, topRelevantFrameIndex]
|
|
1756
1814
|
}
|
|
1757
1815
|
return []
|
|
1758
1816
|
}
|
|
@@ -2082,12 +2140,17 @@ function formatTestOptimizationList (items) {
|
|
|
2082
2140
|
const more = items.length - shown.length
|
|
2083
2141
|
const moreSuffix = more > 0 ? `\n ... and ${more} more` : ''
|
|
2084
2142
|
|
|
2085
|
-
|
|
2086
|
-
|
|
2143
|
+
let formattedItems = ''
|
|
2144
|
+
let isFirstItem = true
|
|
2145
|
+
for (const { text, suffix } of shown) {
|
|
2146
|
+
if (!isFirstItem) formattedItems += '\n'
|
|
2147
|
+
formattedItems += ` • ${truncateTestOptimizationNameMiddle(
|
|
2087
2148
|
sanitizeTestOptimizationName(text),
|
|
2088
2149
|
MAX_TEST_OPTIMIZATION_NAME_LENGTH
|
|
2089
|
-
)}${suffix ? ` (${suffix})` : ''}`
|
|
2090
|
-
|
|
2150
|
+
)}${suffix ? ` (${suffix})` : ''}`
|
|
2151
|
+
isFirstItem = false
|
|
2152
|
+
}
|
|
2153
|
+
return formattedItems + moreSuffix
|
|
2091
2154
|
}
|
|
2092
2155
|
|
|
2093
2156
|
/**
|
|
@@ -14,7 +14,7 @@ const INT_SEGMENT = /^[1-9][0-9]+$/ // Integer of size at least 2 (>=10)
|
|
|
14
14
|
const INT_ID_SEGMENT = /^(?=.*[0-9])[0-9._-]{3,}$/ // Mixed string with digits and delimiters
|
|
15
15
|
const HEX_SEGMENT = /^(?=.*[0-9])[A-Fa-f0-9]{6,}$/ // Hexadecimal digits of size at least 6 with at least one decimal digit
|
|
16
16
|
const HEX_ID_SEGMENT = /^(?=.*[0-9])[A-Fa-f0-9._-]{6,}$/ // Mixed string with hex digits and delimiters
|
|
17
|
-
const
|
|
17
|
+
const SPECIAL_CHARACTER_SEGMENT = /[%&'()*+,:=@]/
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Extract full URL from HTTP request
|
|
@@ -167,7 +167,7 @@ function calculateHttpEndpoint (url) {
|
|
|
167
167
|
|
|
168
168
|
if (HEX_ID_SEGMENT.test(element)) return '{param:hex_id}'
|
|
169
169
|
|
|
170
|
-
if (
|
|
170
|
+
if (element.length >= 20 || SPECIAL_CHARACTER_SEGMENT.test(element)) return '{param:str}'
|
|
171
171
|
|
|
172
172
|
// No match
|
|
173
173
|
return element
|
|
@@ -35,7 +35,6 @@ const HTTP_CLIENT_IP = tags.HTTP_CLIENT_IP
|
|
|
35
35
|
const MANUAL_DROP = tags.MANUAL_DROP
|
|
36
36
|
|
|
37
37
|
const contexts = new WeakMap()
|
|
38
|
-
const requests = new WeakMap()
|
|
39
38
|
|
|
40
39
|
// TODO: change this to no longer rely on creating a dummy plugin to be able to access startSpan
|
|
41
40
|
function createWebPlugin (tracer, config = {}) {
|
|
@@ -129,7 +128,6 @@ const web = {
|
|
|
129
128
|
context.tracer = tracer
|
|
130
129
|
context.span = span
|
|
131
130
|
context.res = res
|
|
132
|
-
requests.set(span, req)
|
|
133
131
|
|
|
134
132
|
this.setConfig(req, config)
|
|
135
133
|
addRequestTags(context, this.TYPE)
|
|
@@ -314,7 +312,6 @@ const web = {
|
|
|
314
312
|
web.finishMiddleware(context)
|
|
315
313
|
|
|
316
314
|
web.finishSpan(context, spanType)
|
|
317
|
-
requests.delete(context.span)
|
|
318
315
|
|
|
319
316
|
finishInferredProxySpan(context)
|
|
320
317
|
},
|
|
@@ -344,9 +341,6 @@ const web = {
|
|
|
344
341
|
getContext (req) {
|
|
345
342
|
return contexts.get(req)
|
|
346
343
|
},
|
|
347
|
-
getRequest (span) {
|
|
348
|
-
return requests.get(span)
|
|
349
|
-
},
|
|
350
344
|
setRouteOrEndpointTag (req) {
|
|
351
345
|
const context = contexts.get(req)
|
|
352
346
|
|
|
@@ -511,9 +505,10 @@ function addResourceTag (context) {
|
|
|
511
505
|
|
|
512
506
|
if (spanContext.getTag(RESOURCE_NAME)) return
|
|
513
507
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
508
|
+
let resource = req.method
|
|
509
|
+
const route = spanContext.getTag(HTTP_ROUTE)
|
|
510
|
+
|
|
511
|
+
if (route) resource += ` ${route}`
|
|
517
512
|
|
|
518
513
|
span.setTag(RESOURCE_NAME, resource)
|
|
519
514
|
}
|
|
@@ -54,8 +54,13 @@ function strategiesToCallbackMode (strategies, callbackMode) {
|
|
|
54
54
|
* @returns {string[]}
|
|
55
55
|
*/
|
|
56
56
|
function buildExportCommand (exporters, tags) {
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
let tagString = ''
|
|
58
|
+
for (const [key, value] of Object.entries(tags)) {
|
|
59
|
+
if (tagString) tagString += ','
|
|
60
|
+
tagString += `${key}:${value}`
|
|
61
|
+
}
|
|
62
|
+
if (tagString) tagString += ','
|
|
63
|
+
tagString += `snapshot:${snapshotKinds.ON_OUT_OF_MEMORY}`
|
|
59
64
|
let urls = ''
|
|
60
65
|
for (const exporter of exporters) {
|
|
61
66
|
const url = exporter.getExportUrl()
|