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
|
@@ -17,13 +17,20 @@ const {
|
|
|
17
17
|
} = require('../constants/writers')
|
|
18
18
|
const { parseResponseAndLog } = require('./util')
|
|
19
19
|
|
|
20
|
+
const MAX_BUFFER_EVENTS = 1000
|
|
21
|
+
|
|
20
22
|
class LLMObsBuffer {
|
|
21
|
-
|
|
23
|
+
/**
|
|
24
|
+
* @param {{
|
|
25
|
+
* events: Record<string, unknown>[],
|
|
26
|
+
* size: number,
|
|
27
|
+
* routing?: { apiKey?: string, site?: string }
|
|
28
|
+
* }} options
|
|
29
|
+
*/
|
|
30
|
+
constructor ({ events, size, routing = {} }) {
|
|
22
31
|
this.events = events
|
|
23
32
|
this.size = size
|
|
24
33
|
this.routing = routing
|
|
25
|
-
this.isDefault = isDefault
|
|
26
|
-
this.limit = limit
|
|
27
34
|
}
|
|
28
35
|
|
|
29
36
|
clear () {
|
|
@@ -46,7 +53,7 @@ class BaseLLMObsWriter {
|
|
|
46
53
|
this._eventType = eventType
|
|
47
54
|
|
|
48
55
|
/** @type {LLMObsBuffer} */
|
|
49
|
-
this._buffer = new LLMObsBuffer({ events: [], size: 0
|
|
56
|
+
this._buffer = new LLMObsBuffer({ events: [], size: 0 })
|
|
50
57
|
|
|
51
58
|
/** @type {import('../../config/config-base')} */
|
|
52
59
|
this._config = config
|
|
@@ -102,8 +109,8 @@ class BaseLLMObsWriter {
|
|
|
102
109
|
append (event, routing, byteLength) {
|
|
103
110
|
const buffer = this._getBuffer(routing)
|
|
104
111
|
|
|
105
|
-
if (buffer.events.length >=
|
|
106
|
-
logger.warn(`${this.constructor.name} event buffer full (limit is ${
|
|
112
|
+
if (buffer.events.length >= MAX_BUFFER_EVENTS) {
|
|
113
|
+
logger.warn(`${this.constructor.name} event buffer full (limit is ${MAX_BUFFER_EVENTS}), dropping event`)
|
|
107
114
|
telemetry.recordDroppedPayload(1, this._eventType, 'buffer_full')
|
|
108
115
|
return false
|
|
109
116
|
}
|
|
@@ -158,30 +165,48 @@ class BaseLLMObsWriter {
|
|
|
158
165
|
}
|
|
159
166
|
|
|
160
167
|
for (const [apiKey, buffer] of this.#multiTenantBuffers) {
|
|
161
|
-
if (buffer.events.length === 0)
|
|
162
|
-
|
|
163
|
-
|
|
168
|
+
if (buffer.events.length === 0) {
|
|
169
|
+
this.#multiTenantBuffers.delete(apiKey)
|
|
170
|
+
continue
|
|
171
|
+
}
|
|
164
172
|
const site = buffer.routing.site || this._config.site
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
173
|
+
const maskedApiKey = `****${apiKey.slice(-4)}`
|
|
174
|
+
let options
|
|
175
|
+
let url
|
|
176
|
+
try {
|
|
177
|
+
options = {
|
|
178
|
+
headers: {
|
|
179
|
+
'Content-Type': 'application/json',
|
|
180
|
+
'DD-API-KEY': apiKey,
|
|
181
|
+
},
|
|
182
|
+
method: 'POST',
|
|
183
|
+
timeout: this._timeout,
|
|
184
|
+
url: new URL(format({
|
|
185
|
+
protocol: 'https:',
|
|
186
|
+
hostname: `${this._intake}.${site}`,
|
|
187
|
+
})),
|
|
188
|
+
path: this._baseEndpoint,
|
|
189
|
+
}
|
|
190
|
+
url = this.#buildUrl(options.url.href, options.path)
|
|
191
|
+
} catch (error) {
|
|
192
|
+
buffer.clear()
|
|
193
|
+
this.#multiTenantBuffers.delete(apiKey)
|
|
194
|
+
logger.error(
|
|
195
|
+
'Failed to route LLMObs %s events for API key %s: %s',
|
|
196
|
+
this._eventType,
|
|
197
|
+
maskedApiKey,
|
|
198
|
+
error.message
|
|
199
|
+
)
|
|
200
|
+
continue
|
|
177
201
|
}
|
|
178
|
-
|
|
179
|
-
const
|
|
202
|
+
|
|
203
|
+
const events = buffer.events
|
|
204
|
+
buffer.clear()
|
|
205
|
+
this.#multiTenantBuffers.delete(apiKey)
|
|
180
206
|
log.debug('Encoding and flushing multi-tenant buffer for %s', maskedApiKey)
|
|
181
207
|
requests.push({ events, options, url })
|
|
182
208
|
}
|
|
183
209
|
|
|
184
|
-
this.#cleanupEmptyBuffers()
|
|
185
210
|
return requests
|
|
186
211
|
}
|
|
187
212
|
|
|
@@ -194,14 +219,6 @@ class BaseLLMObsWriter {
|
|
|
194
219
|
})
|
|
195
220
|
}
|
|
196
221
|
|
|
197
|
-
#cleanupEmptyBuffers () {
|
|
198
|
-
for (const [key, buffer] of this.#multiTenantBuffers) {
|
|
199
|
-
if (buffer.events.length === 0) {
|
|
200
|
-
this.#multiTenantBuffers.delete(key)
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
222
|
makePayload (events) {}
|
|
206
223
|
|
|
207
224
|
/**
|
|
@@ -29,7 +29,13 @@ const log = {
|
|
|
29
29
|
const stack = logRecord.stack.split('\n')
|
|
30
30
|
const fn = stack[1].replace(/^\s+at ([^\s]+) .+/, '$1')
|
|
31
31
|
const options = { depth: 2, breakLength: Infinity, compact: true, maxArrayLength: Infinity }
|
|
32
|
-
|
|
32
|
+
let params = ''
|
|
33
|
+
let isFirstParameter = true
|
|
34
|
+
for (const argument of args) {
|
|
35
|
+
if (!isFirstParameter) params += ', '
|
|
36
|
+
params += inspect(argument, options)
|
|
37
|
+
isFirstParameter = false
|
|
38
|
+
}
|
|
33
39
|
|
|
34
40
|
stack[0] = `Trace: ${fn}(${params})`
|
|
35
41
|
|
|
@@ -2,19 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
const { Writable } = require('node:stream')
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const { FINAL_FLUSH_TIMEOUT } = require('../final-flush')
|
|
5
|
+
const FinalFlushRequestTracker = require('../exporters/common/final-flush-request-tracker')
|
|
6
|
+
const request = require('../exporters/common/request')
|
|
7
|
+
const log = require('../log')
|
|
8
|
+
const Plugin = require('../plugins/plugin')
|
|
10
9
|
|
|
11
10
|
const MAX_BATCH_BYTES = 5 * 1024 * 1024
|
|
12
11
|
const MAX_BATCH_LOGS = 1000
|
|
13
12
|
const BATCH_FLUSH_INTERVAL = 1000
|
|
13
|
+
const FINAL_FLUSH_TIMEOUT = 60_000
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* @
|
|
17
|
-
|
|
16
|
+
* @returns {Error & { code: string }}
|
|
17
|
+
*/
|
|
18
|
+
function createFinalFlushTimeoutError () {
|
|
19
|
+
return Object.assign(
|
|
20
|
+
new Error('Timed out waiting for automatic log submission to flush'),
|
|
21
|
+
{ code: 'ERR_DD_LOG_SUBMISSION_FLUSH_TIMEOUT' }
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param {import('../config/config-base')} config
|
|
27
|
+
* @returns {URL | void}
|
|
18
28
|
*/
|
|
19
29
|
function getLogSubmissionUrl (config) {
|
|
20
30
|
if (config.DD_AGENTLESS_LOG_SUBMISSION_URL) {
|
|
@@ -39,7 +49,15 @@ function getLogSubmissionUrl (config) {
|
|
|
39
49
|
}
|
|
40
50
|
|
|
41
51
|
/**
|
|
42
|
-
* @param {
|
|
52
|
+
* @param {unknown} config
|
|
53
|
+
* @returns {import('../config/config-base')}
|
|
54
|
+
*/
|
|
55
|
+
function asTracerConfig (config) {
|
|
56
|
+
return /** @type {import('../config/config-base')} */ (config)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @param {import('../config/config-base')} config
|
|
43
61
|
* @param {string} source
|
|
44
62
|
* @returns {string}
|
|
45
63
|
*/
|
|
@@ -54,6 +72,8 @@ class LogSubmissionPlugin extends Plugin {
|
|
|
54
72
|
#batch = []
|
|
55
73
|
#batchBytes = 2
|
|
56
74
|
#batchSource
|
|
75
|
+
/** @type {import('../config/config-base') | undefined} */
|
|
76
|
+
#config
|
|
57
77
|
#logSubmissionUrl
|
|
58
78
|
#requestTracker
|
|
59
79
|
#timer
|
|
@@ -71,12 +91,19 @@ class LogSubmissionPlugin extends Plugin {
|
|
|
71
91
|
},
|
|
72
92
|
})
|
|
73
93
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
94
|
+
/**
|
|
95
|
+
* @param {object} tracer
|
|
96
|
+
* @param {unknown} tracerConfig
|
|
97
|
+
*/
|
|
98
|
+
constructor (tracer, tracerConfig) {
|
|
99
|
+
super(tracer, asTracerConfig(tracerConfig))
|
|
100
|
+
this.#requestTracker = new FinalFlushRequestTracker(
|
|
101
|
+
(done) => {
|
|
102
|
+
this.#flushLogs()
|
|
103
|
+
done?.()
|
|
104
|
+
},
|
|
105
|
+
createFinalFlushTimeoutError
|
|
106
|
+
)
|
|
80
107
|
|
|
81
108
|
// The main-module hook (configure) and the logger.js hook (add-transport) can fire in either
|
|
82
109
|
// order depending on how Winston is required, so buffer loggers that arrive before configure.
|
|
@@ -128,8 +155,9 @@ class LogSubmissionPlugin extends Plugin {
|
|
|
128
155
|
if (this._enabled) this.#flushLogs()
|
|
129
156
|
|
|
130
157
|
const isEnabled = typeof config === 'boolean' ? config : config.enabled
|
|
131
|
-
this.#
|
|
132
|
-
|
|
158
|
+
this.#config = isEnabled && typeof config !== 'boolean' ? asTracerConfig(config) : undefined
|
|
159
|
+
this.#logSubmissionUrl = this.#config
|
|
160
|
+
? getLogSubmissionUrl(this.#config)
|
|
133
161
|
: undefined
|
|
134
162
|
super.configure(config)
|
|
135
163
|
|
|
@@ -189,7 +217,8 @@ class LogSubmissionPlugin extends Plugin {
|
|
|
189
217
|
clearTimeout(this.#timer)
|
|
190
218
|
this.#timer = undefined
|
|
191
219
|
|
|
192
|
-
|
|
220
|
+
const config = this.#config
|
|
221
|
+
if (this.#batch.length === 0 || !this.#logSubmissionUrl || !config) return
|
|
193
222
|
|
|
194
223
|
const source = this.#batchSource
|
|
195
224
|
const data = `[${this.#batch.join(',')}]`
|
|
@@ -197,10 +226,10 @@ class LogSubmissionPlugin extends Plugin {
|
|
|
197
226
|
this.#batchBytes = 2
|
|
198
227
|
this.#batchSource = undefined
|
|
199
228
|
const options = {
|
|
200
|
-
path: getLogSubmissionPath(
|
|
229
|
+
path: getLogSubmissionPath(config, source),
|
|
201
230
|
method: 'POST',
|
|
202
231
|
headers: {
|
|
203
|
-
'DD-API-KEY':
|
|
232
|
+
'DD-API-KEY': config.DD_API_KEY,
|
|
204
233
|
'Content-Type': 'application/json',
|
|
205
234
|
},
|
|
206
235
|
url: this.#logSubmissionUrl,
|
|
@@ -214,21 +214,23 @@ class BaseFFEWriter {
|
|
|
214
214
|
* @returns {ActiveWriterRoute} Active route state
|
|
215
215
|
*/
|
|
216
216
|
#createRoute (route) {
|
|
217
|
+
const requestOptions = {
|
|
218
|
+
headers: {
|
|
219
|
+
...route.headers,
|
|
220
|
+
'Content-Type': 'application/json',
|
|
221
|
+
},
|
|
222
|
+
method: 'POST',
|
|
223
|
+
retry: true,
|
|
224
|
+
timeout: this._timeout,
|
|
225
|
+
url: route.url,
|
|
226
|
+
path: route.endpoint,
|
|
227
|
+
}
|
|
228
|
+
if (route.agent) requestOptions.agent = route.agent
|
|
229
|
+
|
|
217
230
|
return {
|
|
218
231
|
url: route.url,
|
|
219
232
|
endpoint: route.endpoint,
|
|
220
|
-
requestOptions
|
|
221
|
-
...(route.agent && { agent: route.agent }),
|
|
222
|
-
headers: {
|
|
223
|
-
...route.headers,
|
|
224
|
-
'Content-Type': 'application/json',
|
|
225
|
-
},
|
|
226
|
-
method: 'POST',
|
|
227
|
-
retry: true,
|
|
228
|
-
timeout: this._timeout,
|
|
229
|
-
url: route.url,
|
|
230
|
-
path: route.endpoint,
|
|
231
|
-
},
|
|
233
|
+
requestOptions,
|
|
232
234
|
}
|
|
233
235
|
}
|
|
234
236
|
|
|
@@ -75,8 +75,8 @@ function setAgentlessStrategy (config, setWriterEnabledValue) {
|
|
|
75
75
|
headers: {
|
|
76
76
|
[EVP_SUBDOMAIN_HEADER_NAME]: EVP_EVENT_PLATFORM_SUBDOMAIN,
|
|
77
77
|
},
|
|
78
|
-
...(directRoute && { fallback: directRoute }),
|
|
79
78
|
}
|
|
79
|
+
if (directRoute) route.fallback = directRoute
|
|
80
80
|
logger.debug('FFE Writer enabled with local EVP route %s', route.basePath)
|
|
81
81
|
setWriterEnabledValue(true, route)
|
|
82
82
|
return
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const { buildResourceAttributes, registerResourceAttributeRefresh } = require('../resource-attributes')
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @typedef {import('../../config')} Config
|
|
@@ -37,35 +37,13 @@ const OtlpHttpLogExporter = require('./otlp_http_log_exporter')
|
|
|
37
37
|
* @param {import('../../config/config-base')} config - Tracer configuration instance
|
|
38
38
|
*/
|
|
39
39
|
function initializeOpenTelemetryLogs (config) {
|
|
40
|
-
// Build resource attributes
|
|
41
|
-
const resourceAttributes = {
|
|
42
|
-
'service.name': config.service,
|
|
43
|
-
'service.version': config.version,
|
|
44
|
-
'deployment.environment': config.env,
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Add all tracer tags (includes DD_TAGS, OTEL_RESOURCE_ATTRIBUTES, DD_TRACE_TAGS, etc.)
|
|
48
|
-
// Exclude Datadog-style keys that duplicate OpenTelemetry standard keys
|
|
49
|
-
if (config.tags) {
|
|
50
|
-
const filteredTags = { ...config.tags }
|
|
51
|
-
delete filteredTags.service
|
|
52
|
-
delete filteredTags.version
|
|
53
|
-
delete filteredTags.env
|
|
54
|
-
Object.assign(resourceAttributes, filteredTags)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Add host.name if reportHostname is enabled
|
|
58
|
-
if (config.reportHostname) {
|
|
59
|
-
resourceAttributes['host.name'] = os.hostname()
|
|
60
|
-
}
|
|
61
|
-
|
|
62
40
|
// Create OTLP exporter using resolved config values
|
|
63
41
|
const exporter = new OtlpHttpLogExporter(
|
|
64
42
|
config.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
|
|
65
43
|
config.OTEL_EXPORTER_OTLP_LOGS_HEADERS,
|
|
66
44
|
config.OTEL_EXPORTER_OTLP_LOGS_TIMEOUT,
|
|
67
45
|
config.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL,
|
|
68
|
-
|
|
46
|
+
buildResourceAttributes(config)
|
|
69
47
|
)
|
|
70
48
|
|
|
71
49
|
// Create batch processor for exporting logs to Datadog Agent
|
|
@@ -80,8 +58,11 @@ function initializeOpenTelemetryLogs (config) {
|
|
|
80
58
|
|
|
81
59
|
// Expose this provider to application calls through the OpenTelemetry Logs API.
|
|
82
60
|
loggerProvider.register()
|
|
61
|
+
|
|
83
62
|
// Include final log batches in lifecycle retention with trace delivery.
|
|
84
63
|
registerTelemetryFlusher(done => loggerProvider.forceFlush(done))
|
|
64
|
+
|
|
65
|
+
registerResourceAttributeRefresh(exporter, () => buildResourceAttributes(config))
|
|
85
66
|
}
|
|
86
67
|
|
|
87
68
|
module.exports = {
|
|
@@ -4,7 +4,7 @@ const OtlpHttpExporterBase = require('../otlp/otlp_http_exporter_base')
|
|
|
4
4
|
const OtlpTransformer = require('./otlp_transformer')
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* @typedef {import('@opentelemetry/
|
|
7
|
+
* @typedef {import('@opentelemetry/api').Attributes} Attributes
|
|
8
8
|
* @typedef {import('@opentelemetry/api-logs').LogRecord} LogRecord
|
|
9
9
|
*/
|
|
10
10
|
|
|
@@ -26,11 +26,21 @@ class OtlpHttpLogExporter extends OtlpHttpExporterBase {
|
|
|
26
26
|
* corresponding `OTEL_EXPORTER_OTLP_*_HEADERS` env by the MAP parser.
|
|
27
27
|
* @param {number} timeout - Request timeout in milliseconds
|
|
28
28
|
* @param {string} protocol - OTLP protocol (http/protobuf or http/json)
|
|
29
|
-
* @param {
|
|
29
|
+
* @param {Attributes} resourceAttributes - Resource attributes
|
|
30
30
|
*/
|
|
31
|
-
constructor (url, headers, timeout, protocol,
|
|
31
|
+
constructor (url, headers, timeout, protocol, resourceAttributes) {
|
|
32
32
|
super(url, headers, timeout, protocol, 'logs')
|
|
33
|
-
this.transformer = new OtlpTransformer(
|
|
33
|
+
this.transformer = new OtlpTransformer(resourceAttributes, protocol)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Recomputes the resource attributes baked into the transformer (e.g. after a MicroVM clone
|
|
38
|
+
* resume regenerates `runtime-id`).
|
|
39
|
+
*
|
|
40
|
+
* @param {Attributes} resourceAttributes - Resource attributes
|
|
41
|
+
*/
|
|
42
|
+
updateResourceAttributes (resourceAttributes) {
|
|
43
|
+
this.transformer.updateResourceAttributes(resourceAttributes)
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
/**
|
|
@@ -7,6 +7,10 @@ const { metrics } = require('@opentelemetry/api')
|
|
|
7
7
|
const { VERSION } = require('../../../../../version')
|
|
8
8
|
const processTags = require('../../process-tags')
|
|
9
9
|
const { registerTelemetryFlusher } = require('../../flush')
|
|
10
|
+
const {
|
|
11
|
+
buildResourceAttributes: buildGeneralResourceAttributes,
|
|
12
|
+
registerResourceAttributeRefresh,
|
|
13
|
+
} = require('../resource-attributes')
|
|
10
14
|
const MeterProvider = require('./meter_provider')
|
|
11
15
|
const PeriodicMetricReader = require('./periodic_metric_reader')
|
|
12
16
|
const OtlpHttpMetricExporter = require('./otlp_http_metric_exporter')
|
|
@@ -43,30 +47,12 @@ const RESERVED_TRACER_TAGS = new Set(['service', 'env', 'version', 'runtime_id',
|
|
|
43
47
|
* @param {import('../../config/config-base')} config - Tracer configuration instance
|
|
44
48
|
*/
|
|
45
49
|
function initializeOpenTelemetryMetrics (config) {
|
|
46
|
-
const resourceAttributes = {
|
|
47
|
-
'service.name': config.service,
|
|
48
|
-
'service.version': config.version,
|
|
49
|
-
'deployment.environment': config.env,
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (config.tags) {
|
|
53
|
-
const filteredTags = { ...config.tags }
|
|
54
|
-
delete filteredTags.service
|
|
55
|
-
delete filteredTags.version
|
|
56
|
-
delete filteredTags.env
|
|
57
|
-
Object.assign(resourceAttributes, filteredTags)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (config.reportHostname) {
|
|
61
|
-
resourceAttributes['host.name'] = os.hostname()
|
|
62
|
-
}
|
|
63
|
-
|
|
64
50
|
const exporter = new OtlpHttpMetricExporter(
|
|
65
51
|
config.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT,
|
|
66
52
|
config.OTEL_EXPORTER_OTLP_METRICS_HEADERS,
|
|
67
53
|
config.OTEL_EXPORTER_OTLP_METRICS_TIMEOUT,
|
|
68
54
|
config.OTEL_EXPORTER_OTLP_METRICS_PROTOCOL,
|
|
69
|
-
|
|
55
|
+
buildGeneralResourceAttributes(config)
|
|
70
56
|
)
|
|
71
57
|
|
|
72
58
|
const reader = new PeriodicMetricReader(
|
|
@@ -78,8 +64,11 @@ function initializeOpenTelemetryMetrics (config) {
|
|
|
78
64
|
|
|
79
65
|
const meterProvider = new MeterProvider({ reader })
|
|
80
66
|
metrics.setGlobalMeterProvider(meterProvider)
|
|
67
|
+
|
|
81
68
|
// Include the final metric collection and export in lifecycle retention.
|
|
82
69
|
registerTelemetryFlusher(done => meterProvider.forceFlush(done))
|
|
70
|
+
|
|
71
|
+
registerResourceAttributeRefresh(exporter, () => buildGeneralResourceAttributes(config))
|
|
83
72
|
}
|
|
84
73
|
|
|
85
74
|
/**
|
|
@@ -122,19 +111,23 @@ function buildResourceAttributes (tags, { reportHostname, service, env, serviceV
|
|
|
122
111
|
function createOtlpSpanStatsExporter (config) {
|
|
123
112
|
const { OtlpStatsExporter } = require('./otlp_span_stats_exporter')
|
|
124
113
|
const protocol = config.OTEL_EXPORTER_OTLP_METRICS_PROTOCOL || 'http/json'
|
|
125
|
-
const
|
|
114
|
+
const buildSpanStatsResourceAttributes = () => buildResourceAttributes(config.tags, {
|
|
126
115
|
reportHostname: config.reportHostname,
|
|
127
116
|
service: config.service,
|
|
128
117
|
env: config.env,
|
|
129
118
|
serviceVersion: config.version,
|
|
130
119
|
})
|
|
131
|
-
|
|
120
|
+
const exporter = new OtlpStatsExporter(
|
|
132
121
|
config.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT,
|
|
133
122
|
protocol,
|
|
134
|
-
|
|
123
|
+
buildSpanStatsResourceAttributes(),
|
|
135
124
|
config.OTEL_EXPORTER_OTLP_METRICS_HEADERS,
|
|
136
125
|
config.OTEL_EXPORTER_OTLP_METRICS_TIMEOUT
|
|
137
126
|
)
|
|
127
|
+
|
|
128
|
+
registerResourceAttributeRefresh(exporter, buildSpanStatsResourceAttributes)
|
|
129
|
+
|
|
130
|
+
return exporter
|
|
138
131
|
}
|
|
139
132
|
|
|
140
133
|
module.exports = {
|
|
@@ -4,7 +4,7 @@ const OtlpHttpExporterBase = require('../otlp/otlp_http_exporter_base')
|
|
|
4
4
|
const OtlpTransformer = require('./otlp_transformer')
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* @typedef {import('@opentelemetry/
|
|
7
|
+
* @typedef {import('@opentelemetry/api').Attributes} Attributes
|
|
8
8
|
* @typedef {import('./periodic_metric_reader').AggregatedMetric} AggregatedMetric
|
|
9
9
|
*/
|
|
10
10
|
|
|
@@ -22,11 +22,21 @@ class OtlpHttpMetricExporter extends OtlpHttpExporterBase {
|
|
|
22
22
|
* corresponding `OTEL_EXPORTER_OTLP_*_HEADERS` env by the MAP parser.
|
|
23
23
|
* @param {number} timeout - Request timeout in milliseconds
|
|
24
24
|
* @param {string} protocol - OTLP protocol (http/protobuf or http/json)
|
|
25
|
-
* @param {
|
|
25
|
+
* @param {Attributes} resourceAttributes - Resource attributes
|
|
26
26
|
*/
|
|
27
|
-
constructor (url, headers, timeout, protocol,
|
|
27
|
+
constructor (url, headers, timeout, protocol, resourceAttributes) {
|
|
28
28
|
super(url, headers, timeout, protocol, 'metrics')
|
|
29
|
-
this.transformer = new OtlpTransformer(
|
|
29
|
+
this.transformer = new OtlpTransformer(resourceAttributes, protocol)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Recomputes the resource attributes baked into the transformer (e.g. after a MicroVM clone
|
|
34
|
+
* resume regenerates `runtime-id`). Leaves the reader's export interval untouched.
|
|
35
|
+
*
|
|
36
|
+
* @param {Attributes} resourceAttributes - Resource attributes
|
|
37
|
+
*/
|
|
38
|
+
updateResourceAttributes (resourceAttributes) {
|
|
39
|
+
this.transformer.updateResourceAttributes(resourceAttributes)
|
|
30
40
|
}
|
|
31
41
|
|
|
32
42
|
/**
|
|
@@ -19,6 +19,16 @@ class OtlpStatsExporter extends OtlpHttpExporterBase {
|
|
|
19
19
|
this.#transformer = new OtlpStatsTransformer(resourceAttributes, protocol)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Recomputes the resource attributes baked into the transformer (e.g. after a MicroVM clone
|
|
24
|
+
* resume regenerates `runtime-id`).
|
|
25
|
+
*
|
|
26
|
+
* @param {import('@opentelemetry/api').Attributes} resourceAttributes
|
|
27
|
+
*/
|
|
28
|
+
updateResourceAttributes (resourceAttributes) {
|
|
29
|
+
this.#transformer.updateResourceAttributes(resourceAttributes)
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
/**
|
|
23
33
|
* @param {Array<{timeNs: number, bucket: import('../../span_stats').SpanBuckets}>} drained
|
|
24
34
|
* @param {number} bucketSizeNs
|
|
@@ -75,6 +75,16 @@ class OtlpTransformerBase {
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Recomputes the cached OTLP resource attributes (e.g. after `config.tags` changes post-
|
|
80
|
+
* construction, such as a MicroVM clone resume regenerating its runtime-id). Leaves the
|
|
81
|
+
* reader/exporter/protocol otherwise untouched.
|
|
82
|
+
* @param {Attributes} resourceAttributes - Resource attributes
|
|
83
|
+
*/
|
|
84
|
+
updateResourceAttributes (resourceAttributes) {
|
|
85
|
+
this.#resourceAttributes = this.transformAttributes(resourceAttributes)
|
|
86
|
+
}
|
|
87
|
+
|
|
78
88
|
/**
|
|
79
89
|
* Transforms attributes to OTLP KeyValue format.
|
|
80
90
|
* @param {Attributes} attributes - Attributes to transform
|
|
@@ -170,10 +180,15 @@ function stableStringify (attributes) {
|
|
|
170
180
|
// Attributes are sorted by key to ensure consistent serialization regardless of key order.
|
|
171
181
|
// Keys are always strings and values are always strings, numbers, booleans,
|
|
172
182
|
// or arrays of strings, numbers, or booleans.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
183
|
+
const keys = Object.keys(attributes).sort()
|
|
184
|
+
let serialized = ''
|
|
185
|
+
let isFirstKey = true
|
|
186
|
+
for (const key of keys) {
|
|
187
|
+
if (!isFirstKey) serialized += ','
|
|
188
|
+
serialized += `${key}:${JSON.stringify(attributes[key])}`
|
|
189
|
+
isFirstKey = false
|
|
190
|
+
}
|
|
191
|
+
return serialized
|
|
177
192
|
}
|
|
178
193
|
|
|
179
194
|
module.exports = OtlpTransformerBase
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const os = require('node:os')
|
|
4
|
+
|
|
5
|
+
const { channel } = require('dc-polyfill')
|
|
6
|
+
|
|
7
|
+
const identityRefreshChannel = channel('datadog:identity:refresh')
|
|
8
|
+
const resourceAttributeRefreshers = new Map()
|
|
9
|
+
|
|
10
|
+
function refreshActiveResourceAttributes () {
|
|
11
|
+
for (const refreshResourceAttributes of resourceAttributeRefreshers.values()) {
|
|
12
|
+
refreshResourceAttributes()
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {import('@opentelemetry/api').Attributes} Attributes
|
|
18
|
+
* @typedef {{
|
|
19
|
+
* signalType: string,
|
|
20
|
+
* updateResourceAttributes: (resourceAttributes: Attributes) => void
|
|
21
|
+
* }} ResourceAttributeExporter
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {import('../config/config-base')} config
|
|
26
|
+
* @returns {Attributes}
|
|
27
|
+
*/
|
|
28
|
+
function buildResourceAttributes (config) {
|
|
29
|
+
const { service, version, env, ...tags } = config.tags
|
|
30
|
+
const resourceAttributes = {
|
|
31
|
+
'service.name': config.service,
|
|
32
|
+
'service.version': config.version,
|
|
33
|
+
'deployment.environment': config.env,
|
|
34
|
+
...tags,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (config.reportHostname) resourceAttributes['host.name'] = os.hostname()
|
|
38
|
+
|
|
39
|
+
return resourceAttributes
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {ResourceAttributeExporter} exporter
|
|
44
|
+
* @param {() => Attributes} buildResourceAttributes
|
|
45
|
+
*/
|
|
46
|
+
function registerResourceAttributeRefresh (exporter, buildResourceAttributes) {
|
|
47
|
+
if (resourceAttributeRefreshers.size === 0) {
|
|
48
|
+
identityRefreshChannel.subscribe(refreshActiveResourceAttributes)
|
|
49
|
+
}
|
|
50
|
+
resourceAttributeRefreshers.set(exporter.signalType, () => {
|
|
51
|
+
exporter.updateResourceAttributes(buildResourceAttributes())
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = { buildResourceAttributes, registerResourceAttributeRefresh }
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { VERSION } = require('../../../../../version')
|
|
4
|
+
const { registerResourceAttributeRefresh } = require('../resource-attributes')
|
|
4
5
|
const OtlpHttpTraceExporter = require('./otlp_http_trace_exporter')
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -59,13 +60,17 @@ function buildResourceAttributes (config) {
|
|
|
59
60
|
* @returns {OtlpHttpTraceExporter} The OTLP HTTP/JSON exporter
|
|
60
61
|
*/
|
|
61
62
|
function createOtlpTraceExporter (config) {
|
|
62
|
-
|
|
63
|
+
const exporter = new OtlpHttpTraceExporter(
|
|
63
64
|
config.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
|
|
64
65
|
config.OTEL_EXPORTER_OTLP_TRACES_HEADERS,
|
|
65
66
|
config.OTEL_EXPORTER_OTLP_TRACES_TIMEOUT,
|
|
66
67
|
buildResourceAttributes(config),
|
|
67
68
|
config.DD_TRACE_OTEL_SEMANTICS_ENABLED
|
|
68
69
|
)
|
|
70
|
+
|
|
71
|
+
registerResourceAttributeRefresh(exporter, () => buildResourceAttributes(config))
|
|
72
|
+
|
|
73
|
+
return exporter
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
module.exports = {
|
|
@@ -43,6 +43,16 @@ class OtlpHttpTraceExporter extends OtlpHttpExporterBase {
|
|
|
43
43
|
this.#transformer = new OtlpTraceTransformer(resourceAttributes, otelTraceSemanticsEnabled)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Recomputes the resource attributes baked into the transformer (e.g. after a MicroVM clone
|
|
48
|
+
* resume regenerates `runtime-id`).
|
|
49
|
+
*
|
|
50
|
+
* @param {import('@opentelemetry/api').Attributes} resourceAttributes - Resource attributes
|
|
51
|
+
*/
|
|
52
|
+
updateResourceAttributes (resourceAttributes) {
|
|
53
|
+
this.#transformer.updateResourceAttributes(resourceAttributes)
|
|
54
|
+
}
|
|
55
|
+
|
|
46
56
|
/**
|
|
47
57
|
* Exports DD-formatted spans via OTLP over HTTP.
|
|
48
58
|
*
|