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.
- package/LICENSE-3rdparty.csv +4 -3
- package/package.json +4 -4
- package/packages/datadog-instrumentations/src/aws-sdk.js +5 -0
- package/packages/datadog-instrumentations/src/cassandra-driver.js +6 -3
- package/packages/datadog-instrumentations/src/elasticsearch.js +39 -1
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/kafkajs.js +13 -4
- package/packages/datadog-instrumentations/src/opensearch.js +2 -1
- package/packages/datadog-instrumentations/src/redis.js +48 -5
- package/packages/datadog-plugin-aws-sdk/src/base.js +3 -3
- package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/s3.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sns.js +1 -0
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -0
- package/packages/datadog-plugin-cassandra-driver/src/index.js +4 -4
- package/packages/datadog-plugin-grpc/src/client.js +8 -2
- package/packages/datadog-plugin-grpc/src/server.js +2 -2
- package/packages/datadog-plugin-kafkajs/src/consumer.js +6 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +14 -2
- package/packages/datadog-plugin-mongodb-core/src/index.js +13 -2
- package/packages/datadog-plugin-openai/src/index.js +9 -2
- package/packages/datadog-plugin-openai/src/services.js +14 -10
- package/packages/datadog-plugin-oracledb/src/index.js +1 -0
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +6 -5
- package/packages/dd-trace/src/config.js +11 -0
- package/packages/dd-trace/src/data_streams_context.js +15 -0
- package/packages/dd-trace/src/datastreams/pathway.js +58 -0
- package/packages/dd-trace/src/datastreams/processor.js +194 -0
- package/packages/dd-trace/src/datastreams/writer.js +66 -0
- package/packages/dd-trace/src/dogstatsd.js +14 -1
- package/packages/dd-trace/src/metrics.js +2 -2
- package/packages/dd-trace/src/plugin_manager.js +6 -1
- package/packages/dd-trace/src/plugins/database.js +2 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/outbound.js +2 -1
- package/packages/dd-trace/src/plugins/tracing.js +3 -0
- package/packages/dd-trace/src/plugins/util/git.js +37 -5
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +36 -2
- package/packages/dd-trace/src/profiling/config.js +32 -5
- package/packages/dd-trace/src/service-naming/index.js +13 -1
- package/packages/dd-trace/src/service-naming/schemas/v0/web.js +9 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/web.js +8 -0
- package/packages/dd-trace/src/telemetry/metrics.js +76 -20
- 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 =
|
|
110
|
-
|
|
111
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
153
|
-
|
|
183
|
+
function getMetric (collection, type, name, tags, interval) {
|
|
184
|
+
const metricId = getId(type, collection, name, tags)
|
|
154
185
|
|
|
155
|
-
|
|
156
|
-
|
|
186
|
+
let metric = collection.get(metricId)
|
|
187
|
+
if (metric) return metric
|
|
157
188
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
-
|
|
164
|
-
|
|
197
|
+
return metric
|
|
198
|
+
}
|
|
165
199
|
|
|
166
|
-
|
|
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.
|
|
212
|
+
return getMetric(this.metrics, 'count', name, tags)
|
|
171
213
|
}
|
|
172
214
|
|
|
173
215
|
gauge (name, tags) {
|
|
174
|
-
return this.
|
|
216
|
+
return getMetric(this.metrics, 'gauge', name, tags)
|
|
175
217
|
}
|
|
176
218
|
|
|
177
219
|
rate (name, interval, tags) {
|
|
178
|
-
return this.
|
|
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 {
|
|
228
|
+
const { distributions, metrics } = this
|
|
183
229
|
return {
|
|
184
|
-
|
|
185
|
-
|
|
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
|
-
|
|
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()
|