dd-trace 2.41.0 → 2.42.1
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/README.md +2 -2
- package/package.json +3 -3
- package/packages/datadog-core/src/storage/async_resource.js +4 -0
- package/packages/datadog-instrumentations/src/aws-sdk.js +6 -2
- package/packages/datadog-instrumentations/src/fetch.js +24 -21
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/http/client.js +41 -32
- package/packages/datadog-instrumentations/src/http2/client.js +1 -0
- package/packages/datadog-instrumentations/src/jest.js +32 -4
- package/packages/datadog-plugin-fetch/src/index.js +7 -13
- package/packages/datadog-plugin-graphql/src/execute.js +6 -4
- package/packages/datadog-plugin-http/src/client.js +25 -20
- package/packages/datadog-plugin-jest/src/index.js +8 -3
- package/packages/datadog-plugin-openai/src/index.js +39 -16
- package/packages/datadog-plugin-openai/src/services.js +13 -9
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +3 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +45 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/index.js +3 -3
- package/packages/dd-trace/src/appsec/iast/analyzers/missing-header-analyzer.js +66 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +25 -8
- package/packages/dd-trace/src/appsec/iast/analyzers/xcontenttype-header-missing-analyzer.js +19 -0
- package/packages/dd-trace/src/appsec/iast/index.js +5 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +4 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +17 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/source-types.js +1 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +5 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +3 -1
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +1 -1
- package/packages/dd-trace/src/config.js +26 -10
- package/packages/dd-trace/src/external-logger/src/index.js +9 -1
- package/packages/dd-trace/src/external-logger/test/index.spec.js +1 -1
- package/packages/dd-trace/src/format.js +1 -1
- package/packages/dd-trace/src/lambda/handler.js +8 -1
- package/packages/dd-trace/src/opentelemetry/span.js +3 -1
- package/packages/dd-trace/src/opentracing/span_context.js +2 -1
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +2 -1
- package/packages/dd-trace/src/plugins/util/web.js +1 -0
- package/packages/dd-trace/src/profiling/config.js +8 -5
- package/packages/dd-trace/src/profiling/exporters/agent.js +4 -1
- package/packages/dd-trace/src/profiling/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/wall.js +144 -4
- package/packages/dd-trace/src/service-naming/index.js +2 -2
- package/packages/dd-trace/src/service-naming/schemas/v0/graphql.js +12 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/index.js +2 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/graphql.js +12 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/index.js +2 -1
- package/packages/dd-trace/src/span_processor.js +0 -4
- package/packages/dd-trace/src/span_sampler.js +1 -1
- package/packages/dd-trace/src/telemetry/dependencies.js +24 -12
- package/packages/dd-trace/src/telemetry/metrics.js +11 -1
- package/packages/diagnostics_channel/src/index.js +1 -1
- package/scripts/version.js +0 -66
|
@@ -86,6 +86,13 @@ exports.datadog = function datadog (lambdaHandler) {
|
|
|
86
86
|
const context = extractContext(args)
|
|
87
87
|
|
|
88
88
|
checkTimeout(context)
|
|
89
|
-
|
|
89
|
+
const result = lambdaHandler.apply(this, args)
|
|
90
|
+
if (result && typeof result.then === 'function') {
|
|
91
|
+
return result.then((res) => {
|
|
92
|
+
clearTimeout(__lambdaTimeout)
|
|
93
|
+
return res
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
return result
|
|
90
97
|
}
|
|
91
98
|
}
|
|
@@ -10,6 +10,7 @@ const { timeInputToHrTime } = require('@opentelemetry/core')
|
|
|
10
10
|
const tracer = require('../../')
|
|
11
11
|
const DatadogSpan = require('../opentracing/span')
|
|
12
12
|
const { ERROR_MESSAGE, ERROR_TYPE, ERROR_STACK } = require('../constants')
|
|
13
|
+
const { SERVICE_NAME, RESOURCE_NAME } = require('../../../../ext/tags')
|
|
13
14
|
|
|
14
15
|
const SpanContext = require('./span_context')
|
|
15
16
|
|
|
@@ -40,7 +41,8 @@ class Span {
|
|
|
40
41
|
hostname: _tracer._hostname,
|
|
41
42
|
integrationName: 'otel',
|
|
42
43
|
tags: {
|
|
43
|
-
|
|
44
|
+
[SERVICE_NAME]: _tracer._service,
|
|
45
|
+
[RESOURCE_NAME]: spanName
|
|
44
46
|
}
|
|
45
47
|
}, _tracer._debug)
|
|
46
48
|
|
|
@@ -12,7 +12,8 @@ class DatadogSpanContext {
|
|
|
12
12
|
this._name = props.name
|
|
13
13
|
this._isFinished = props.isFinished || false
|
|
14
14
|
this._tags = props.tags || {}
|
|
15
|
-
this._sampling =
|
|
15
|
+
this._sampling = props.sampling || {}
|
|
16
|
+
this._spanSampling = undefined
|
|
16
17
|
this._baggageItems = props.baggageItems || {}
|
|
17
18
|
this._traceparent = props.traceparent
|
|
18
19
|
this._tracestate = props.tracestate
|
|
@@ -10,6 +10,7 @@ module.exports = {
|
|
|
10
10
|
get '@grpc/grpc-js' () { return require('../../../datadog-plugin-grpc/src') },
|
|
11
11
|
get '@hapi/hapi' () { return require('../../../datadog-plugin-hapi/src') },
|
|
12
12
|
get '@jest/core' () { return require('../../../datadog-plugin-jest/src') },
|
|
13
|
+
get '@jest/transform' () { return require('../../../datadog-plugin-jest/src') },
|
|
13
14
|
get '@koa/router' () { return require('../../../datadog-plugin-koa/src') },
|
|
14
15
|
get '@node-redis/client' () { return require('../../../datadog-plugin-redis/src') },
|
|
15
16
|
get '@opensearch-project/opensearch' () { return require('../../../datadog-plugin-opensearch/src') },
|
|
@@ -399,6 +399,7 @@ module.exports = {
|
|
|
399
399
|
BITBUCKET_BRANCH,
|
|
400
400
|
BITBUCKET_COMMIT,
|
|
401
401
|
BITBUCKET_GIT_SSH_ORIGIN,
|
|
402
|
+
BITBUCKET_GIT_HTTP_ORIGIN,
|
|
402
403
|
BITBUCKET_TAG,
|
|
403
404
|
BITBUCKET_PIPELINE_UUID,
|
|
404
405
|
BITBUCKET_CLONE_DIR
|
|
@@ -416,7 +417,7 @@ module.exports = {
|
|
|
416
417
|
[CI_PIPELINE_URL]: url,
|
|
417
418
|
[GIT_BRANCH]: BITBUCKET_BRANCH,
|
|
418
419
|
[GIT_TAG]: BITBUCKET_TAG,
|
|
419
|
-
[GIT_REPOSITORY_URL]: BITBUCKET_GIT_SSH_ORIGIN,
|
|
420
|
+
[GIT_REPOSITORY_URL]: BITBUCKET_GIT_SSH_ORIGIN || BITBUCKET_GIT_HTTP_ORIGIN,
|
|
420
421
|
[CI_WORKSPACE_PATH]: BITBUCKET_CLONE_DIR,
|
|
421
422
|
[CI_PIPELINE_ID]: BITBUCKET_PIPELINE_UUID && BITBUCKET_PIPELINE_UUID.replace(/{|}/gm, '')
|
|
422
423
|
}
|
|
@@ -18,7 +18,6 @@ class Config {
|
|
|
18
18
|
const {
|
|
19
19
|
DD_PROFILING_ENABLED,
|
|
20
20
|
DD_PROFILING_PROFILERS,
|
|
21
|
-
DD_PROFILING_ENDPOINT_COLLECTION_ENABLED,
|
|
22
21
|
DD_ENV,
|
|
23
22
|
DD_TAGS,
|
|
24
23
|
DD_SERVICE,
|
|
@@ -36,7 +35,9 @@ class Config {
|
|
|
36
35
|
DD_PROFILING_EXPERIMENTAL_OOM_MONITORING_ENABLED,
|
|
37
36
|
DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE,
|
|
38
37
|
DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT,
|
|
39
|
-
DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES
|
|
38
|
+
DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES,
|
|
39
|
+
DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED,
|
|
40
|
+
DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED
|
|
40
41
|
} = process.env
|
|
41
42
|
|
|
42
43
|
const enabled = isTrue(coalesce(options.enabled, DD_PROFILING_ENABLED, true))
|
|
@@ -51,8 +52,8 @@ class Config {
|
|
|
51
52
|
Number(DD_PROFILING_UPLOAD_TIMEOUT), 60 * 1000)
|
|
52
53
|
const sourceMap = coalesce(options.sourceMap,
|
|
53
54
|
DD_PROFILING_SOURCE_MAP, true)
|
|
54
|
-
const
|
|
55
|
-
|
|
55
|
+
const endpointCollectionEnabled = coalesce(options.endpointCollection,
|
|
56
|
+
DD_PROFILING_EXPERIMENTAL_ENDPOINT_COLLECTION_ENABLED, false)
|
|
56
57
|
const pprofPrefix = coalesce(options.pprofPrefix,
|
|
57
58
|
DD_PROFILING_PPROF_PREFIX, '')
|
|
58
59
|
|
|
@@ -73,7 +74,7 @@ class Config {
|
|
|
73
74
|
this.uploadTimeout = uploadTimeout
|
|
74
75
|
this.sourceMap = sourceMap
|
|
75
76
|
this.debugSourceMaps = isTrue(coalesce(options.debugSourceMaps, DD_PROFILING_DEBUG_SOURCE_MAPS, false))
|
|
76
|
-
this.
|
|
77
|
+
this.endpointCollectionEnabled = endpointCollectionEnabled
|
|
77
78
|
this.pprofPrefix = pprofPrefix
|
|
78
79
|
|
|
79
80
|
const hostname = coalesce(options.hostname, DD_AGENT_HOST) || 'localhost'
|
|
@@ -110,6 +111,8 @@ class Config {
|
|
|
110
111
|
const profilers = options.profilers
|
|
111
112
|
? options.profilers
|
|
112
113
|
: getProfilers({ DD_PROFILING_HEAP_ENABLED, DD_PROFILING_WALLTIME_ENABLED, DD_PROFILING_PROFILERS })
|
|
114
|
+
this.codeHotspotsEnabled = isTrue(coalesce(options.codeHotspotsEnabled,
|
|
115
|
+
DD_PROFILING_EXPERIMENTAL_CODEHOTSPOTS_ENABLED, false))
|
|
113
116
|
|
|
114
117
|
this.profilers = ensureProfilers(profilers, this)
|
|
115
118
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const retry = require('retry')
|
|
4
|
-
const { request } = require('http')
|
|
4
|
+
const { request: httpRequest } = require('http')
|
|
5
|
+
const { request: httpsRequest } = require('https')
|
|
5
6
|
|
|
6
7
|
// TODO: avoid using dd-trace internals. Make this a separate module?
|
|
7
8
|
const docker = require('../../exporters/common/docker')
|
|
@@ -12,6 +13,8 @@ const version = require('../../../../../package.json').version
|
|
|
12
13
|
const containerId = docker.id()
|
|
13
14
|
|
|
14
15
|
function sendRequest (options, form, callback) {
|
|
16
|
+
const request = options.protocol === 'https:' ? httpsRequest : httpRequest
|
|
17
|
+
|
|
15
18
|
const store = storage.getStore()
|
|
16
19
|
storage.enterWith({ noop: true })
|
|
17
20
|
const req = request(options, res => {
|
|
@@ -1,23 +1,111 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { storage } = require('../../../../datadog-core')
|
|
4
|
+
|
|
5
|
+
const dc = require('../../../../diagnostics_channel')
|
|
6
|
+
|
|
7
|
+
const beforeCh = dc.channel('dd-trace:storage:before')
|
|
8
|
+
const enterCh = dc.channel('dd-trace:storage:enter')
|
|
9
|
+
|
|
10
|
+
let kSampleCount
|
|
11
|
+
|
|
12
|
+
function getActiveSpan () {
|
|
13
|
+
const store = storage.getStore()
|
|
14
|
+
return store && store.span
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getStartedSpans (context) {
|
|
18
|
+
return context._trace.started
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function generateLabels ({ spanId, rootSpanId, webTags, endpoint }) {
|
|
22
|
+
const labels = {}
|
|
23
|
+
if (spanId) {
|
|
24
|
+
labels['span id'] = spanId
|
|
25
|
+
}
|
|
26
|
+
if (rootSpanId) {
|
|
27
|
+
labels['local root span id'] = rootSpanId
|
|
28
|
+
}
|
|
29
|
+
if (webTags && Object.keys(webTags).length !== 0) {
|
|
30
|
+
labels['trace endpoint'] = endpointNameFromTags(webTags)
|
|
31
|
+
} else if (endpoint) {
|
|
32
|
+
// fallback to endpoint computed when sample was taken
|
|
33
|
+
labels['trace endpoint'] = endpoint
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return labels
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getSpanContextTags (span) {
|
|
40
|
+
return span.context()._tags
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function isWebServerSpan (tags) {
|
|
44
|
+
return tags['span.type'] === 'web'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function endpointNameFromTags (tags) {
|
|
48
|
+
return tags['resource.name'] || [
|
|
49
|
+
tags['http.method'],
|
|
50
|
+
tags['http.route']
|
|
51
|
+
].filter(v => v).join(' ')
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function updateContext (context, span, startedSpans, endpointCollectionEnabled) {
|
|
55
|
+
context.spanId = span.context().toSpanId()
|
|
56
|
+
const rootSpan = startedSpans[0]
|
|
57
|
+
if (rootSpan) {
|
|
58
|
+
context.rootSpanId = rootSpan.context().toSpanId()
|
|
59
|
+
if (endpointCollectionEnabled) {
|
|
60
|
+
// Find the first webspan starting from the end:
|
|
61
|
+
// There might be several webspans, for example with next.js, http plugin creates a first span
|
|
62
|
+
// and then next.js plugin creates a child span, and this child span haves the correct endpoint information.
|
|
63
|
+
for (let i = startedSpans.length - 1; i >= 0; i--) {
|
|
64
|
+
const tags = getSpanContextTags(startedSpans[i])
|
|
65
|
+
if (isWebServerSpan(tags)) {
|
|
66
|
+
context.webTags = tags
|
|
67
|
+
// endpoint may not be determined yet, but keep it as fallback
|
|
68
|
+
// if tags are not available anymore during serialization
|
|
69
|
+
context.endpoint = endpointNameFromTags(tags)
|
|
70
|
+
break
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
3
77
|
class NativeWallProfiler {
|
|
4
78
|
constructor (options = {}) {
|
|
5
79
|
this.type = 'wall'
|
|
6
80
|
this._samplingIntervalMicros = options.samplingInterval || 1e6 / 99 // 99hz
|
|
7
81
|
this._flushIntervalMillis = options.flushInterval || 60 * 1e3 // 60 seconds
|
|
8
82
|
this._codeHotspotsEnabled = !!options.codeHotspotsEnabled
|
|
83
|
+
this._endpointCollectionEnabled = !!options.endpointCollectionEnabled
|
|
9
84
|
this._mapper = undefined
|
|
10
85
|
this._pprof = undefined
|
|
11
86
|
|
|
87
|
+
// Bind to this so the same value can be used to unsubscribe later
|
|
88
|
+
this._enter = this._enter.bind(this)
|
|
12
89
|
this._logger = options.logger
|
|
13
90
|
this._started = false
|
|
14
91
|
}
|
|
15
92
|
|
|
93
|
+
codeHotspotsEnabled () {
|
|
94
|
+
return this._codeHotspotsEnabled
|
|
95
|
+
}
|
|
96
|
+
|
|
16
97
|
start ({ mapper } = {}) {
|
|
17
98
|
if (this._started) return
|
|
18
99
|
|
|
100
|
+
if (this._codeHotspotsEnabled && !this._emittedFFMessage && this._logger) {
|
|
101
|
+
this._logger.debug(
|
|
102
|
+
`Wall profiler: Enable config_trace_show_breakdown_profiling_for_node feature flag to see code hotspots.`)
|
|
103
|
+
this._emittedFFMessage = true
|
|
104
|
+
}
|
|
105
|
+
|
|
19
106
|
this._mapper = mapper
|
|
20
107
|
this._pprof = require('@datadog/pprof')
|
|
108
|
+
kSampleCount = this._pprof.time.constants.kSampleCount
|
|
21
109
|
|
|
22
110
|
// pprof otherwise crashes in worker threads
|
|
23
111
|
if (!process._startProfilerIdleNotifier) {
|
|
@@ -31,16 +119,62 @@ class NativeWallProfiler {
|
|
|
31
119
|
intervalMicros: this._samplingIntervalMicros,
|
|
32
120
|
durationMillis: this._flushIntervalMillis,
|
|
33
121
|
sourceMapper: this._mapper,
|
|
34
|
-
|
|
122
|
+
withContexts: this._codeHotspotsEnabled,
|
|
35
123
|
lineNumbers: false
|
|
36
124
|
})
|
|
37
125
|
|
|
126
|
+
if (this._codeHotspotsEnabled) {
|
|
127
|
+
this._profilerState = this._pprof.time.getState()
|
|
128
|
+
this._currentContext = {}
|
|
129
|
+
this._pprof.time.setContext(this._currentContext)
|
|
130
|
+
this._lastSpan = undefined
|
|
131
|
+
this._lastStartedSpans = undefined
|
|
132
|
+
this._lastSampleCount = 0
|
|
133
|
+
|
|
134
|
+
beforeCh.subscribe(this._enter)
|
|
135
|
+
enterCh.subscribe(this._enter)
|
|
136
|
+
}
|
|
137
|
+
|
|
38
138
|
this._started = true
|
|
39
139
|
}
|
|
40
140
|
|
|
41
|
-
|
|
141
|
+
_enter () {
|
|
42
142
|
if (!this._started) return
|
|
43
|
-
|
|
143
|
+
|
|
144
|
+
const sampleCount = this._profilerState[kSampleCount]
|
|
145
|
+
if (sampleCount !== this._lastSampleCount) {
|
|
146
|
+
this._lastSampleCount = sampleCount
|
|
147
|
+
const context = this._currentContext
|
|
148
|
+
this._currentContext = {}
|
|
149
|
+
this._pprof.time.setContext(this._currentContext)
|
|
150
|
+
|
|
151
|
+
if (this._lastSpan) {
|
|
152
|
+
updateContext(context, this._lastSpan, this._lastStartedSpans, this._endpointCollectionEnabled)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const span = getActiveSpan()
|
|
157
|
+
if (span) {
|
|
158
|
+
this._lastSpan = span
|
|
159
|
+
this._lastStartedSpans = getStartedSpans(span.context())
|
|
160
|
+
} else {
|
|
161
|
+
this._lastStartedSpans = undefined
|
|
162
|
+
this._lastSpan = undefined
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
_stop (restart) {
|
|
167
|
+
if (!this._started) return
|
|
168
|
+
if (this._codeHotspotsEnabled) {
|
|
169
|
+
// update last sample context if needed
|
|
170
|
+
this._enter()
|
|
171
|
+
this._lastSampleCount = 0
|
|
172
|
+
}
|
|
173
|
+
return this._pprof.time.stop(restart, this._codeHotspotsEnabled ? generateLabels : undefined)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
profile () {
|
|
177
|
+
return this._stop(true)
|
|
44
178
|
}
|
|
45
179
|
|
|
46
180
|
encode (profile) {
|
|
@@ -50,7 +184,13 @@ class NativeWallProfiler {
|
|
|
50
184
|
stop () {
|
|
51
185
|
if (!this._started) return
|
|
52
186
|
|
|
53
|
-
const profile = this.
|
|
187
|
+
const profile = this._stop(false)
|
|
188
|
+
if (this._codeHotspotsEnabled) {
|
|
189
|
+
beforeCh.unsubscribe(this._enter)
|
|
190
|
+
enterCh.subscribe(this._enter)
|
|
191
|
+
this._profilerState = undefined
|
|
192
|
+
}
|
|
193
|
+
|
|
54
194
|
this._started = false
|
|
55
195
|
return profile
|
|
56
196
|
}
|
|
@@ -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', spanRemoveIntegrationFromService: false }
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
get schema () {
|
|
@@ -15,7 +15,7 @@ class SchemaManager {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
get shouldUseConsistentServiceNaming () {
|
|
18
|
-
return this.config.
|
|
18
|
+
return this.config.spanRemoveIntegrationFromService && this.version === 'v0'
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
opName (type, kind, plugin, ...opNameArgs) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const SchemaDefinition = require('../definition')
|
|
2
2
|
const messaging = require('./messaging')
|
|
3
3
|
const storage = require('./storage')
|
|
4
|
+
const graphql = require('./graphql')
|
|
4
5
|
const web = require('./web')
|
|
5
6
|
|
|
6
|
-
module.exports = new SchemaDefinition({ messaging, storage, web })
|
|
7
|
+
module.exports = new SchemaDefinition({ messaging, storage, web, graphql })
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const SchemaDefinition = require('../definition')
|
|
2
2
|
const messaging = require('./messaging')
|
|
3
3
|
const storage = require('./storage')
|
|
4
|
+
const graphql = require('./graphql')
|
|
4
5
|
const web = require('./web')
|
|
5
6
|
|
|
6
|
-
module.exports = new SchemaDefinition({ messaging, storage, web })
|
|
7
|
+
module.exports = new SchemaDefinition({ messaging, storage, web, graphql })
|
|
@@ -7,8 +7,10 @@ const { sendData } = require('./send-data')
|
|
|
7
7
|
const dc = require('../../../diagnostics_channel')
|
|
8
8
|
const { fileURLToPath } = require('url')
|
|
9
9
|
|
|
10
|
-
const
|
|
11
|
-
const
|
|
10
|
+
const savedDependenciesToSend = new Set()
|
|
11
|
+
const detectedDependencyKeys = new Set()
|
|
12
|
+
const detectedDependencyVersions = new Set()
|
|
13
|
+
|
|
12
14
|
const FILE_URI_START = `file://`
|
|
13
15
|
const moduleLoadStartChannel = dc.channel('dd-trace:moduleLoadStart')
|
|
14
16
|
|
|
@@ -18,14 +20,14 @@ function waitAndSend (config, application, host) {
|
|
|
18
20
|
if (!immediate) {
|
|
19
21
|
immediate = setImmediate(() => {
|
|
20
22
|
immediate = null
|
|
21
|
-
if (
|
|
22
|
-
const dependencies = Array.from(
|
|
23
|
-
|
|
23
|
+
if (savedDependenciesToSend.size > 0) {
|
|
24
|
+
const dependencies = Array.from(savedDependenciesToSend.values()).splice(0, 1000).map(pair => {
|
|
25
|
+
savedDependenciesToSend.delete(pair)
|
|
24
26
|
const [name, version] = pair.split(' ')
|
|
25
27
|
return { name, version }
|
|
26
28
|
})
|
|
27
29
|
sendData(config, application, host, 'app-dependencies-loaded', { dependencies })
|
|
28
|
-
if (
|
|
30
|
+
if (savedDependenciesToSend.size > 0) {
|
|
29
31
|
waitAndSend(config, application, host)
|
|
30
32
|
}
|
|
31
33
|
}
|
|
@@ -46,15 +48,24 @@ function onModuleLoad (data) {
|
|
|
46
48
|
}
|
|
47
49
|
const parseResult = filename && parse(filename)
|
|
48
50
|
const request = data.request || (parseResult && parseResult.name)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
const dependencyKey = parseResult && parseResult.basedir ? parseResult.basedir : request
|
|
52
|
+
|
|
53
|
+
if (filename && request && isDependency(filename, request) && !detectedDependencyKeys.has(dependencyKey)) {
|
|
54
|
+
detectedDependencyKeys.add(dependencyKey)
|
|
55
|
+
|
|
51
56
|
if (parseResult) {
|
|
52
57
|
const { name, basedir } = parseResult
|
|
53
58
|
if (basedir) {
|
|
54
59
|
try {
|
|
55
60
|
const { version } = requirePackageJson(basedir, module)
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
const dependencyAndVersion = `${name} ${version}`
|
|
62
|
+
|
|
63
|
+
if (!detectedDependencyVersions.has(dependencyAndVersion)) {
|
|
64
|
+
savedDependenciesToSend.add(dependencyAndVersion)
|
|
65
|
+
detectedDependencyVersions.add(dependencyAndVersion)
|
|
66
|
+
|
|
67
|
+
waitAndSend(config, application, host)
|
|
68
|
+
}
|
|
58
69
|
} catch (e) {
|
|
59
70
|
// can not read the package.json, do nothing
|
|
60
71
|
}
|
|
@@ -88,8 +99,9 @@ function stop () {
|
|
|
88
99
|
config = null
|
|
89
100
|
application = null
|
|
90
101
|
host = null
|
|
91
|
-
|
|
92
|
-
|
|
102
|
+
detectedDependencyKeys.clear()
|
|
103
|
+
savedDependenciesToSend.clear()
|
|
104
|
+
detectedDependencyVersions.clear()
|
|
93
105
|
if (moduleLoadStartChannel.hasSubscribers) {
|
|
94
106
|
moduleLoadStartChannel.unsubscribe(onModuleLoad)
|
|
95
107
|
}
|
|
@@ -25,6 +25,10 @@ function mapToJsonArray (map) {
|
|
|
25
25
|
return Array.from(map.values()).map(v => v.toJSON())
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
function hasPoints (metric) {
|
|
29
|
+
return metric.points.length > 0
|
|
30
|
+
}
|
|
31
|
+
|
|
28
32
|
class Metric {
|
|
29
33
|
constructor (namespace, metric, common, tags) {
|
|
30
34
|
this.namespace = namespace.toString()
|
|
@@ -172,10 +176,16 @@ class MetricsCollection extends Map {
|
|
|
172
176
|
|
|
173
177
|
toJSON () {
|
|
174
178
|
if (!this.size) return
|
|
179
|
+
|
|
180
|
+
const series = mapToJsonArray(this)
|
|
181
|
+
.filter(hasPoints)
|
|
182
|
+
|
|
183
|
+
if (!series.length) return
|
|
184
|
+
|
|
175
185
|
const { namespace } = this
|
|
176
186
|
return {
|
|
177
187
|
namespace,
|
|
178
|
-
series
|
|
188
|
+
series
|
|
179
189
|
}
|
|
180
190
|
}
|
|
181
191
|
}
|
|
@@ -64,7 +64,7 @@ if (!Channel.prototype.runStores) {
|
|
|
64
64
|
this._stores.set(store, transform)
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
Channel.prototype.unbindStore = ActiveChannelPrototype.
|
|
67
|
+
Channel.prototype.unbindStore = ActiveChannelPrototype.unbindStore = function (store) {
|
|
68
68
|
if (!this._stores) return
|
|
69
69
|
this._stores.delete(store)
|
|
70
70
|
}
|
package/scripts/version.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const path = require('path')
|
|
4
|
-
const fs = require('fs')
|
|
5
|
-
const semver = require('semver')
|
|
6
|
-
const exec = require('./helpers/exec')
|
|
7
|
-
const title = require('./helpers/title')
|
|
8
|
-
|
|
9
|
-
const pkg = require('../package.json')
|
|
10
|
-
const increment = getIncrement()
|
|
11
|
-
const version = semver.inc(pkg.version, increment, 'pre')
|
|
12
|
-
|
|
13
|
-
title(`Bumping version to v${version}.`)
|
|
14
|
-
|
|
15
|
-
const currentBranch = exec.pipe(`git branch --show-current`)
|
|
16
|
-
|
|
17
|
-
if (currentBranch === 'master') {
|
|
18
|
-
const major = semver.major(pkg.version)
|
|
19
|
-
const nextMajor = semver.major(pkg.version) + 1
|
|
20
|
-
|
|
21
|
-
exec(`git checkout -b v${major}.x`)
|
|
22
|
-
exec(`git push -u origin HEAD`)
|
|
23
|
-
|
|
24
|
-
bump(`${nextMajor}.0.0-pre`)
|
|
25
|
-
|
|
26
|
-
exec(`git checkout v${major}.x`)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
bump(version)
|
|
30
|
-
|
|
31
|
-
exec(`git checkout ${currentBranch}`)
|
|
32
|
-
|
|
33
|
-
function bump (newVersion) {
|
|
34
|
-
pkg.version = newVersion
|
|
35
|
-
|
|
36
|
-
exec(`git checkout -b v${newVersion}-bump`)
|
|
37
|
-
write('package.json', JSON.stringify(pkg, null, 2) + '\n')
|
|
38
|
-
write('packages/dd-trace/lib/version.js', `module.exports = '${newVersion}'\n`)
|
|
39
|
-
add('package.json')
|
|
40
|
-
add('packages/dd-trace/lib/version.js')
|
|
41
|
-
exec(`git commit -m "v${newVersion}"`)
|
|
42
|
-
exec(`git push -u origin HEAD`)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function getIncrement () {
|
|
46
|
-
const increments = ['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease']
|
|
47
|
-
const index = increments.indexOf(process.argv[2])
|
|
48
|
-
|
|
49
|
-
if (index === -1) {
|
|
50
|
-
throw new Error(`increment must be one of ${increments.join(', ')}`)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return increments[index]
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function filename (relativePath) {
|
|
57
|
-
return path.normalize(path.join(__dirname, '..', relativePath))
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function write (file, data) {
|
|
61
|
-
fs.writeFileSync(filename(file), data)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function add (file) {
|
|
65
|
-
exec(`git add ${filename(file)}`)
|
|
66
|
-
}
|