dd-trace 5.97.0 → 5.99.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-3rdparty.csv +0 -1
- package/ext/tags.js +1 -0
- package/index.d.ts +35 -3
- package/package.json +48 -46
- package/packages/datadog-instrumentations/src/crypto.js +45 -0
- package/packages/datadog-instrumentations/src/cucumber.js +65 -3
- package/packages/datadog-instrumentations/src/cypress-config.js +153 -53
- package/packages/datadog-instrumentations/src/dns.js +24 -56
- package/packages/datadog-instrumentations/src/graphql.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +74 -0
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +4 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +10 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/modelcontextprotocol-sdk.js +59 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +11 -2
- package/packages/datadog-instrumentations/src/jest.js +104 -12
- package/packages/datadog-instrumentations/src/mocha/utils.js +8 -0
- package/packages/datadog-instrumentations/src/modelcontextprotocol-sdk.js +7 -0
- package/packages/datadog-instrumentations/src/pino.js +4 -28
- package/packages/datadog-instrumentations/src/playwright-browser-scripts.js +27 -0
- package/packages/datadog-instrumentations/src/playwright.js +5 -17
- package/packages/datadog-instrumentations/src/redis.js +12 -6
- package/packages/datadog-instrumentations/src/stripe.js +38 -24
- package/packages/datadog-instrumentations/src/vitest.js +32 -4
- package/packages/datadog-instrumentations/src/zlib.js +29 -0
- package/packages/datadog-plugin-aws-sdk/src/base.js +2 -3
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -0
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +8 -15
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +4 -9
- package/packages/datadog-plugin-cucumber/src/index.js +8 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +114 -6
- package/packages/datadog-plugin-cypress/src/index.js +59 -2
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +48 -1
- package/packages/datadog-plugin-fs/src/index.js +1 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -1
- package/packages/datadog-plugin-google-cloud-pubsub/src/pubsub-push-subscription.js +2 -7
- package/packages/datadog-plugin-http/src/client.js +1 -1
- package/packages/datadog-plugin-http/src/server.js +21 -13
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-http2/src/server.js +10 -2
- package/packages/datadog-plugin-jest/src/index.js +2 -2
- package/packages/datadog-plugin-mocha/src/index.js +1 -2
- package/packages/datadog-plugin-modelcontextprotocol-sdk/src/index.js +24 -0
- package/packages/datadog-plugin-modelcontextprotocol-sdk/src/tracing.js +55 -0
- package/packages/datadog-plugin-mongodb-core/src/index.js +4 -9
- package/packages/datadog-plugin-mysql/src/index.js +1 -1
- package/packages/datadog-plugin-next/src/index.js +8 -2
- package/packages/datadog-plugin-pg/src/index.js +1 -1
- package/packages/datadog-plugin-playwright/src/index.js +2 -3
- package/packages/datadog-plugin-tedious/src/index.js +1 -1
- package/packages/datadog-plugin-vitest/src/index.js +14 -6
- package/packages/datadog-plugin-ws/src/close.js +3 -1
- package/packages/datadog-plugin-ws/src/producer.js +2 -0
- package/packages/datadog-plugin-ws/src/receiver.js +2 -1
- package/packages/dd-trace/src/aiguard/channels.js +8 -0
- package/packages/dd-trace/src/aiguard/index.js +7 -3
- package/packages/dd-trace/src/aiguard/sdk.js +66 -22
- package/packages/dd-trace/src/aiguard/tags.js +1 -0
- package/packages/dd-trace/src/appsec/blocked_templates.js +4 -3
- package/packages/dd-trace/src/appsec/blocking.js +62 -34
- package/packages/dd-trace/src/appsec/graphql.js +6 -6
- package/packages/dd-trace/src/appsec/index.js +9 -11
- package/packages/dd-trace/src/appsec/rasp/command_injection.js +4 -5
- package/packages/dd-trace/src/appsec/rasp/lfi.js +8 -4
- package/packages/dd-trace/src/appsec/rasp/sql_injection.js +5 -10
- package/packages/dd-trace/src/appsec/rasp/ssrf.js +5 -6
- package/packages/dd-trace/src/appsec/recommended.json +2438 -13
- package/packages/dd-trace/src/appsec/reporter.js +6 -5
- package/packages/dd-trace/src/appsec/sdk/set_user.js +1 -1
- package/packages/dd-trace/src/appsec/sdk/track_event.js +5 -5
- package/packages/dd-trace/src/appsec/sdk/user_blocking.js +6 -10
- package/packages/dd-trace/src/appsec/sdk/utils.js +4 -2
- package/packages/dd-trace/src/appsec/store.js +50 -0
- package/packages/dd-trace/src/appsec/waf/index.js +3 -5
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +3 -4
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -2
- package/packages/dd-trace/src/ci-visibility/log-submission/log-submission-plugin.js +4 -5
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +3 -4
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +6 -6
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +2 -2
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +2 -2
- package/packages/dd-trace/src/config/config-types.d.ts +0 -4
- package/packages/dd-trace/src/config/defaults.js +10 -11
- package/packages/dd-trace/src/config/generated-config-types.d.ts +14 -8
- package/packages/dd-trace/src/config/index.js +49 -32
- package/packages/dd-trace/src/config/parsers.js +26 -9
- package/packages/dd-trace/src/config/supported-configurations.json +86 -33
- package/packages/dd-trace/src/constants.js +1 -0
- package/packages/dd-trace/src/debugger/config.js +2 -0
- package/packages/dd-trace/src/debugger/devtools_client/send.js +25 -5
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +5 -2
- package/packages/dd-trace/src/encode/0.4.js +11 -11
- package/packages/dd-trace/src/encode/span-stats.js +4 -1
- package/packages/dd-trace/src/exporters/agent/index.js +0 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +1 -2
- package/packages/dd-trace/src/exporters/agentless/writer.js +3 -3
- package/packages/dd-trace/src/exporters/common/util.js +2 -2
- package/packages/dd-trace/src/id.js +2 -0
- package/packages/dd-trace/src/index.js +2 -5
- package/packages/dd-trace/src/lambda/handler.js +1 -3
- package/packages/dd-trace/src/llmobs/plugins/{anthropic.js → anthropic/index.js} +5 -63
- package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +106 -0
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chain.js +3 -2
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +3 -2
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/embedding.js +2 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +0 -49
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/vectorstore.js +2 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/messages.js +76 -0
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -26
- package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/index.js +68 -0
- package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +57 -0
- package/packages/dd-trace/src/llmobs/sdk.js +2 -2
- package/packages/dd-trace/src/log/index.js +0 -10
- package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +103 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +3 -0
- package/packages/dd-trace/src/openfeature/remote_config.js +6 -1
- package/packages/dd-trace/src/opentelemetry/context_manager.js +6 -4
- package/packages/dd-trace/src/opentelemetry/logs/index.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +3 -2
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +3 -2
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +19 -51
- package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +14 -2
- package/packages/dd-trace/src/opentelemetry/otlp/trace.proto +358 -0
- package/packages/dd-trace/src/opentelemetry/otlp/trace_service.proto +78 -0
- package/packages/dd-trace/src/opentelemetry/trace/index.js +70 -0
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +74 -0
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +342 -0
- package/packages/dd-trace/src/opentelemetry/tracer.js +9 -11
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +17 -10
- package/packages/dd-trace/src/opentracing/span.js +1 -1
- package/packages/dd-trace/src/opentracing/tracer.js +17 -5
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/log_plugin.js +3 -0
- package/packages/dd-trace/src/plugins/plugin.js +6 -11
- package/packages/dd-trace/src/plugins/storage.js +2 -2
- package/packages/dd-trace/src/plugins/tracing.js +22 -5
- package/packages/dd-trace/src/plugins/util/test.js +128 -5
- package/packages/dd-trace/src/plugins/util/url.js +2 -1
- package/packages/dd-trace/src/plugins/util/web.js +6 -88
- package/packages/dd-trace/src/profiling/profiler.js +34 -77
- package/packages/dd-trace/src/profiling/profilers/event_plugins/crypto.js +32 -0
- package/packages/dd-trace/src/profiling/profilers/event_plugins/zlib.js +19 -0
- package/packages/dd-trace/src/profiling/profilers/events.js +35 -0
- package/packages/dd-trace/src/proxy.js +3 -4
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +17 -13
- package/packages/dd-trace/src/service-naming/index.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/definition.js +4 -1
- package/packages/dd-trace/src/service-naming/schemas/util.js +15 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +24 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +60 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +21 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/websocket.js +5 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +17 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +15 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/websocket.js +6 -0
- package/packages/dd-trace/src/span_processor.js +1 -2
- package/packages/dd-trace/src/span_stats.js +5 -1
- package/packages/dd-trace/src/tagger.js +2 -2
- package/packages/dd-trace/src/telemetry/send-data.js +5 -7
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +28 -6
- package/vendor/dist/protobufjs/index.js +1 -1
- package/packages/dd-trace/src/log/utils.js +0 -16
- package/vendor/dist/ignore/LICENSE +0 -21
- package/vendor/dist/ignore/index.js +0 -1
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const OtlpTransformerBase = require('../otlp/otlp_transformer_base')
|
|
4
|
+
const { getProtobufTypes } = require('../otlp/protobuf_loader')
|
|
5
|
+
const { VERSION } = require('../../../../../version')
|
|
6
|
+
const id = require('../../id')
|
|
7
|
+
|
|
8
|
+
const { protoSpanKind } = getProtobufTypes()
|
|
9
|
+
const SPAN_KIND_UNSPECIFIED = protoSpanKind.values.SPAN_KIND_UNSPECIFIED
|
|
10
|
+
const SPAN_KIND_INTERNAL = protoSpanKind.values.SPAN_KIND_INTERNAL
|
|
11
|
+
const SPAN_KIND_SERVER = protoSpanKind.values.SPAN_KIND_SERVER
|
|
12
|
+
const SPAN_KIND_CLIENT = protoSpanKind.values.SPAN_KIND_CLIENT
|
|
13
|
+
const SPAN_KIND_PRODUCER = protoSpanKind.values.SPAN_KIND_PRODUCER
|
|
14
|
+
const SPAN_KIND_CONSUMER = protoSpanKind.values.SPAN_KIND_CONSUMER
|
|
15
|
+
|
|
16
|
+
// Cached zero Identifier used to detect zero IDs without re-allocating per span.
|
|
17
|
+
const ZERO_ID = id('0')
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {import('../../id').Identifier} Identifier
|
|
21
|
+
*
|
|
22
|
+
* @typedef {object} DDSpanLink
|
|
23
|
+
* @property {string} trace_id - Hex-encoded trace ID
|
|
24
|
+
* @property {string} span_id - Hex-encoded span ID
|
|
25
|
+
* @property {Record<string, string | number | boolean>} [attributes] - Link attributes
|
|
26
|
+
* @property {number} [flags] - Trace flags
|
|
27
|
+
* @property {string} [tracestate] - W3C trace state
|
|
28
|
+
*
|
|
29
|
+
* @typedef {object} DDSpanEvent
|
|
30
|
+
* @property {string} name - Event name
|
|
31
|
+
* @property {number} time_unix_nano - Event time in nanoseconds since epoch
|
|
32
|
+
* @property {Record<string, string | number | boolean>} [attributes] - Event attributes
|
|
33
|
+
*
|
|
34
|
+
* @typedef {object} DDFormattedSpan
|
|
35
|
+
* @property {Identifier} trace_id - DD Identifier for trace ID
|
|
36
|
+
* @property {Identifier} span_id - DD Identifier for span ID
|
|
37
|
+
* @property {Identifier} parent_id - DD Identifier for parent span ID
|
|
38
|
+
* @property {string} name - Span operation name
|
|
39
|
+
* @property {string} resource - Resource name
|
|
40
|
+
* @property {string} [service] - Service name
|
|
41
|
+
* @property {string} [type] - Span type
|
|
42
|
+
* @property {number} error - Error flag (0 or 1)
|
|
43
|
+
* @property {{[key: string]: string}} meta - String key-value tags
|
|
44
|
+
* @property {{[key: string]: number}} metrics - Numeric key-value tags
|
|
45
|
+
* @property {{[key: string]: object}} [meta_struct] - Structured tags (JSON-serialized, bytes in protobuf)
|
|
46
|
+
* @property {number} start - Start time in nanoseconds since epoch
|
|
47
|
+
* @property {number} duration - Duration in nanoseconds
|
|
48
|
+
* @property {DDSpanEvent[]} [span_events] - Span events
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
// Map DD span.kind string values to OTLP SpanKind numeric values
|
|
52
|
+
const SPAN_KIND_MAP = {
|
|
53
|
+
internal: SPAN_KIND_INTERNAL,
|
|
54
|
+
server: SPAN_KIND_SERVER,
|
|
55
|
+
client: SPAN_KIND_CLIENT,
|
|
56
|
+
producer: SPAN_KIND_PRODUCER,
|
|
57
|
+
consumer: SPAN_KIND_CONSUMER,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// OTLP StatusCode values (from trace.proto Status.StatusCode enum)
|
|
61
|
+
const STATUS_CODE_UNSET = 0
|
|
62
|
+
const STATUS_CODE_ERROR = 2
|
|
63
|
+
|
|
64
|
+
// DD meta keys that are mapped to dedicated OTLP span fields and should not appear as attributes
|
|
65
|
+
const EXCLUDED_META_KEYS = new Set([
|
|
66
|
+
'_dd.span_links',
|
|
67
|
+
'span.kind',
|
|
68
|
+
])
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* OtlpTraceTransformer transforms DD-formatted spans to OTLP trace JSON format.
|
|
72
|
+
*
|
|
73
|
+
* This implementation follows the OTLP trace data model:
|
|
74
|
+
* https://opentelemetry.io/docs/specs/otlp/#trace-data-model
|
|
75
|
+
*
|
|
76
|
+
* It receives DD-formatted spans (from span_format.js) and produces
|
|
77
|
+
* an ExportTraceServiceRequest serialized as JSON (http/json protocol only).
|
|
78
|
+
*
|
|
79
|
+
* @class OtlpTraceTransformer
|
|
80
|
+
* @augments OtlpTransformerBase
|
|
81
|
+
*/
|
|
82
|
+
class OtlpTraceTransformer extends OtlpTransformerBase {
|
|
83
|
+
/**
|
|
84
|
+
* Creates a new OtlpTraceTransformer instance.
|
|
85
|
+
*
|
|
86
|
+
* @param {import('@opentelemetry/api').Attributes} resourceAttributes - Resource attributes
|
|
87
|
+
*/
|
|
88
|
+
constructor (resourceAttributes) {
|
|
89
|
+
super(resourceAttributes, 'http/json', 'traces')
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Transforms DD-formatted spans to OTLP JSON format.
|
|
94
|
+
*
|
|
95
|
+
* @param {DDFormattedSpan[]} spans - Array of DD-formatted spans to transform
|
|
96
|
+
* @returns {Buffer} JSON-encoded trace data
|
|
97
|
+
*/
|
|
98
|
+
transformSpans (spans) {
|
|
99
|
+
const traceData = {
|
|
100
|
+
resourceSpans: [{
|
|
101
|
+
resource: this.transformResource(),
|
|
102
|
+
scopeSpans: this.#transformScopeSpans(spans),
|
|
103
|
+
}],
|
|
104
|
+
}
|
|
105
|
+
return this.serializeToJson(traceData)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Creates scope spans. DD spans do not carry instrumentation scope info,
|
|
110
|
+
* so all spans are placed under a single default scope.
|
|
111
|
+
*
|
|
112
|
+
* @param {DDFormattedSpan[]} spans - Array of DD-formatted spans
|
|
113
|
+
* @returns {object[]} Array of scope span objects
|
|
114
|
+
*/
|
|
115
|
+
#transformScopeSpans (spans) {
|
|
116
|
+
return [{
|
|
117
|
+
scope: {
|
|
118
|
+
name: 'dd-trace-js',
|
|
119
|
+
version: VERSION,
|
|
120
|
+
attributes: [],
|
|
121
|
+
droppedAttributesCount: 0,
|
|
122
|
+
},
|
|
123
|
+
schemaUrl: '',
|
|
124
|
+
spans: spans.map(span => this.#transformSpan(span)),
|
|
125
|
+
}]
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Transforms a single DD-formatted span to an OTLP Span object.
|
|
130
|
+
*
|
|
131
|
+
* @param {DDFormattedSpan} span - DD-formatted span to transform
|
|
132
|
+
* @returns {object} OTLP Span object
|
|
133
|
+
*/
|
|
134
|
+
#transformSpan (span) {
|
|
135
|
+
const parentId = span.parent_id
|
|
136
|
+
const links = this.#extractLinks(span.meta?.['_dd.span_links'])
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
traceId: this.#idToBytes(span.trace_id, 16),
|
|
140
|
+
spanId: this.#idToBytes(span.span_id, 8),
|
|
141
|
+
parentSpanId: (parentId && !parentId.equals(ZERO_ID)) ? this.#idToBytes(parentId, 8) : undefined,
|
|
142
|
+
name: span.resource,
|
|
143
|
+
kind: this.#mapSpanKind(span.meta?.['span.kind']),
|
|
144
|
+
startTimeUnixNano: span.start,
|
|
145
|
+
endTimeUnixNano: span.start + span.duration,
|
|
146
|
+
attributes: this.#buildAttributes(span),
|
|
147
|
+
droppedAttributesCount: 0,
|
|
148
|
+
events: span.span_events?.length ? span.span_events.map(event => this.#transformEvent(event)) : undefined,
|
|
149
|
+
droppedEventsCount: 0,
|
|
150
|
+
links: links.length ? links : undefined,
|
|
151
|
+
droppedLinksCount: 0,
|
|
152
|
+
status: this.#mapStatus(span),
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Builds OTLP attributes from DD span fields.
|
|
158
|
+
* Merges top-level DD fields (service, resource, type), meta (string tags),
|
|
159
|
+
* and metrics (numeric tags) into a single OTLP KeyValue array.
|
|
160
|
+
*
|
|
161
|
+
* @param {DDFormattedSpan} span - DD-formatted span
|
|
162
|
+
* @returns {object[]} Array of OTLP KeyValue objects
|
|
163
|
+
*/
|
|
164
|
+
#buildAttributes (span) {
|
|
165
|
+
const attributes = []
|
|
166
|
+
|
|
167
|
+
// Add top-level DD span fields as OTLP attributes
|
|
168
|
+
if (span.service) {
|
|
169
|
+
attributes.push({ key: 'service.name', value: { stringValue: span.service } })
|
|
170
|
+
}
|
|
171
|
+
if (span.name) {
|
|
172
|
+
attributes.push({ key: 'operation.name', value: { stringValue: span.name } })
|
|
173
|
+
}
|
|
174
|
+
if (span.resource) {
|
|
175
|
+
attributes.push({ key: 'resource.name', value: { stringValue: span.resource } })
|
|
176
|
+
}
|
|
177
|
+
if (span.type) {
|
|
178
|
+
attributes.push({ key: 'span.type', value: { stringValue: span.type } })
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Add meta string tags, skipping keys that map to dedicated OTLP fields
|
|
182
|
+
if (span.meta) {
|
|
183
|
+
for (const [key, value] of Object.entries(span.meta)) {
|
|
184
|
+
if (EXCLUDED_META_KEYS.has(key)) continue
|
|
185
|
+
attributes.push({ key, value: { stringValue: value } })
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Add metrics as numeric attributes
|
|
190
|
+
if (span.metrics) {
|
|
191
|
+
for (const [key, value] of Object.entries(span.metrics)) {
|
|
192
|
+
if (Number.isInteger(value)) {
|
|
193
|
+
attributes.push({ key, value: { intValue: value } })
|
|
194
|
+
} else {
|
|
195
|
+
attributes.push({ key, value: { doubleValue: value } })
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// TODO: meta_struct values are logically raw bytes. The OTLP http/json spec encodes the bytesValue
|
|
201
|
+
// field as base64, but when http/protobuf or gRPC support is added the payload should be sent as
|
|
202
|
+
// raw bytes directly (no JSON.stringify + base64). The backend decoding side will need to be
|
|
203
|
+
// updated in parallel to accept the unencoded bytes.
|
|
204
|
+
if (span.meta_struct) {
|
|
205
|
+
for (const [key, value] of Object.entries(span.meta_struct)) {
|
|
206
|
+
const bytes = Buffer.from(JSON.stringify(value))
|
|
207
|
+
attributes.push({ key, value: { bytesValue: bytes.toString('base64') } })
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return attributes
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Maps a DD span.kind string to an OTLP SpanKind enum value.
|
|
216
|
+
*
|
|
217
|
+
* @param {string | undefined} kind - DD span kind string
|
|
218
|
+
* @returns {number} OTLP SpanKind enum value
|
|
219
|
+
*/
|
|
220
|
+
#mapSpanKind (kind) {
|
|
221
|
+
if (!kind) return SPAN_KIND_UNSPECIFIED
|
|
222
|
+
return SPAN_KIND_MAP[kind] ?? SPAN_KIND_UNSPECIFIED
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Maps DD span error state to an OTLP Status object.
|
|
227
|
+
* Combines error.type and error.message when both are present so error type
|
|
228
|
+
* information is preserved on the OTel side.
|
|
229
|
+
*
|
|
230
|
+
* @param {DDFormattedSpan} span - DD-formatted span
|
|
231
|
+
* @returns {object} OTLP Status object with code and message
|
|
232
|
+
*/
|
|
233
|
+
#mapStatus (span) {
|
|
234
|
+
if (span.error !== 1) {
|
|
235
|
+
return { code: STATUS_CODE_UNSET, message: '' }
|
|
236
|
+
}
|
|
237
|
+
const errorType = span.meta?.['error.type']
|
|
238
|
+
const errorMessage = span.meta?.['error.message']
|
|
239
|
+
let message = ''
|
|
240
|
+
if (errorType && errorMessage) {
|
|
241
|
+
message = `${errorType}: ${errorMessage}`
|
|
242
|
+
} else if (errorType) {
|
|
243
|
+
message = errorType
|
|
244
|
+
} else if (errorMessage) {
|
|
245
|
+
message = errorMessage
|
|
246
|
+
}
|
|
247
|
+
return { code: STATUS_CODE_ERROR, message }
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Transforms a DD span event to an OTLP Event object.
|
|
252
|
+
*
|
|
253
|
+
* @param {DDSpanEvent} event - DD span event
|
|
254
|
+
* @returns {object} OTLP Event object
|
|
255
|
+
*/
|
|
256
|
+
#transformEvent (event) {
|
|
257
|
+
return {
|
|
258
|
+
timeUnixNano: event.time_unix_nano,
|
|
259
|
+
name: event.name || '',
|
|
260
|
+
attributes: this.transformAttributes(event.attributes ?? {}),
|
|
261
|
+
droppedAttributesCount: 0,
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Extracts and transforms span links from the DD _dd.span_links meta JSON string.
|
|
267
|
+
*
|
|
268
|
+
* @param {string | undefined} spanLinksJson - JSON-encoded array of DD span links
|
|
269
|
+
* @returns {object[]} Array of OTLP Link objects
|
|
270
|
+
*/
|
|
271
|
+
#extractLinks (spanLinksJson) {
|
|
272
|
+
if (!spanLinksJson) return []
|
|
273
|
+
|
|
274
|
+
let parsedLinks
|
|
275
|
+
try {
|
|
276
|
+
parsedLinks = JSON.parse(spanLinksJson)
|
|
277
|
+
} catch {
|
|
278
|
+
return []
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (!Array.isArray(parsedLinks)) return []
|
|
282
|
+
|
|
283
|
+
return parsedLinks.map(link => this.#transformLink(link))
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Transforms a single DD span link to an OTLP Link object.
|
|
288
|
+
*
|
|
289
|
+
* @param {DDSpanLink} link - DD span link
|
|
290
|
+
* @returns {object} OTLP Link object
|
|
291
|
+
*/
|
|
292
|
+
#transformLink (link) {
|
|
293
|
+
return {
|
|
294
|
+
traceId: this.#hexToBytes(link.trace_id, 16),
|
|
295
|
+
spanId: this.#hexToBytes(link.span_id, 8),
|
|
296
|
+
traceState: link.tracestate || '',
|
|
297
|
+
attributes: this.transformAttributes(link.attributes ?? {}),
|
|
298
|
+
droppedAttributesCount: 0,
|
|
299
|
+
flags: link.flags,
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Converts a DD Identifier object to a hex-encoded string of the specified byte length.
|
|
305
|
+
* Pads with leading zeros if the identifier buffer is shorter than the target.
|
|
306
|
+
* Per the OTLP http/json spec, trace-ids and span-ids must be hex-encoded strings.
|
|
307
|
+
*
|
|
308
|
+
* @param {Identifier} identifier - DD Identifier
|
|
309
|
+
* @param {number} targetLength - Target byte length (16 for trace ID, 8 for span ID)
|
|
310
|
+
* @returns {string} Hex-encoded string of the specified length
|
|
311
|
+
*/
|
|
312
|
+
#idToBytes (identifier, targetLength) {
|
|
313
|
+
const buffer = identifier.toBuffer()
|
|
314
|
+
if (buffer.length === targetLength) {
|
|
315
|
+
return Buffer.from(buffer).toString('hex')
|
|
316
|
+
}
|
|
317
|
+
if (buffer.length > targetLength) {
|
|
318
|
+
return Buffer.from(buffer.slice(buffer.length - targetLength)).toString('hex')
|
|
319
|
+
}
|
|
320
|
+
// Pad with leading zeros to reach target length.
|
|
321
|
+
const result = Buffer.alloc(targetLength)
|
|
322
|
+
Buffer.from(buffer).copy(result, targetLength - buffer.length)
|
|
323
|
+
return result.toString('hex')
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Normalizes a hex string to the specified byte length.
|
|
328
|
+
* Pads with leading zeros if the hex string is shorter than expected.
|
|
329
|
+
* Per the OTLP http/json spec, trace-ids and span-ids must be hex-encoded strings.
|
|
330
|
+
*
|
|
331
|
+
* @param {string | undefined} hexString - Hex string to normalize
|
|
332
|
+
* @param {number} targetLength - Target byte length
|
|
333
|
+
* @returns {string} Hex-encoded string of the specified length
|
|
334
|
+
*/
|
|
335
|
+
#hexToBytes (hexString, targetLength) {
|
|
336
|
+
if (!hexString) return '0'.repeat(targetLength * 2)
|
|
337
|
+
const cleanHex = hexString.startsWith('0x') ? hexString.slice(2) : hexString
|
|
338
|
+
return cleanHex.padStart(targetLength * 2, '0')
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
module.exports = OtlpTraceTransformer
|
|
@@ -81,10 +81,10 @@ class Tracer {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
_convertOtelContextToDatadog (traceId, spanId, traceFlag, ts, meta = {}) {
|
|
84
|
-
|
|
84
|
+
let origin = null
|
|
85
85
|
let samplingPriority = traceFlag
|
|
86
86
|
|
|
87
|
-
ts = ts?.traceparent
|
|
87
|
+
ts = ts?.traceparent
|
|
88
88
|
|
|
89
89
|
if (ts) {
|
|
90
90
|
// Use TraceState.fromString to parse the tracestate header
|
|
@@ -101,19 +101,17 @@ class Tracer {
|
|
|
101
101
|
// Assuming ddTraceStateData is now a Map or similar structure containing Datadog trace state data
|
|
102
102
|
// Extract values as needed, similar to the original logic
|
|
103
103
|
const samplingPriorityTs = ddTraceStateData.get('s')
|
|
104
|
-
|
|
104
|
+
origin = ddTraceStateData.get('o') ?? null
|
|
105
105
|
// Convert Map to object for meta
|
|
106
106
|
const otherPropagatedTags = Object.fromEntries(ddTraceStateData.entries())
|
|
107
107
|
|
|
108
108
|
// Update meta and samplingPriority based on extracted values
|
|
109
109
|
Object.assign(meta, otherPropagatedTags)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
origin
|
|
114
|
-
)
|
|
110
|
+
// Guard against an undefined/empty `s:` field that would result in NaN.
|
|
111
|
+
const tracestateSamplingPriority = samplingPriorityTs ? Math.trunc(samplingPriorityTs) : undefined
|
|
112
|
+
samplingPriority = TextMapPropagator._getSamplingPriority(traceFlag, tracestateSamplingPriority, origin)
|
|
115
113
|
} else {
|
|
116
|
-
log.debug('
|
|
114
|
+
log.debug('No dd list member in tracestate from incoming request:', ts)
|
|
117
115
|
}
|
|
118
116
|
}
|
|
119
117
|
|
|
@@ -121,8 +119,8 @@ class Tracer {
|
|
|
121
119
|
traceId: id(traceId, 16), spanId: id(), tags: meta, parentId: id(spanId, 16),
|
|
122
120
|
})
|
|
123
121
|
|
|
124
|
-
spanContext._sampling = { priority: samplingPriority }
|
|
125
|
-
spanContext._trace = { origin }
|
|
122
|
+
spanContext._ddContext._sampling = { priority: samplingPriority }
|
|
123
|
+
spanContext._ddContext._trace = { ...spanContext._ddContext._trace, origin }
|
|
126
124
|
return spanContext
|
|
127
125
|
}
|
|
128
126
|
|
|
@@ -802,18 +802,25 @@ class TextMapPropagator {
|
|
|
802
802
|
return spanContext._traceId.toString(16)
|
|
803
803
|
}
|
|
804
804
|
|
|
805
|
-
|
|
805
|
+
/**
|
|
806
|
+
* @param {number} traceparentSampled
|
|
807
|
+
* @param {number|undefined} tracestateSamplingPriority
|
|
808
|
+
* @param {string|null} origin
|
|
809
|
+
* @returns {import('../../priority_sampler').SamplingPriority}
|
|
810
|
+
*/
|
|
811
|
+
static _getSamplingPriority (traceparentSampled, tracestateSamplingPriority, origin) {
|
|
806
812
|
const fromRumWithoutPriority = !tracestateSamplingPriority && origin === 'rum'
|
|
807
813
|
|
|
808
|
-
let samplingPriority
|
|
809
|
-
|
|
810
|
-
(!
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
814
|
+
let samplingPriority =
|
|
815
|
+
/** @type {import('../../priority_sampler').SamplingPriority} */ (tracestateSamplingPriority ?? AUTO_KEEP)
|
|
816
|
+
if (!fromRumWithoutPriority) {
|
|
817
|
+
if (traceparentSampled === 0 &&
|
|
818
|
+
(!tracestateSamplingPriority || tracestateSamplingPriority >= 0)) {
|
|
819
|
+
samplingPriority = AUTO_REJECT
|
|
820
|
+
} else if (traceparentSampled === 1 &&
|
|
821
|
+
(!tracestateSamplingPriority || tracestateSamplingPriority < 0)) {
|
|
822
|
+
samplingPriority = AUTO_KEEP
|
|
823
|
+
}
|
|
817
824
|
}
|
|
818
825
|
|
|
819
826
|
return samplingPriority
|
|
@@ -21,8 +21,6 @@ const REFERENCE_FOLLOWS_FROM = 'follows_from'
|
|
|
21
21
|
|
|
22
22
|
class DatadogTracer {
|
|
23
23
|
constructor (config, prioritySampler) {
|
|
24
|
-
const Exporter = getExporter(config.experimental.exporter)
|
|
25
|
-
|
|
26
24
|
this._config = config
|
|
27
25
|
this._service = config.service
|
|
28
26
|
this._version = config.version
|
|
@@ -30,7 +28,21 @@ class DatadogTracer {
|
|
|
30
28
|
this._logInjection = config.logInjection
|
|
31
29
|
this._debug = config.debug
|
|
32
30
|
this._prioritySampler = prioritySampler ?? new PrioritySampler(config.env, config.sampler)
|
|
33
|
-
|
|
31
|
+
|
|
32
|
+
// OTEL_TRACES_EXPORTER=otlp should not replace the Test Optimization
|
|
33
|
+
// exporter when the tracer is running in Test Optimization mode. Test spans
|
|
34
|
+
// (test_session/test_module/ test_suite/test) belong on the citestcycle
|
|
35
|
+
// endpoint, not on an OTLP traces endpoint — otherwise users with OTEL_*
|
|
36
|
+
// vars set in their environment (e.g. for a separate telemetry integration)
|
|
37
|
+
// silently lose all test spans.
|
|
38
|
+
if (config.OTEL_TRACES_EXPORTER === 'otlp' && !config.isCiVisibility) {
|
|
39
|
+
const { createOtlpTraceExporter } = require('../opentelemetry/trace')
|
|
40
|
+
this._exporter = createOtlpTraceExporter(config)
|
|
41
|
+
} else {
|
|
42
|
+
const Exporter = getExporter(config.experimental.exporter)
|
|
43
|
+
this._exporter = new Exporter(config, this._prioritySampler)
|
|
44
|
+
}
|
|
45
|
+
|
|
34
46
|
this._processor = new SpanProcessor(this._exporter, this._prioritySampler, config)
|
|
35
47
|
this._url = this._exporter._url
|
|
36
48
|
this._enableGetRumData = config.experimental.enableGetRumData
|
|
@@ -38,7 +50,7 @@ class DatadogTracer {
|
|
|
38
50
|
this._propagators = {
|
|
39
51
|
[formats.TEXT_MAP]: new TextMapPropagator(config),
|
|
40
52
|
[formats.HTTP_HEADERS]: new HttpPropagator(config),
|
|
41
|
-
[formats.BINARY]: new BinaryPropagator(
|
|
53
|
+
[formats.BINARY]: new BinaryPropagator(),
|
|
42
54
|
[formats.LOG]: new LogPropagator(config),
|
|
43
55
|
[formats.TEXT_MAP_DSM]: new DSMTextMapPropagator(config),
|
|
44
56
|
}
|
|
@@ -111,7 +123,7 @@ class DatadogTracer {
|
|
|
111
123
|
* Get the span context from a span or a span context.
|
|
112
124
|
*
|
|
113
125
|
* @param {Span|SpanContext} spanContext
|
|
114
|
-
* @returns {SpanContext}
|
|
126
|
+
* @returns {SpanContext|null}
|
|
115
127
|
*/
|
|
116
128
|
function getContext (spanContext) {
|
|
117
129
|
if (spanContext instanceof Span) {
|
|
@@ -6,6 +6,7 @@ const plugins = {
|
|
|
6
6
|
get '@aws-sdk/smithy-client' () { return require('../../../datadog-plugin-aws-sdk/src') },
|
|
7
7
|
get '@azure/event-hubs' () { return require('../../../datadog-plugin-azure-event-hubs/src') },
|
|
8
8
|
get '@azure/functions' () { return require('../../../datadog-plugin-azure-functions/src') },
|
|
9
|
+
get '@modelcontextprotocol/sdk' () { return require('../../../datadog-plugin-modelcontextprotocol-sdk/src') },
|
|
9
10
|
get 'durable-functions' () { return require('../../../datadog-plugin-azure-durable-functions/src') },
|
|
10
11
|
get '@azure/service-bus' () { return require('../../../datadog-plugin-azure-service-bus/src') },
|
|
11
12
|
get '@cucumber/cucumber' () { return require('../../../datadog-plugin-cucumber/src') },
|
|
@@ -13,6 +13,9 @@ function messageProxy (message, holder) {
|
|
|
13
13
|
|
|
14
14
|
return target[key]
|
|
15
15
|
},
|
|
16
|
+
set (target, key, value) {
|
|
17
|
+
return Reflect.set(target, key, value)
|
|
18
|
+
},
|
|
16
19
|
ownKeys (target) {
|
|
17
20
|
const ownKeys = Reflect.ownKeys(target)
|
|
18
21
|
if (!Object.hasOwn(target, 'dd') && Reflect.isExtensible(target)) {
|
|
@@ -106,12 +106,6 @@ module.exports = class Plugin {
|
|
|
106
106
|
storage('legacy').enterWith({ ...store, span })
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
// TODO: Implement filters on resource name for all plugins.
|
|
110
|
-
/** Prevents creation of spans here and for all async descendants. */
|
|
111
|
-
skip () {
|
|
112
|
-
storage('legacy').enterWith({ noop: true })
|
|
113
|
-
}
|
|
114
|
-
|
|
115
109
|
/**
|
|
116
110
|
* Subscribe to a diagnostic channel with automatic error handling and enable/disable lifecycle.
|
|
117
111
|
*
|
|
@@ -157,8 +151,9 @@ module.exports = class Plugin {
|
|
|
157
151
|
|
|
158
152
|
if (!store || !store.span) return
|
|
159
153
|
|
|
160
|
-
|
|
161
|
-
|
|
154
|
+
const span = /** @type {import('../opentracing/span')} */ (store.span)
|
|
155
|
+
if (!span._spanContext._tags.error) {
|
|
156
|
+
span.setTag('error', error || 1)
|
|
162
157
|
}
|
|
163
158
|
}
|
|
164
159
|
|
|
@@ -167,12 +162,12 @@ module.exports = class Plugin {
|
|
|
167
162
|
*
|
|
168
163
|
* TODO: Remove the overloading with `enabled` and use the config object directly.
|
|
169
164
|
*
|
|
170
|
-
* @param {boolean|import('../config/config-base')} config Either a boolean to
|
|
171
|
-
* or a configuration object containing at least `{ enabled: boolean }`.
|
|
165
|
+
* @param {boolean | import('../config/config-base') & {enabled: boolean}} config Either a boolean to
|
|
166
|
+
* enable/disable or a configuration object containing at least `{ enabled: boolean }`.
|
|
172
167
|
*/
|
|
173
168
|
configure (config) {
|
|
174
169
|
if (typeof config === 'boolean') {
|
|
175
|
-
config = { enabled: config }
|
|
170
|
+
config = /** @type {import('../config/config-base') & {enabled: boolean}} */ ({ enabled: config })
|
|
176
171
|
}
|
|
177
172
|
this.config = config
|
|
178
173
|
if (config.enabled) {
|
|
@@ -12,8 +12,8 @@ class StoragePlugin extends ClientPlugin {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
startSpan (name, options, ctx) {
|
|
15
|
-
if (!options.service && this.system) {
|
|
16
|
-
options.service = `${this.tracer._service}-${this.system}
|
|
15
|
+
if (!options.service?.name && this.system) {
|
|
16
|
+
options.service = { name: `${this.tracer._service}-${this.system}`, source: this.system }
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
return super.startSpan(name, options, ctx)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { storage } = require('../../../datadog-core')
|
|
4
4
|
const analyticsSampler = require('../analytics_sampler')
|
|
5
|
-
const { COMPONENT } = require('../constants')
|
|
5
|
+
const { COMPONENT, SVC_SRC_KEY } = require('../constants')
|
|
6
6
|
const Plugin = require('./plugin')
|
|
7
7
|
|
|
8
8
|
class TracingPlugin extends Plugin {
|
|
@@ -26,7 +26,7 @@ class TracingPlugin extends Plugin {
|
|
|
26
26
|
* @param {string} [opts.type]
|
|
27
27
|
* @param {string} [opts.id]
|
|
28
28
|
* @param {string} [opts.kind]
|
|
29
|
-
* @returns {string}
|
|
29
|
+
* @returns {{ name: string, source: string | undefined }}
|
|
30
30
|
*/
|
|
31
31
|
serviceName (opts = {}) {
|
|
32
32
|
const {
|
|
@@ -157,7 +157,8 @@ class TracingPlugin extends Plugin {
|
|
|
157
157
|
* @param {string} [options.kind] - The kind of the span.
|
|
158
158
|
* @param {object} [options.meta] - The meta data for the span.
|
|
159
159
|
* @param {object} [options.metrics] - The metrics for the span.
|
|
160
|
-
* @param {string} [options.service] - The service name
|
|
160
|
+
* @param {string | { name: string, source?: string }} [options.service] - The service name, or an object with
|
|
161
|
+
* name and source.
|
|
161
162
|
* @param {number} [options.startTime] - The start time of the span.
|
|
162
163
|
* @param {string} [options.resource] - The resource name.
|
|
163
164
|
* @param {string} [options.type] - The type of the span.
|
|
@@ -180,24 +181,40 @@ class TracingPlugin extends Plugin {
|
|
|
180
181
|
resource,
|
|
181
182
|
type,
|
|
182
183
|
} = options
|
|
183
|
-
|
|
184
|
+
let serviceSource
|
|
184
185
|
const tracer = options.tracer || this.tracer
|
|
185
186
|
const config = options.config || this.config
|
|
186
187
|
|
|
188
|
+
if (service && typeof service === 'object') {
|
|
189
|
+
serviceSource = service.source
|
|
190
|
+
service = service.name
|
|
191
|
+
} else if (service !== undefined) {
|
|
192
|
+
// service is a plain value returned by service naming/config logic
|
|
193
|
+
serviceSource = service ? 'opt.plugin' : undefined
|
|
194
|
+
}
|
|
195
|
+
|
|
187
196
|
const store = storage('legacy').getStore()
|
|
188
197
|
if (store && childOf === undefined) {
|
|
189
198
|
childOf = /** @type {import('../opentracing/span') | undefined} */ (store.span)
|
|
190
199
|
}
|
|
191
200
|
|
|
201
|
+
// clear service source if service is the same as tracer._service
|
|
202
|
+
const serviceName = service || meta?.service
|
|
203
|
+
|
|
204
|
+
if (!serviceName || serviceName === tracer._service) {
|
|
205
|
+
serviceSource = undefined
|
|
206
|
+
}
|
|
207
|
+
|
|
192
208
|
const span = tracer.startSpan(name, {
|
|
193
209
|
startTime,
|
|
194
210
|
childOf,
|
|
195
211
|
tags: {
|
|
196
212
|
[COMPONENT]: component,
|
|
197
|
-
'service.name':
|
|
213
|
+
'service.name': serviceName || tracer._service,
|
|
198
214
|
'resource.name': resource,
|
|
199
215
|
'span.kind': kind,
|
|
200
216
|
'span.type': type,
|
|
217
|
+
...(serviceSource === undefined ? undefined : { [SVC_SRC_KEY]: serviceSource }),
|
|
201
218
|
...meta,
|
|
202
219
|
...metrics,
|
|
203
220
|
},
|