dd-trace 2.38.0 → 2.40.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 (45) hide show
  1. package/LICENSE-3rdparty.csv +4 -3
  2. package/package.json +4 -4
  3. package/packages/datadog-instrumentations/src/aws-sdk.js +5 -0
  4. package/packages/datadog-instrumentations/src/cassandra-driver.js +6 -3
  5. package/packages/datadog-instrumentations/src/elasticsearch.js +39 -1
  6. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  7. package/packages/datadog-instrumentations/src/kafkajs.js +13 -4
  8. package/packages/datadog-instrumentations/src/opensearch.js +2 -1
  9. package/packages/datadog-instrumentations/src/redis.js +48 -5
  10. package/packages/datadog-plugin-aws-sdk/src/base.js +3 -3
  11. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +1 -0
  12. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -0
  13. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -0
  14. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -0
  15. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -0
  16. package/packages/datadog-plugin-cassandra-driver/src/index.js +4 -4
  17. package/packages/datadog-plugin-grpc/src/client.js +8 -2
  18. package/packages/datadog-plugin-grpc/src/server.js +2 -2
  19. package/packages/datadog-plugin-kafkajs/src/consumer.js +6 -1
  20. package/packages/datadog-plugin-kafkajs/src/producer.js +14 -2
  21. package/packages/datadog-plugin-mongodb-core/src/index.js +13 -2
  22. package/packages/datadog-plugin-openai/src/index.js +9 -2
  23. package/packages/datadog-plugin-openai/src/services.js +14 -10
  24. package/packages/datadog-plugin-oracledb/src/index.js +1 -0
  25. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -5
  26. package/packages/dd-trace/src/config.js +11 -0
  27. package/packages/dd-trace/src/data_streams_context.js +15 -0
  28. package/packages/dd-trace/src/datastreams/pathway.js +58 -0
  29. package/packages/dd-trace/src/datastreams/processor.js +194 -0
  30. package/packages/dd-trace/src/datastreams/writer.js +66 -0
  31. package/packages/dd-trace/src/dogstatsd.js +14 -1
  32. package/packages/dd-trace/src/metrics.js +2 -2
  33. package/packages/dd-trace/src/plugin_manager.js +6 -1
  34. package/packages/dd-trace/src/plugins/database.js +2 -1
  35. package/packages/dd-trace/src/plugins/index.js +1 -0
  36. package/packages/dd-trace/src/plugins/outbound.js +2 -1
  37. package/packages/dd-trace/src/plugins/tracing.js +3 -0
  38. package/packages/dd-trace/src/plugins/util/git.js +37 -5
  39. package/packages/dd-trace/src/plugins/util/user-provided-git.js +36 -2
  40. package/packages/dd-trace/src/profiling/config.js +32 -5
  41. package/packages/dd-trace/src/service-naming/index.js +13 -1
  42. package/packages/dd-trace/src/service-naming/schemas/v0/web.js +9 -0
  43. package/packages/dd-trace/src/service-naming/schemas/v1/web.js +8 -0
  44. package/packages/dd-trace/src/telemetry/metrics.js +76 -20
  45. package/packages/dd-trace/src/tracer.js +19 -1
@@ -12,7 +12,7 @@ const WallProfiler = require('./profilers/wall')
12
12
  const SpaceProfiler = require('./profilers/space')
13
13
  const { oomExportStrategies, snapshotKinds } = require('./constants')
14
14
  const { tagger } = require('./tagger')
15
- const { isTrue } = require('../util')
15
+ const { isFalse, isTrue } = require('../util')
16
16
 
17
17
  class Config {
18
18
  constructor (options = {}) {
@@ -32,6 +32,8 @@ class Config {
32
32
  DD_PROFILING_SOURCE_MAP,
33
33
  DD_PROFILING_UPLOAD_PERIOD,
34
34
  DD_PROFILING_PPROF_PREFIX,
35
+ DD_PROFILING_HEAP_ENABLED,
36
+ DD_PROFILING_WALLTIME_ENABLED,
35
37
  DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED,
36
38
  DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE,
37
39
  DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT,
@@ -106,10 +108,9 @@ class Config {
106
108
  exportCommand
107
109
  }
108
110
 
109
- const profilers = coalesce(options.profilers, DD_PROFILING_PROFILERS, [
110
- new WallProfiler(this),
111
- new SpaceProfiler(this)
112
- ])
111
+ const profilers = options.profilers
112
+ ? options.profilers
113
+ : getProfilers({ DD_PROFILING_HEAP_ENABLED, DD_PROFILING_WALLTIME_ENABLED, DD_PROFILING_PROFILERS })
113
114
 
114
115
  this.profilers = ensureProfilers(profilers, this)
115
116
  }
@@ -117,6 +118,32 @@ class Config {
117
118
 
118
119
  module.exports = { Config }
119
120
 
121
+ function getProfilers ({ DD_PROFILING_HEAP_ENABLED, DD_PROFILING_WALLTIME_ENABLED, DD_PROFILING_PROFILERS }) {
122
+ // First consider "legacy" DD_PROFILING_PROFILERS env variable, defaulting to wall + space
123
+ // Use a Set to avoid duplicates
124
+ const profilers = new Set(coalesce(DD_PROFILING_PROFILERS, 'wall,space').split(','))
125
+
126
+ // Add/remove wall depending on the value of DD_PROFILING_WALLTIME_ENABLED
127
+ if (DD_PROFILING_WALLTIME_ENABLED != null) {
128
+ if (isTrue(DD_PROFILING_WALLTIME_ENABLED)) {
129
+ profilers.add('wall')
130
+ } else if (isFalse(DD_PROFILING_WALLTIME_ENABLED)) {
131
+ profilers.delete('wall')
132
+ }
133
+ }
134
+
135
+ // Add/remove wall depending on the value of DD_PROFILING_HEAP_ENABLED
136
+ if (DD_PROFILING_HEAP_ENABLED != null) {
137
+ if (isTrue(DD_PROFILING_HEAP_ENABLED)) {
138
+ profilers.add('space')
139
+ } else if (isFalse(DD_PROFILING_HEAP_ENABLED)) {
140
+ profilers.delete('space')
141
+ }
142
+ }
143
+
144
+ return [...profilers]
145
+ }
146
+
120
147
  function getExportStrategy (name, options) {
121
148
  const strategy = Object.values(oomExportStrategies).find(value => value === name)
122
149
  if (strategy === undefined) {
@@ -3,7 +3,7 @@ const { schemaDefinitions } = require('./schemas')
3
3
  class SchemaManager {
4
4
  constructor () {
5
5
  this.schemas = schemaDefinitions
6
- this.config = { spanAttributeSchema: 'v0' }
6
+ this.config = { spanAttributeSchema: 'v0', traceRemoveIntegrationServiceNamesEnabled: false }
7
7
  }
8
8
 
9
9
  get schema () {
@@ -14,6 +14,10 @@ class SchemaManager {
14
14
  return this.config.spanAttributeSchema
15
15
  }
16
16
 
17
+ get shouldUseConsistentServiceNaming () {
18
+ return this.config.traceRemoveIntegrationServiceNamesEnabled && this.version === 'v0'
19
+ }
20
+
17
21
  opName (type, kind, plugin, ...opNameArgs) {
18
22
  return this.schema.getOpName(type, kind, plugin, ...opNameArgs)
19
23
  }
@@ -22,6 +26,14 @@ class SchemaManager {
22
26
  return this.schema.getServiceName(type, kind, plugin, this.config.service, ...serviceNameArgs)
23
27
  }
24
28
 
29
+ shortCircuitServiceName (pluginConfig, ...args) {
30
+ // We're short-circuiting, so we do not obey custom service functions
31
+ if (typeof pluginConfig.service === 'function') {
32
+ return this.config.service
33
+ }
34
+ return pluginConfig.service || this.config.service
35
+ }
36
+
25
37
  configure (config = {}) {
26
38
  this.config = config
27
39
  }
@@ -1,13 +1,22 @@
1
1
  const { identityService } = require('../util')
2
+ const { DD_MAJOR } = require('../../../../../../version')
2
3
 
3
4
  const web = {
4
5
  client: {
6
+ grpc: {
7
+ opName: () => DD_MAJOR <= 2 ? 'grpc.request' : 'grpc.client',
8
+ serviceName: identityService
9
+ },
5
10
  moleculer: {
6
11
  opName: () => 'moleculer.call',
7
12
  serviceName: identityService
8
13
  }
9
14
  },
10
15
  server: {
16
+ grpc: {
17
+ opName: () => DD_MAJOR <= 2 ? 'grpc.request' : 'grpc.server',
18
+ serviceName: identityService
19
+ },
11
20
  moleculer: {
12
21
  opName: () => 'moleculer.action',
13
22
  serviceName: identityService
@@ -2,12 +2,20 @@ const { identityService } = require('../util')
2
2
 
3
3
  const web = {
4
4
  client: {
5
+ grpc: {
6
+ opName: () => 'grpc.client.request',
7
+ serviceName: identityService
8
+ },
5
9
  moleculer: {
6
10
  opName: () => 'moleculer.client.request',
7
11
  serviceName: identityService
8
12
  }
9
13
  },
10
14
  server: {
15
+ grpc: {
16
+ opName: () => 'grpc.server.request',
17
+ serviceName: identityService
18
+ },
11
19
  moleculer: {
12
20
  opName: () => 'moleculer.server.request',
13
21
  serviceName: identityService
@@ -89,6 +89,26 @@ class CountMetric extends Metric {
89
89
  }
90
90
  }
91
91
 
92
+ class DistributionMetric extends Metric {
93
+ get type () {
94
+ return 'distribution'
95
+ }
96
+
97
+ track (value = 1) {
98
+ this.points.push(value)
99
+ }
100
+
101
+ toJSON () {
102
+ const { metric, points, tags, common } = this
103
+ return {
104
+ metric,
105
+ points,
106
+ common,
107
+ tags
108
+ }
109
+ }
110
+ }
111
+
92
112
  class GaugeMetric extends Metric {
93
113
  get type () {
94
114
  return 'gauge'
@@ -129,11 +149,12 @@ class RateMetric extends Metric {
129
149
 
130
150
  const metricsTypes = {
131
151
  count: CountMetric,
152
+ distribution: DistributionMetric,
132
153
  gauge: GaugeMetric,
133
154
  rate: RateMetric
134
155
  }
135
156
 
136
- class Namespace extends Map {
157
+ class MetricsCollection extends Map {
137
158
  constructor (namespace) {
138
159
  super()
139
160
  this.namespace = namespace
@@ -146,43 +167,68 @@ class Namespace extends Map {
146
167
  }
147
168
 
148
169
  toString () {
149
- return `dd.instrumentation_telemetry_data.${this.namespace}`
170
+ return this.namespace
171
+ }
172
+
173
+ toJSON () {
174
+ if (!this.size) return
175
+ const { namespace } = this
176
+ return {
177
+ namespace,
178
+ series: mapToJsonArray(this)
179
+ }
150
180
  }
181
+ }
151
182
 
152
- getMetric (type, name, tags, interval) {
153
- const metricId = getId(type, this, name, tags)
183
+ function getMetric (collection, type, name, tags, interval) {
184
+ const metricId = getId(type, collection, name, tags)
154
185
 
155
- let metric = this.get(metricId)
156
- if (metric) return metric
186
+ let metric = collection.get(metricId)
187
+ if (metric) return metric
157
188
 
158
- const Factory = metricsTypes[type]
159
- if (!Factory) {
160
- throw new Error(`Unknown metric type ${type}`)
161
- }
189
+ const Factory = metricsTypes[type]
190
+ if (!Factory) {
191
+ throw new Error(`Unknown metric type ${type}`)
192
+ }
193
+
194
+ metric = new Factory(collection, name, true, tags, interval)
195
+ collection.set(metricId, metric)
162
196
 
163
- metric = new Factory(this, name, true, tags, interval)
164
- this.set(metricId, metric)
197
+ return metric
198
+ }
165
199
 
166
- return metric
200
+ class Namespace {
201
+ constructor (namespace) {
202
+ this.distributions = new MetricsCollection(namespace)
203
+ this.metrics = new MetricsCollection(namespace)
204
+ }
205
+
206
+ reset () {
207
+ this.metrics.reset()
208
+ this.distributions.reset()
167
209
  }
168
210
 
169
211
  count (name, tags) {
170
- return this.getMetric('count', name, tags)
212
+ return getMetric(this.metrics, 'count', name, tags)
171
213
  }
172
214
 
173
215
  gauge (name, tags) {
174
- return this.getMetric('gauge', name, tags)
216
+ return getMetric(this.metrics, 'gauge', name, tags)
175
217
  }
176
218
 
177
219
  rate (name, interval, tags) {
178
- return this.getMetric('rate', name, tags, interval)
220
+ return getMetric(this.metrics, 'rate', name, tags, interval)
221
+ }
222
+
223
+ distribution (name, tags) {
224
+ return getMetric(this.distributions, 'distribution', name, tags)
179
225
  }
180
226
 
181
227
  toJSON () {
182
- const { namespace } = this
228
+ const { distributions, metrics } = this
183
229
  return {
184
- namespace,
185
- series: mapToJsonArray(this)
230
+ distributions: distributions.toJSON(),
231
+ metrics: metrics.toJSON()
186
232
  }
187
233
  }
188
234
  }
@@ -203,7 +249,15 @@ class NamespaceManager extends Map {
203
249
 
204
250
  send (config, application, host) {
205
251
  for (const namespace of this.values()) {
206
- sendData(config, application, host, 'generate-metrics', namespace.toJSON())
252
+ const { metrics, distributions } = namespace.toJSON()
253
+
254
+ if (metrics) {
255
+ sendData(config, application, host, 'generate-metrics', metrics)
256
+ }
257
+
258
+ if (distributions) {
259
+ sendData(config, application, host, 'distributions', distributions)
260
+ }
207
261
 
208
262
  // TODO: This could also be clear() but then it'd have to rebuild all
209
263
  // metric instances on every send. This may be desirable if we want tags
@@ -217,8 +271,10 @@ const manager = new NamespaceManager()
217
271
 
218
272
  module.exports = {
219
273
  CountMetric,
274
+ DistributionMetric,
220
275
  GaugeMetric,
221
276
  RateMetric,
277
+ MetricsCollection,
222
278
  Namespace,
223
279
  NamespaceManager,
224
280
  manager
@@ -7,7 +7,10 @@ const { storage } = require('../../datadog-core')
7
7
  const { isError } = require('./util')
8
8
  const { setStartupLogConfig } = require('./startup-log')
9
9
  const { ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../../dd-trace/src/constants')
10
+ const { DataStreamsProcessor } = require('./datastreams/processor')
11
+ const { decodePathwayContext } = require('./datastreams/pathway')
10
12
  const { DD_MAJOR } = require('../../../version')
13
+ const DataStreamsContext = require('./data_streams_context')
11
14
 
12
15
  const SPAN_TYPE = tags.SPAN_TYPE
13
16
  const RESOURCE_NAME = tags.RESOURCE_NAME
@@ -17,11 +20,26 @@ const MEASURED = tags.MEASURED
17
20
  class DatadogTracer extends Tracer {
18
21
  constructor (config) {
19
22
  super(config)
20
-
23
+ this._dataStreamsProcessor = new DataStreamsProcessor(config)
21
24
  this._scope = new Scope()
22
25
  setStartupLogConfig(config)
23
26
  }
24
27
 
28
+ // todo[piochelepiotr] These two methods are not related to the tracer, but to data streams monitoring.
29
+ // They should be moved outside of the tracer in the future.
30
+ setCheckpoint (edgeTags) {
31
+ const ctx = this._dataStreamsProcessor.setCheckpoint(edgeTags, DataStreamsContext.getDataStreamsContext())
32
+ DataStreamsContext.setDataStreamsContext(ctx)
33
+ return ctx
34
+ }
35
+
36
+ decodeDataStreamsContext (data) {
37
+ const ctx = decodePathwayContext(data)
38
+ // we erase the previous context everytime we decode a new one
39
+ DataStreamsContext.setDataStreamsContext(ctx)
40
+ return ctx
41
+ }
42
+
25
43
  trace (name, options, fn) {
26
44
  options = Object.assign({
27
45
  childOf: this.scope().active()