dd-trace 5.79.0 → 5.81.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.
Files changed (242) hide show
  1. package/LICENSE-3rdparty.csv +79 -87
  2. package/ext/tags.d.ts +1 -0
  3. package/ext/tags.js +1 -0
  4. package/index.d.ts +46 -39
  5. package/initialize.mjs +10 -10
  6. package/loader-hook.mjs +10 -3
  7. package/package.json +23 -40
  8. package/packages/datadog-core/src/storage.js +4 -4
  9. package/packages/datadog-esbuild/index.js +36 -19
  10. package/packages/datadog-esbuild/src/utils.js +5 -1
  11. package/packages/datadog-instrumentations/index.js +1 -0
  12. package/packages/datadog-instrumentations/src/anthropic.js +12 -0
  13. package/packages/datadog-instrumentations/src/aws-sdk.js +13 -2
  14. package/packages/datadog-instrumentations/src/azure-service-bus.js +43 -36
  15. package/packages/datadog-instrumentations/src/cucumber.js +2 -2
  16. package/packages/datadog-instrumentations/src/find-my-way.js +6 -5
  17. package/packages/datadog-instrumentations/src/google-genai.js +120 -0
  18. package/packages/datadog-instrumentations/src/graphql.js +20 -0
  19. package/packages/datadog-instrumentations/src/helpers/hook.js +1 -0
  20. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  21. package/packages/datadog-instrumentations/src/helpers/instrument.js +12 -1
  22. package/packages/datadog-instrumentations/src/helpers/register.js +6 -1
  23. package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +27 -0
  24. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +152 -0
  25. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +5 -0
  26. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/langchain.js +237 -0
  27. package/packages/datadog-instrumentations/src/helpers/rewriter/loader.js +9 -0
  28. package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +11 -0
  29. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +139 -0
  30. package/packages/datadog-instrumentations/src/jest.js +1 -1
  31. package/packages/datadog-instrumentations/src/langchain.js +3 -109
  32. package/packages/datadog-instrumentations/src/mocha/main.js +1 -1
  33. package/packages/datadog-instrumentations/src/mysql2.js +1 -1
  34. package/packages/datadog-instrumentations/src/playwright.js +65 -16
  35. package/packages/datadog-instrumentations/src/router.js +1 -1
  36. package/packages/datadog-instrumentations/src/selenium.js +3 -1
  37. package/packages/datadog-instrumentations/src/ws.js +35 -17
  38. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +3 -2
  39. package/packages/datadog-plugin-azure-service-bus/src/producer.js +14 -5
  40. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +1 -1
  41. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +23 -2
  42. package/packages/datadog-plugin-cypress/src/plugin.js +1 -1
  43. package/packages/datadog-plugin-cypress/src/support.js +73 -31
  44. package/packages/datadog-plugin-google-genai/src/index.js +17 -0
  45. package/packages/datadog-plugin-google-genai/src/tracing.js +41 -0
  46. package/packages/datadog-plugin-graphql/src/tools/transforms.js +5 -4
  47. package/packages/datadog-plugin-jest/src/util.js +4 -3
  48. package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -1
  49. package/packages/datadog-plugin-kafkajs/src/producer.js +3 -1
  50. package/packages/datadog-plugin-langchain/src/tracing.js +7 -3
  51. package/packages/datadog-plugin-next/src/index.js +11 -3
  52. package/packages/datadog-plugin-openai/src/stream-helpers.js +1 -1
  53. package/packages/datadog-shimmer/src/shimmer.js +2 -2
  54. package/packages/dd-trace/src/aiguard/sdk.js +29 -14
  55. package/packages/dd-trace/src/appsec/api_security_sampler.js +1 -1
  56. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +1 -1
  57. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -1
  58. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +1 -2
  59. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
  60. package/packages/dd-trace/src/appsec/reporter.js +0 -4
  61. package/packages/dd-trace/src/baggage.js +11 -0
  62. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +4 -8
  63. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +1 -1
  64. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +4 -2
  65. package/packages/dd-trace/src/config.js +81 -7
  66. package/packages/dd-trace/src/config_defaults.js +15 -2
  67. package/packages/dd-trace/src/datastreams/encoding.js +23 -6
  68. package/packages/dd-trace/src/datastreams/pathway.js +40 -1
  69. package/packages/dd-trace/src/datastreams/processor.js +1 -1
  70. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -1
  71. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +15 -5
  72. package/packages/dd-trace/src/debugger/devtools_client/condition.js +1 -1
  73. package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
  74. package/packages/dd-trace/src/debugger/devtools_client/index.js +30 -15
  75. package/packages/dd-trace/src/debugger/devtools_client/inspector_promises_polyfill.js +2 -0
  76. package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +24 -18
  77. package/packages/dd-trace/src/debugger/devtools_client/send.js +18 -8
  78. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +103 -15
  79. package/packages/dd-trace/src/debugger/devtools_client/snapshot/constants.js +25 -0
  80. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +56 -25
  81. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +64 -23
  82. package/packages/dd-trace/src/debugger/devtools_client/snapshot/symbols.js +3 -1
  83. package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +404 -0
  84. package/packages/dd-trace/src/debugger/devtools_client/source-maps.js +1 -1
  85. package/packages/dd-trace/src/debugger/devtools_client/state.js +7 -2
  86. package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
  87. package/packages/dd-trace/src/debugger/index.js +1 -1
  88. package/packages/dd-trace/src/encode/0.4.js +3 -3
  89. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +2 -2
  90. package/packages/dd-trace/src/encode/span-stats.js +7 -1
  91. package/packages/dd-trace/src/exporters/agent/writer.js +6 -13
  92. package/packages/dd-trace/src/histogram.js +1 -1
  93. package/packages/dd-trace/src/id.js +60 -0
  94. package/packages/dd-trace/src/lambda/runtime/ritm.js +2 -3
  95. package/packages/dd-trace/src/llmobs/constants/tags.js +1 -0
  96. package/packages/dd-trace/src/llmobs/index.js +5 -5
  97. package/packages/dd-trace/src/llmobs/noop.js +6 -0
  98. package/packages/dd-trace/src/llmobs/plugins/ai/index.js +1 -0
  99. package/packages/dd-trace/src/llmobs/plugins/genai/index.js +104 -0
  100. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +486 -0
  101. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +2 -2
  102. package/packages/dd-trace/src/llmobs/plugins/{openai.js → openai/index.js} +87 -39
  103. package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +114 -0
  104. package/packages/dd-trace/src/llmobs/sdk.js +10 -1
  105. package/packages/dd-trace/src/llmobs/span_processor.js +11 -6
  106. package/packages/dd-trace/src/llmobs/tagger.js +35 -17
  107. package/packages/dd-trace/src/msgpack/chunk.js +2 -2
  108. package/packages/dd-trace/src/msgpack/encoder.js +2 -3
  109. package/packages/dd-trace/src/msgpack/index.js +2 -2
  110. package/packages/dd-trace/src/openfeature/flagging_provider.js +5 -3
  111. package/packages/dd-trace/src/opentelemetry/logs/index.js +3 -3
  112. package/packages/dd-trace/src/opentelemetry/logs/logger.js +14 -8
  113. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +6 -4
  114. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +9 -17
  115. package/packages/dd-trace/src/opentelemetry/metrics/constants.js +34 -0
  116. package/packages/dd-trace/src/opentelemetry/metrics/index.js +81 -0
  117. package/packages/dd-trace/src/opentelemetry/metrics/instruments.js +225 -0
  118. package/packages/dd-trace/src/opentelemetry/metrics/meter.js +171 -0
  119. package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +54 -0
  120. package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +62 -0
  121. package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +251 -0
  122. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +532 -0
  123. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +10 -18
  124. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +36 -22
  125. package/packages/dd-trace/src/opentelemetry/otlp/protobuf_loader.js +2 -2
  126. package/packages/dd-trace/src/opentelemetry/span.js +1 -1
  127. package/packages/dd-trace/src/opentelemetry/tracer.js +1 -1
  128. package/packages/dd-trace/src/opentelemetry/tracer_provider.js +1 -1
  129. package/packages/dd-trace/src/payload-tagging/index.js +2 -2
  130. package/packages/dd-trace/src/plugin_manager.js +4 -2
  131. package/packages/dd-trace/src/plugins/database.js +1 -0
  132. package/packages/dd-trace/src/plugins/index.js +1 -0
  133. package/packages/dd-trace/src/plugins/plugin.js +7 -9
  134. package/packages/dd-trace/src/plugins/util/test.js +3 -3
  135. package/packages/dd-trace/src/plugins/util/url.js +119 -1
  136. package/packages/dd-trace/src/plugins/util/web.js +10 -41
  137. package/packages/dd-trace/src/process-tags/index.js +81 -0
  138. package/packages/dd-trace/src/profiling/config.js +1 -1
  139. package/packages/dd-trace/src/profiling/exporter_cli.js +7 -6
  140. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  141. package/packages/dd-trace/src/profiling/profilers/events.js +10 -1
  142. package/packages/dd-trace/src/proxy.js +5 -0
  143. package/packages/dd-trace/src/rate_limiter.js +1 -1
  144. package/packages/dd-trace/src/remote_config/manager.js +1 -1
  145. package/packages/dd-trace/src/require-package-json.js +1 -1
  146. package/packages/dd-trace/src/ritm.js +1 -1
  147. package/packages/dd-trace/src/service-naming/index.js +31 -4
  148. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +4 -0
  149. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +4 -0
  150. package/packages/dd-trace/src/{format.js → span_format.js} +9 -4
  151. package/packages/dd-trace/src/span_processor.js +16 -11
  152. package/packages/dd-trace/src/span_stats.js +15 -4
  153. package/packages/dd-trace/src/spanleak.js +1 -1
  154. package/packages/dd-trace/src/supported-configurations.json +13 -0
  155. package/packages/dd-trace/src/telemetry/dependencies.js +1 -1
  156. package/packages/dd-trace/src/telemetry/telemetry.js +11 -2
  157. package/vendor/dist/@datadog/sketches-js/LICENSE +39 -0
  158. package/vendor/dist/@datadog/sketches-js/index.js +1 -0
  159. package/vendor/dist/@datadog/source-map/LICENSE +28 -0
  160. package/vendor/dist/@datadog/source-map/index.js +1 -0
  161. package/vendor/dist/@isaacs/ttlcache/LICENSE +55 -0
  162. package/vendor/dist/@isaacs/ttlcache/index.js +1 -0
  163. package/vendor/dist/@opentelemetry/core/LICENSE +201 -0
  164. package/vendor/dist/@opentelemetry/core/index.js +1 -0
  165. package/vendor/dist/@opentelemetry/resources/LICENSE +201 -0
  166. package/vendor/dist/@opentelemetry/resources/index.js +1 -0
  167. package/vendor/dist/astring/LICENSE +19 -0
  168. package/vendor/dist/astring/index.js +1 -0
  169. package/vendor/dist/crypto-randomuuid/index.js +1 -0
  170. package/vendor/dist/escape-string-regexp/LICENSE +9 -0
  171. package/vendor/dist/escape-string-regexp/index.js +1 -0
  172. package/vendor/dist/esquery/LICENSE +24 -0
  173. package/vendor/dist/esquery/index.js +1 -0
  174. package/vendor/dist/ignore/LICENSE +21 -0
  175. package/vendor/dist/ignore/index.js +1 -0
  176. package/vendor/dist/istanbul-lib-coverage/LICENSE +24 -0
  177. package/vendor/dist/istanbul-lib-coverage/index.js +1 -0
  178. package/vendor/dist/jest-docblock/LICENSE +21 -0
  179. package/vendor/dist/jest-docblock/index.js +1 -0
  180. package/vendor/dist/jsonpath-plus/LICENSE +22 -0
  181. package/vendor/dist/jsonpath-plus/index.js +1 -0
  182. package/vendor/dist/limiter/LICENSE +19 -0
  183. package/vendor/dist/limiter/index.js +1 -0
  184. package/vendor/dist/lodash.sortby/LICENSE +47 -0
  185. package/vendor/dist/lodash.sortby/index.js +1 -0
  186. package/vendor/dist/lru-cache/LICENSE +15 -0
  187. package/vendor/dist/lru-cache/index.js +1 -0
  188. package/vendor/dist/meriyah/LICENSE +7 -0
  189. package/vendor/dist/meriyah/index.js +1 -0
  190. package/vendor/dist/module-details-from-path/LICENSE +21 -0
  191. package/vendor/dist/module-details-from-path/index.js +1 -0
  192. package/vendor/dist/mutexify/promise/LICENSE +21 -0
  193. package/vendor/dist/mutexify/promise/index.js +1 -0
  194. package/vendor/dist/opentracing/LICENSE +201 -0
  195. package/vendor/dist/opentracing/binary_carrier.d.ts +11 -0
  196. package/vendor/dist/opentracing/constants.d.ts +61 -0
  197. package/vendor/dist/opentracing/examples/demo/demo.d.ts +2 -0
  198. package/vendor/dist/opentracing/ext/tags.d.ts +90 -0
  199. package/vendor/dist/opentracing/functions.d.ts +20 -0
  200. package/vendor/dist/opentracing/global_tracer.d.ts +14 -0
  201. package/vendor/dist/opentracing/index.d.ts +12 -0
  202. package/vendor/dist/opentracing/index.js +1 -0
  203. package/vendor/dist/opentracing/mock_tracer/index.d.ts +5 -0
  204. package/vendor/dist/opentracing/mock_tracer/mock_context.d.ts +13 -0
  205. package/vendor/dist/opentracing/mock_tracer/mock_report.d.ts +16 -0
  206. package/vendor/dist/opentracing/mock_tracer/mock_span.d.ts +50 -0
  207. package/vendor/dist/opentracing/mock_tracer/mock_tracer.d.ts +26 -0
  208. package/vendor/dist/opentracing/noop.d.ts +8 -0
  209. package/vendor/dist/opentracing/reference.d.ts +33 -0
  210. package/vendor/dist/opentracing/span.d.ts +147 -0
  211. package/vendor/dist/opentracing/span_context.d.ts +26 -0
  212. package/vendor/dist/opentracing/test/api_compatibility.d.ts +16 -0
  213. package/vendor/dist/opentracing/test/mocktracer_implemenation.d.ts +3 -0
  214. package/vendor/dist/opentracing/test/noop_implementation.d.ts +4 -0
  215. package/vendor/dist/opentracing/test/opentracing_api.d.ts +3 -0
  216. package/vendor/dist/opentracing/test/unittest.d.ts +2 -0
  217. package/vendor/dist/opentracing/tracer.d.ts +127 -0
  218. package/vendor/dist/path-to-regexp/LICENSE +21 -0
  219. package/vendor/dist/path-to-regexp/index.js +1 -0
  220. package/vendor/dist/pprof-format/LICENSE +8 -0
  221. package/vendor/dist/pprof-format/index.js +1 -0
  222. package/vendor/dist/protobufjs/LICENSE +39 -0
  223. package/vendor/dist/protobufjs/index.js +1 -0
  224. package/vendor/dist/protobufjs/minimal/LICENSE +39 -0
  225. package/vendor/dist/protobufjs/minimal/index.js +1 -0
  226. package/vendor/dist/retry/LICENSE +21 -0
  227. package/vendor/dist/retry/index.js +1 -0
  228. package/vendor/dist/rfdc/LICENSE +15 -0
  229. package/vendor/dist/rfdc/index.js +1 -0
  230. package/vendor/dist/semifies/LICENSE +201 -0
  231. package/vendor/dist/semifies/index.js +1 -0
  232. package/vendor/dist/shell-quote/LICENSE +24 -0
  233. package/vendor/dist/shell-quote/index.js +1 -0
  234. package/vendor/dist/source-map/LICENSE +28 -0
  235. package/vendor/dist/source-map/index.js +1 -0
  236. package/vendor/dist/source-map/lib/util/LICENSE +28 -0
  237. package/vendor/dist/source-map/lib/util/index.js +1 -0
  238. package/vendor/dist/source-map/mappings.wasm +0 -0
  239. package/vendor/dist/tlhunter-sorted-set/LICENSE +21 -0
  240. package/vendor/dist/tlhunter-sorted-set/index.js +1 -0
  241. package/vendor/dist/ttl-set/LICENSE +21 -0
  242. package/vendor/dist/ttl-set/index.js +1 -0
@@ -0,0 +1,81 @@
1
+ 'use strict'
2
+
3
+ const os = require('os')
4
+
5
+ /**
6
+ * @typedef {import('../../config')} Config
7
+ */
8
+
9
+ /**
10
+ * @file OpenTelemetry Metrics Implementation for dd-trace-js
11
+ *
12
+ * This package provides a custom OpenTelemetry Metrics implementation that integrates
13
+ * with the Datadog tracing library. It includes all necessary components for
14
+ * creating instruments, recording measurements, and exporting metrics via OTLP.
15
+ *
16
+ * Key Components:
17
+ * - MeterProvider: Main entry point for creating meters
18
+ * - Meter: Provides methods to create metric instruments
19
+ * - Instruments: Gauge, Counter, UpDownCounter, ObservableGauge, ObservableCounter, ObservableUpDownCounter, Histogram
20
+ * - PeriodicMetricReader: Collects and exports instruments (metrics) at regular intervals
21
+ * - OtlpHttpMetricExporter: Exports instruments (metrics) via OTLP over HTTP
22
+ * - OtlpTransformer: Transforms instruments (metrics) to OTLP format
23
+ *
24
+ * This is a custom implementation to avoid pulling in the full OpenTelemetry SDK,
25
+ * based on OTLP Protocol v1.7.0. It supports both protobuf and JSON serialization
26
+ * formats and integrates with Datadog's configuration system.
27
+ *
28
+ * @package
29
+ */
30
+
31
+ const { metrics } = require('@opentelemetry/api')
32
+ const MeterProvider = require('./meter_provider')
33
+ const PeriodicMetricReader = require('./periodic_metric_reader')
34
+ const OtlpHttpMetricExporter = require('./otlp_http_metric_exporter')
35
+
36
+ /**
37
+ * Initializes OpenTelemetry Metrics support
38
+ * @param {Config} config - Tracer configuration instance
39
+ */
40
+ function initializeOpenTelemetryMetrics (config) {
41
+ const resourceAttributes = {
42
+ 'service.name': config.service,
43
+ 'service.version': config.version,
44
+ 'deployment.environment': config.env
45
+ }
46
+
47
+ if (config.tags) {
48
+ const filteredTags = { ...config.tags }
49
+ delete filteredTags.service
50
+ delete filteredTags.version
51
+ delete filteredTags.env
52
+ Object.assign(resourceAttributes, filteredTags)
53
+ }
54
+
55
+ if (config.reportHostname) {
56
+ resourceAttributes['host.name'] = os.hostname()
57
+ }
58
+
59
+ const exporter = new OtlpHttpMetricExporter(
60
+ config.otelMetricsUrl,
61
+ config.otelMetricsHeaders,
62
+ config.otelMetricsTimeout,
63
+ config.otelMetricsProtocol,
64
+ resourceAttributes
65
+ )
66
+
67
+ const reader = new PeriodicMetricReader(
68
+ exporter,
69
+ config.otelMetricsExportInterval,
70
+ config.otelMetricsTemporalityPreference,
71
+ config.otelMaxQueueSize
72
+ )
73
+
74
+ const meterProvider = new MeterProvider({ reader })
75
+ metrics.setGlobalMeterProvider(meterProvider)
76
+ }
77
+
78
+ module.exports = {
79
+ MeterProvider,
80
+ initializeOpenTelemetryMetrics
81
+ }
@@ -0,0 +1,225 @@
1
+ 'use strict'
2
+
3
+ const { sanitizeAttributes } = require('../../../../../vendor/dist/@opentelemetry/core')
4
+ const { METRIC_TYPES } = require('./constants')
5
+
6
+ /**
7
+ * @typedef {import('@opentelemetry/api').Attributes} Attributes
8
+ * @typedef {import('@opentelemetry/core').InstrumentationScope} InstrumentationScope
9
+ */
10
+
11
+ /**
12
+ * @typedef {Object} Measurement
13
+ * @property {string} name - Instrument name
14
+ * @property {string} description - Instrument description
15
+ * @property {string} unit - Measurement unit
16
+ * @property {InstrumentationScope} instrumentationScope - Instrumentation scope
17
+ * @property {string} type - Metric type from METRIC_TYPES
18
+ * @property {number} value - Measured value
19
+ * @property {Attributes} attributes - Sanitized metric attributes
20
+ * @property {number} timestamp - Timestamp in nanoseconds
21
+ */
22
+
23
+ /**
24
+ * Base class for all metric instruments.
25
+ *
26
+ *
27
+ */
28
+ class Instrument {
29
+ /**
30
+ * Creates a new instrument instance.
31
+ *
32
+ * @param {string} name - Instrument name (e.g., 'http.request.duration')
33
+ * @param {Object} options - Instrument configuration options
34
+ * @param {string} [options.description] - Human-readable description of the instrument
35
+ * @param {string} [options.unit] - Unit of measurement (e.g., 'ms', 'bytes', '1')
36
+ * @param {InstrumentationScope} instrumentationScope - Instrumentation scope for this instrument
37
+ * @param {Object} reader - Metric reader for recording measurements
38
+ */
39
+ constructor (name, options, instrumentationScope, reader) {
40
+ this.name = name
41
+ this.description = options.description ?? ''
42
+ this.unit = options.unit ?? ''
43
+ this.valueType = options.valueType // currently ignored, TODO: add support for ValueType
44
+ this.advice = options.advice // currently ignored, TODO: add support for MetricAdvice
45
+ this.instrumentationScope = instrumentationScope
46
+ this.reader = reader
47
+ }
48
+
49
+ /**
50
+ * Creates a measurement object for recording metric values.
51
+ * @param {string} type - Metric type from METRIC_TYPES
52
+ * @param {number} value - Numeric value to record
53
+ * @param {Attributes} attributes - Key-value pairs for metric dimensions
54
+ * @returns {Measurement} Measurement object with metadata and timestamp
55
+ */
56
+ createMeasurement (type, value, attributes) {
57
+ return {
58
+ name: this.name,
59
+ description: this.description,
60
+ unit: this.unit,
61
+ instrumentationScope: this.instrumentationScope,
62
+ type,
63
+ value,
64
+ attributes: sanitizeAttributes(attributes),
65
+ timestamp: Number(process.hrtime.bigint())
66
+ }
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Implementation of the OpenTelemetry Counter interface:
72
+ * https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.Counter.html
73
+ * @class Counter
74
+ */
75
+ class Counter extends Instrument {
76
+ add (value, attributes = {}) {
77
+ if (value < 0) return
78
+ this.reader?.record(this.createMeasurement(METRIC_TYPES.COUNTER, value, attributes))
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Implementation of the OpenTelemetry UpDownCounter interface:
84
+ * https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.UpDownCounter.html
85
+ * @class UpDownCounter
86
+ */
87
+ class UpDownCounter extends Instrument {
88
+ add (value, attributes = {}) {
89
+ this.reader?.record(this.createMeasurement(METRIC_TYPES.UPDOWNCOUNTER, value, attributes))
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Implementation of the OpenTelemetry Histogram interface:
95
+ * https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.Histogram.html
96
+ * @class Histogram
97
+ */
98
+ class Histogram extends Instrument {
99
+ record (value, attributes = {}) {
100
+ if (value < 0) return
101
+ this.reader?.record(this.createMeasurement(METRIC_TYPES.HISTOGRAM, value, attributes))
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Implementation of the OpenTelemetry Gauge interface:
107
+ * https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.Gauge.html
108
+ * @class Gauge
109
+ */
110
+ class Gauge extends Instrument {
111
+ record (value, attributes = {}) {
112
+ this.reader?.record(this.createMeasurement(METRIC_TYPES.GAUGE, value, attributes))
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Base class for observable (asynchronous) instruments.
118
+ * Implementation of the OpenTelemetry Observable interface:
119
+ * https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.Observable.html
120
+ *
121
+ */
122
+ class ObservableInstrument extends Instrument {
123
+ #callbacks = []
124
+ #type
125
+
126
+ constructor (name, options, instrumentationScope, reader, type) {
127
+ super(name, options, instrumentationScope, reader)
128
+ this.#type = type
129
+ }
130
+
131
+ /**
132
+ * Adds a callback to invoke during metric collection.
133
+ *
134
+ * @param {Function} callback - Receives an ObservableResult to record observations
135
+ */
136
+ addCallback (callback) {
137
+ if (typeof callback !== 'function') return
138
+ this.#callbacks.push(callback)
139
+ this.reader?.observableInstruments.add(this)
140
+ }
141
+
142
+ /**
143
+ * Removes a callback.
144
+ *
145
+ * @param {Function} callback - The callback to remove
146
+ */
147
+ removeCallback (callback) {
148
+ const index = this.#callbacks.indexOf(callback)
149
+ if (index !== -1) {
150
+ this.#callbacks.splice(index, 1)
151
+ if (this.#callbacks.length === 0) {
152
+ // Remove instrument from collection when no callbacks remain
153
+ this.reader?.observableInstruments.delete(this)
154
+ }
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Collects observations from all callbacks. Errors are silently ignored.
160
+ *
161
+ * @returns {Array<Measurement>} Array of measurements
162
+ */
163
+ collect () {
164
+ const observations = []
165
+ const observableResult = {
166
+ observe: (value, attributes = {}) => {
167
+ observations.push(this.createMeasurement(this.#type, value, attributes))
168
+ }
169
+ }
170
+
171
+ for (const callback of this.#callbacks) {
172
+ try {
173
+ callback(observableResult)
174
+ } catch {
175
+ // Ignore callback errors per OpenTelemetry spec to prevent disruption
176
+ // Errors are swallowed as callbacks should not break metric collection
177
+ }
178
+ }
179
+
180
+ return observations
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Implementation of the OpenTelemetry ObservableGauge interface:
186
+ * https://open-telemetry.github.io/opentelemetry-js/types/_opentelemetry_api._opentelemetry_api.ObservableGauge.html
187
+ * @class ObservableGauge
188
+ */
189
+ class ObservableGauge extends ObservableInstrument {
190
+ constructor (name, options, instrumentationScope, reader) {
191
+ super(name, options, instrumentationScope, reader, METRIC_TYPES.GAUGE)
192
+ }
193
+ }
194
+
195
+ /**
196
+ * Implementation of the OpenTelemetry ObservableCounter interface:
197
+ * https://open-telemetry.github.io/opentelemetry-js/types/_opentelemetry_api._opentelemetry_api.ObservableCounter.html
198
+ * @class ObservableCounter
199
+ */
200
+ class ObservableCounter extends ObservableInstrument {
201
+ constructor (name, options, instrumentationScope, reader) {
202
+ super(name, options, instrumentationScope, reader, METRIC_TYPES.OBSERVABLECOUNTER)
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Implementation of the OpenTelemetry ObservableUpDownCounter interface:
208
+ * https://open-telemetry.github.io/opentelemetry-js/types/_opentelemetry_api._opentelemetry_api.ObservableUpDownCounter.html
209
+ * @class ObservableUpDownCounter
210
+ */
211
+ class ObservableUpDownCounter extends ObservableInstrument {
212
+ constructor (name, options, instrumentationScope, reader) {
213
+ super(name, options, instrumentationScope, reader, METRIC_TYPES.OBSERVABLEUPDOWNCOUNTER)
214
+ }
215
+ }
216
+
217
+ module.exports = {
218
+ Counter,
219
+ UpDownCounter,
220
+ Histogram,
221
+ Gauge,
222
+ ObservableGauge,
223
+ ObservableCounter,
224
+ ObservableUpDownCounter
225
+ }
@@ -0,0 +1,171 @@
1
+ 'use strict'
2
+
3
+ const { VERSION: packageVersion } = require('../../../../../version')
4
+ const {
5
+ Counter, UpDownCounter, Histogram, Gauge, ObservableGauge, ObservableCounter, ObservableUpDownCounter
6
+ } = require('./instruments')
7
+ const log = require('../../log')
8
+ const { METRIC_TYPES } = require('./constants')
9
+
10
+ /**
11
+ * @typedef {import('@opentelemetry/api').MetricOptions} MetricOptions
12
+ * @typedef {import('@opentelemetry/core').InstrumentationScope} InstrumentationScope
13
+ */
14
+
15
+ /**
16
+ * Meter provides methods to create metric instruments.
17
+ *
18
+ * This implementation follows the OpenTelemetry JavaScript API Meter:
19
+ * https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.Meter.html
20
+ *
21
+ * @class Meter
22
+ */
23
+ class Meter {
24
+ #instrumentationScope
25
+ #instruments = new Map()
26
+ /**
27
+ * Creates a new Meter instance.
28
+ *
29
+ * @param {MeterProvider} meterProvider - Parent meter provider
30
+ * @param {InstrumentationScope} instrumentationScope - Instrumentation scope information
31
+ * @param {string} [instrumentationScope.name] - Meter name (defaults to 'dd-trace-js')
32
+ * @param {string} [instrumentationScope.version] - Meter version (defaults to tracer version)
33
+ * @param {string} [instrumentationScope.schemaUrl] - Schema URL
34
+ * @param {Object} [instrumentationScope.attributes] - Attributes for the instrumentation scope
35
+ */
36
+ constructor (
37
+ meterProvider,
38
+ { name = 'dd-trace-js', version = packageVersion, schemaUrl = '', attributes = {} } = {}
39
+ ) {
40
+ this.meterProvider = meterProvider
41
+ this.#instrumentationScope = {
42
+ name,
43
+ version,
44
+ schemaUrl,
45
+ attributes,
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Gets an existing instrument or creates a new one if it doesn't exist.
51
+ * Instruments are cached by type and normalized (lowercase) name.
52
+ *
53
+ *
54
+ * @param {string} name - Instrument name (will be normalized to lowercase)
55
+ * @param {string} type - Instrument type (e.g., 'counter', 'histogram', 'gauge')
56
+ * @param {Function} InstrumentClass - Constructor for the instrument type
57
+ * @param {MetricOptions} [options] - Instrument options (description, unit, etc.)
58
+ * @returns {Instrument} The instrument instance (new or cached)
59
+ */
60
+ #getOrCreateInstrument (name, type, InstrumentClass, options) {
61
+ const normalizedName = name.toLowerCase()
62
+ const key = `${type}:${normalizedName}`
63
+ let instrument = this.#instruments.get(key)
64
+ if (!instrument) {
65
+ instrument = new InstrumentClass(
66
+ normalizedName, options, this.#instrumentationScope, this.meterProvider.reader
67
+ )
68
+ this.#instruments.set(key, instrument)
69
+ }
70
+ return instrument
71
+ }
72
+
73
+ /**
74
+ * Creates a Counter instrument.
75
+ *
76
+ * @param {string} name - Instrument name (case-insensitive)
77
+ * @param {MetricOptions} [options] - Instrument options
78
+ * @returns {Counter} Counter instrument
79
+ */
80
+ createCounter (name, options = {}) {
81
+ return this.#getOrCreateInstrument(name, METRIC_TYPES.COUNTER, Counter, options)
82
+ }
83
+
84
+ /**
85
+ * Creates an UpDownCounter instrument.
86
+ *
87
+ * @param {string} name - Instrument name
88
+ * @param {MetricOptions} [options] - Instrument options
89
+ * @returns {UpDownCounter} UpDownCounter instrument
90
+ */
91
+ createUpDownCounter (name, options = {}) {
92
+ return this.#getOrCreateInstrument(name, METRIC_TYPES.UPDOWNCOUNTER, UpDownCounter, options)
93
+ }
94
+
95
+ /**
96
+ * Creates a Histogram instrument.
97
+ *
98
+ * @param {string} name - Instrument name (case-insensitive)
99
+ * @param {MetricOptions} [options] - Instrument options
100
+ * @returns {Histogram} Histogram instrument
101
+ */
102
+ createHistogram (name, options = {}) {
103
+ return this.#getOrCreateInstrument(name, METRIC_TYPES.HISTOGRAM, Histogram, options)
104
+ }
105
+
106
+ /**
107
+ * Creates a Gauge instrument.
108
+ *
109
+ * @param {string} name - Instrument name (case-insensitive)
110
+ * @param {MetricOptions} [options] - Instrument options
111
+ * @returns {Gauge} Gauge instrument
112
+ */
113
+ createGauge (name, options = {}) {
114
+ return this.#getOrCreateInstrument(name, METRIC_TYPES.GAUGE, Gauge, options)
115
+ }
116
+
117
+ /**
118
+ * Creates an ObservableGauge instrument.
119
+ *
120
+ * @param {string} name - Instrument name (case-insensitive)
121
+ * @param {MetricOptions} [options] - Instrument options
122
+ * @returns {ObservableGauge} ObservableGauge instrument
123
+ */
124
+ createObservableGauge (name, options = {}) {
125
+ return this.#getOrCreateInstrument(name, METRIC_TYPES.OBSERVABLEGAUGE, ObservableGauge, options)
126
+ }
127
+
128
+ /**
129
+ * Creates an ObservableCounter instrument.
130
+ *
131
+ * @param {string} name - Instrument name (case-insensitive)
132
+ * @param {MetricOptions} [options] - Instrument options
133
+ * @returns {ObservableCounter} ObservableCounter instrument
134
+ */
135
+ createObservableCounter (name, options = {}) {
136
+ return this.#getOrCreateInstrument(name, METRIC_TYPES.OBSERVABLECOUNTER, ObservableCounter, options)
137
+ }
138
+
139
+ /**
140
+ * Creates an ObservableUpDownCounter instrument.
141
+ *
142
+ * @param {string} name - Instrument name (case-insensitive)
143
+ * @param {MetricOptions} [options] - Instrument options
144
+ * @returns {ObservableUpDownCounter} ObservableUpDownCounter instrument
145
+ */
146
+ createObservableUpDownCounter (name, options = {}) {
147
+ return this.#getOrCreateInstrument(name, METRIC_TYPES.OBSERVABLEUPDOWNCOUNTER, ObservableUpDownCounter, options)
148
+ }
149
+
150
+ /**
151
+ * Adds a batch observable callback (not implemented).
152
+ *
153
+ * @param {Function} callback - Batch observable callback
154
+ * @param {Array} observables - Array of observable instruments
155
+ */
156
+ addBatchObservableCallback (callback, observables) {
157
+ log.warn('addBatchObservableCallback is not implemented')
158
+ }
159
+
160
+ /**
161
+ * Removes a batch observable callback (not implemented).
162
+ *
163
+ * @param {Function} callback - Batch observable callback
164
+ * @param {Array} observables - Array of observable instruments
165
+ */
166
+ removeBatchObservableCallback (callback, observables) {
167
+ log.warn('removeBatchObservableCallback is not implemented')
168
+ }
169
+ }
170
+
171
+ module.exports = Meter
@@ -0,0 +1,54 @@
1
+ 'use strict'
2
+
3
+ const Meter = require('./meter')
4
+
5
+ /**
6
+ * @typedef {import('@opentelemetry/api').Meter} Meter
7
+ * @typedef {import('@opentelemetry/api').MeterOptions} MeterOptions
8
+ * @typedef {import('./periodic_metric_reader')} PeriodicMetricReader
9
+ */
10
+
11
+ /**
12
+ * MeterProvider is the main entry point for creating meters with a single reader for Datadog Agent export.
13
+ *
14
+ * This implementation follows the OpenTelemetry JavaScript API MeterProvider interface:
15
+ * https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.MeterProvider.html
16
+ *
17
+ * @class MeterProvider
18
+ * @implements {import('@opentelemetry/api').MeterProvider}
19
+ */
20
+ class MeterProvider {
21
+ #meters = new Map()
22
+
23
+ /**
24
+ * Creates a new MeterProvider instance with a single reader for Datadog Agent export.
25
+ *
26
+ * @param {MeterOptions} [options] - MeterProvider options
27
+ * @param {PeriodicMetricReader} [options.reader] - Single MetricReader instance for
28
+ * exporting metrics to Datadog Agent
29
+ */
30
+ constructor (options = {}) {
31
+ this.reader = options.reader
32
+ }
33
+
34
+ /**
35
+ * Gets or creates a meter instance.
36
+ *
37
+ * @param {string} name - Meter name (case-insensitive)
38
+ * @param {string} [version] - Meter version
39
+ * @param {MeterOptions} [options] - Additional options
40
+ * @returns {Meter} Meter instance
41
+ */
42
+ getMeter (name, version = '', { schemaUrl = '', attributes = {} } = {}) {
43
+ const normalizedName = name.toLowerCase()
44
+ const key = `${normalizedName}@${version}@${schemaUrl}`
45
+ let meter = this.#meters.get(key)
46
+ if (!meter) {
47
+ meter = new Meter(this, { name: normalizedName, version, schemaUrl, attributes })
48
+ this.#meters.set(key, meter)
49
+ }
50
+ return meter
51
+ }
52
+ }
53
+
54
+ module.exports = MeterProvider
@@ -0,0 +1,62 @@
1
+ 'use strict'
2
+
3
+ const OtlpHttpExporterBase = require('../otlp/otlp_http_exporter_base')
4
+ const OtlpTransformer = require('./otlp_transformer')
5
+
6
+ /**
7
+ * @typedef {import('@opentelemetry/resources').Resource} Resource
8
+ * @typedef {import('./periodic_metric_reader').AggregatedMetric} AggregatedMetric
9
+ */
10
+
11
+ /**
12
+ * OtlpHttpMetricExporter exports metrics via OTLP over HTTP.
13
+ *
14
+ * @class OtlpHttpMetricExporter
15
+ */
16
+ class OtlpHttpMetricExporter extends OtlpHttpExporterBase {
17
+ /**
18
+ * Creates a new OtlpHttpMetricExporter instance.
19
+ *
20
+ * @param {string} url - OTLP endpoint URL
21
+ * @param {string} headers - Additional HTTP headers as comma-separated key=value string
22
+ * @param {number} timeout - Request timeout in milliseconds
23
+ * @param {string} protocol - OTLP protocol (http/protobuf or http/json)
24
+ * @param {Resource} resource - Resource attributes
25
+ */
26
+ constructor (url, headers, timeout, protocol, resource) {
27
+ super(url, headers, timeout, protocol, '/v1/metrics', 'metrics')
28
+ this.transformer = new OtlpTransformer(resource, protocol)
29
+ }
30
+
31
+ /**
32
+ * Exports metrics via OTLP over HTTP.
33
+ *
34
+ * @param {Map<string, AggregatedMetric>} metrics - Map of metric data to export
35
+ *
36
+ * @returns {void}
37
+ */
38
+ export (metrics) {
39
+ if (metrics.size === 0) {
40
+ return
41
+ }
42
+
43
+ let dataPointCount = 0
44
+ for (const metric of metrics.values()) {
45
+ if (metric.dataPointMap) {
46
+ dataPointCount += metric.dataPointMap.size
47
+ }
48
+ }
49
+
50
+ const additionalTags = [`points:${dataPointCount}`]
51
+ this.recordTelemetry('otel.metrics_export_attempts', 1, additionalTags)
52
+
53
+ const payload = this.transformer.transformMetrics(metrics.values())
54
+ this.sendPayload(payload, (result) => {
55
+ if (result.code === 0) {
56
+ this.recordTelemetry('otel.metrics_export_successes', 1, additionalTags)
57
+ }
58
+ })
59
+ }
60
+ }
61
+
62
+ module.exports = OtlpHttpMetricExporter