dd-trace 2.0.0-appsec-beta.3 → 2.0.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/MIGRATING.md +65 -0
- package/NOTICE +4 -0
- package/ci/cypress/plugin.js +3 -0
- package/ci/cypress/support.js +1 -0
- package/ci/init.js +13 -0
- package/ci/jest/env.js +14 -0
- package/index.d.ts +35 -48
- package/package.json +7 -4
- package/packages/datadog-instrumentations/index.js +10 -0
- package/packages/datadog-instrumentations/src/bluebird.js +26 -0
- package/packages/datadog-instrumentations/src/dns.js +94 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +120 -0
- package/packages/datadog-instrumentations/src/helpers/promise.js +29 -0
- package/packages/datadog-instrumentations/src/memcached.js +53 -0
- package/packages/datadog-instrumentations/src/mysql.js +67 -0
- package/packages/datadog-instrumentations/src/promise-js.js +15 -0
- package/packages/datadog-instrumentations/src/promise.js +14 -0
- package/packages/datadog-instrumentations/src/q.js +13 -0
- package/packages/datadog-instrumentations/src/when.js +14 -0
- package/packages/datadog-plugin-cucumber/src/index.js +4 -4
- package/packages/datadog-plugin-cypress/src/plugin.js +12 -2
- package/packages/datadog-plugin-cypress/src/support.js +21 -6
- package/packages/datadog-plugin-dns/src/index.js +65 -178
- package/packages/datadog-plugin-fs/src/index.js +7 -3
- package/packages/datadog-plugin-http/src/client.js +9 -24
- package/packages/datadog-plugin-http/src/server.js +5 -0
- package/packages/datadog-plugin-http2/src/client.js +1 -24
- package/packages/datadog-plugin-http2/src/server.js +2 -2
- package/packages/datadog-plugin-jest/src/jest-environment.js +4 -4
- package/packages/datadog-plugin-jest/src/jest-jasmine2.js +2 -2
- package/packages/datadog-plugin-knex/src/index.js +3 -3
- package/packages/datadog-plugin-memcached/src/index.js +41 -63
- package/packages/datadog-plugin-mocha/src/index.js +3 -2
- package/packages/datadog-plugin-moleculer/src/client.js +60 -0
- package/packages/datadog-plugin-moleculer/src/index.js +8 -0
- package/packages/datadog-plugin-moleculer/src/server.js +61 -0
- package/packages/datadog-plugin-moleculer/src/util.js +21 -0
- package/packages/datadog-plugin-mongoose/src/index.js +2 -2
- package/packages/datadog-plugin-mysql/src/index.js +37 -89
- package/packages/datadog-plugin-net/src/index.js +5 -0
- package/packages/datadog-plugin-pino/src/index.js +25 -1
- package/packages/datadog-plugin-redis/src/index.js +31 -1
- package/packages/datadog-plugin-router/src/index.js +28 -3
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/appsec/addresses.js +11 -4
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +5 -8
- package/packages/dd-trace/src/{gateway → appsec/gateway}/als.js +1 -0
- package/packages/dd-trace/src/appsec/gateway/channels.js +11 -0
- package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/engine.js +20 -30
- package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/index.js +0 -0
- package/packages/dd-trace/src/{gateway → appsec/gateway}/engine/runner.js +2 -0
- package/packages/dd-trace/src/appsec/index.js +54 -38
- package/packages/dd-trace/src/appsec/recommended.json +1 -1
- package/packages/dd-trace/src/appsec/reporter.js +27 -10
- package/packages/dd-trace/src/config.js +31 -27
- package/packages/dd-trace/src/constants.js +6 -3
- package/packages/dd-trace/src/exporters/agent/request.js +8 -0
- package/packages/dd-trace/src/format.js +26 -39
- package/packages/dd-trace/src/instrumenter.js +6 -1
- package/packages/dd-trace/src/log.js +6 -15
- package/packages/dd-trace/src/noop/span_context.js +0 -1
- package/packages/dd-trace/src/noop/tracer.js +0 -6
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +79 -46
- package/packages/dd-trace/src/opentracing/span.js +2 -7
- package/packages/dd-trace/src/opentracing/span_context.js +2 -4
- package/packages/dd-trace/src/opentracing/tracer.js +5 -23
- package/packages/dd-trace/src/plugin_manager.js +65 -0
- package/packages/dd-trace/src/plugins/index.js +1 -5
- package/packages/dd-trace/src/plugins/plugin.js +63 -0
- package/packages/dd-trace/src/plugins/util/ci.js +13 -4
- package/packages/dd-trace/src/plugins/util/redis.js +0 -2
- package/packages/dd-trace/src/plugins/util/test.js +9 -4
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +17 -2
- package/packages/dd-trace/src/plugins/util/web.js +6 -16
- package/packages/dd-trace/src/priority_sampler.js +71 -19
- package/packages/dd-trace/src/profiling/exporters/agent.js +35 -34
- package/packages/dd-trace/src/proxy.js +39 -35
- package/packages/dd-trace/src/ritm.js +40 -16
- package/packages/dd-trace/src/span_processor.js +0 -7
- package/packages/dd-trace/src/tracer.js +5 -6
- package/scripts/install_plugin_modules.js +30 -1
- package/packages/datadog-plugin-bluebird/src/index.js +0 -69
- package/packages/datadog-plugin-promise/src/index.js +0 -17
- package/packages/datadog-plugin-promise-js/src/index.js +0 -20
- package/packages/datadog-plugin-q/src/index.js +0 -16
- package/packages/datadog-plugin-when/src/index.js +0 -17
- package/packages/dd-trace/src/gateway/channels.js +0 -8
- package/packages/dd-trace/src/gateway/dc_block.js +0 -68
- package/packages/dd-trace/src/plugins/util/ci-app-spec.json +0 -36
- package/packages/dd-trace/src/plugins/util/promise.js +0 -31
- package/packages/dd-trace/src/scope/noop/scope_manager.js +0 -28
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const addresses = require('./addresses')
|
|
4
|
+
const Limiter = require('../rate_limiter')
|
|
5
|
+
|
|
6
|
+
// default limiter, configurable with setRateLimit()
|
|
7
|
+
let limiter = new Limiter(100)
|
|
4
8
|
|
|
5
9
|
const REQUEST_HEADERS_PASSLIST = [
|
|
6
10
|
'accept',
|
|
@@ -36,7 +40,6 @@ function resolveHTTPRequest (context) {
|
|
|
36
40
|
const headers = context.resolve(addresses.HTTP_INCOMING_HEADERS)
|
|
37
41
|
|
|
38
42
|
return {
|
|
39
|
-
// route: context.resolve(addresses.HTTP_INCOMING_ROUTE),
|
|
40
43
|
remote_ip: context.resolve(addresses.HTTP_INCOMING_REMOTE_IP),
|
|
41
44
|
headers: filterHeaders(headers, REQUEST_HEADERS_PASSLIST, 'http.request.headers.')
|
|
42
45
|
}
|
|
@@ -48,6 +51,7 @@ function resolveHTTPResponse (context) {
|
|
|
48
51
|
const headers = context.resolve(addresses.HTTP_INCOMING_RESPONSE_HEADERS)
|
|
49
52
|
|
|
50
53
|
return {
|
|
54
|
+
endpoint: context.resolve(addresses.HTTP_INCOMING_ENDPOINT),
|
|
51
55
|
headers: filterHeaders(headers, RESPONSE_HEADERS_PASSLIST, 'http.response.headers.')
|
|
52
56
|
}
|
|
53
57
|
}
|
|
@@ -61,16 +65,16 @@ function filterHeaders (headers, passlist, prefix) {
|
|
|
61
65
|
const headerName = passlist[i]
|
|
62
66
|
|
|
63
67
|
if (headers[headerName]) {
|
|
64
|
-
result[`${prefix}${formatHeaderName(headerName)}`] = headers[headerName]
|
|
68
|
+
result[`${prefix}${formatHeaderName(headerName)}`] = headers[headerName] + ''
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
return result
|
|
69
73
|
}
|
|
70
74
|
|
|
75
|
+
// TODO: this can be precomputed at start time
|
|
71
76
|
function formatHeaderName (name) {
|
|
72
77
|
return name
|
|
73
|
-
.toString()
|
|
74
78
|
.trim()
|
|
75
79
|
.slice(0, 200)
|
|
76
80
|
.replace(/[^a-zA-Z0-9_\-:/]/g, '_')
|
|
@@ -85,10 +89,14 @@ function reportAttack (attackData, store) {
|
|
|
85
89
|
const currentTags = topSpan.context()._tags
|
|
86
90
|
|
|
87
91
|
const newTags = {
|
|
88
|
-
'appsec.event': true
|
|
89
|
-
|
|
92
|
+
'appsec.event': 'true'
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (limiter.isAllowed()) {
|
|
96
|
+
newTags['manual.keep'] = 'true' // TODO: figure out how to keep appsec traces with sampling revamp
|
|
90
97
|
}
|
|
91
98
|
|
|
99
|
+
// TODO: maybe add this to format.js later (to take decision as late as possible)
|
|
92
100
|
if (!currentTags['_dd.origin']) {
|
|
93
101
|
newTags['_dd.origin'] = 'appsec'
|
|
94
102
|
}
|
|
@@ -115,8 +123,6 @@ function reportAttack (attackData, store) {
|
|
|
115
123
|
}
|
|
116
124
|
|
|
117
125
|
newTags['network.client.ip'] = resolvedRequest.remote_ip
|
|
118
|
-
|
|
119
|
-
// newTags['http.endpoint'] = resolvedRequest.route
|
|
120
126
|
}
|
|
121
127
|
|
|
122
128
|
topSpan.addTags(newTags)
|
|
@@ -126,9 +132,19 @@ function finishAttacks (req, context) {
|
|
|
126
132
|
const topSpan = req && req._datadog && req._datadog.span
|
|
127
133
|
if (!topSpan || !context) return false
|
|
128
134
|
|
|
129
|
-
const
|
|
135
|
+
const resolvedResponse = resolveHTTPResponse(context)
|
|
136
|
+
|
|
137
|
+
const newTags = resolvedResponse.headers
|
|
138
|
+
|
|
139
|
+
if (resolvedResponse.endpoint) {
|
|
140
|
+
newTags['http.endpoint'] = resolvedResponse.endpoint
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
topSpan.addTags(newTags)
|
|
144
|
+
}
|
|
130
145
|
|
|
131
|
-
|
|
146
|
+
function setRateLimit (rateLimit) {
|
|
147
|
+
limiter = new Limiter(rateLimit)
|
|
132
148
|
}
|
|
133
149
|
|
|
134
150
|
module.exports = {
|
|
@@ -137,5 +153,6 @@ module.exports = {
|
|
|
137
153
|
filterHeaders,
|
|
138
154
|
formatHeaderName,
|
|
139
155
|
reportAttack,
|
|
140
|
-
finishAttacks
|
|
156
|
+
finishAttacks,
|
|
157
|
+
setRateLimit
|
|
141
158
|
}
|
|
@@ -24,9 +24,12 @@ class Config {
|
|
|
24
24
|
tagger.add(this.tags, process.env.DD_TRACE_GLOBAL_TAGS)
|
|
25
25
|
tagger.add(this.tags, options.tags)
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
const DD_TRACING_ENABLED = coalesce(
|
|
28
|
+
process.env.DD_TRACING_ENABLED,
|
|
29
|
+
true
|
|
30
|
+
)
|
|
28
31
|
const DD_PROFILING_ENABLED = coalesce(
|
|
29
|
-
options.profiling,
|
|
32
|
+
options.profiling, // TODO: remove when enabled by default
|
|
30
33
|
process.env.DD_EXPERIMENTAL_PROFILING_ENABLED,
|
|
31
34
|
process.env.DD_PROFILING_ENABLED,
|
|
32
35
|
false
|
|
@@ -42,7 +45,7 @@ class Config {
|
|
|
42
45
|
false
|
|
43
46
|
)
|
|
44
47
|
const DD_RUNTIME_METRICS_ENABLED = coalesce(
|
|
45
|
-
options.runtimeMetrics,
|
|
48
|
+
options.runtimeMetrics, // TODO: remove when enabled by default
|
|
46
49
|
process.env.DD_RUNTIME_METRICS_ENABLED,
|
|
47
50
|
false
|
|
48
51
|
)
|
|
@@ -85,15 +88,9 @@ class Config {
|
|
|
85
88
|
const DD_TRACE_STARTUP_LOGS = coalesce(
|
|
86
89
|
options.startupLogs,
|
|
87
90
|
process.env.DD_TRACE_STARTUP_LOGS,
|
|
88
|
-
|
|
89
|
-
)
|
|
90
|
-
const DD_TRACE_ENABLED = coalesce(
|
|
91
|
-
options.enabled,
|
|
92
|
-
process.env.DD_TRACE_ENABLED,
|
|
93
|
-
true
|
|
91
|
+
false
|
|
94
92
|
)
|
|
95
93
|
const DD_TRACE_DEBUG = coalesce(
|
|
96
|
-
options.debug,
|
|
97
94
|
process.env.DD_TRACE_DEBUG,
|
|
98
95
|
false
|
|
99
96
|
)
|
|
@@ -121,39 +118,46 @@ class Config {
|
|
|
121
118
|
process.env.DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
|
|
122
119
|
false
|
|
123
120
|
)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
false
|
|
128
|
-
)
|
|
129
|
-
// TODO(simon-id): add documentation for appsec config when we release it in public beta
|
|
121
|
+
|
|
122
|
+
let appsec = options.appsec || (options.experimental && options.experimental.appsec)
|
|
123
|
+
|
|
130
124
|
const DD_APPSEC_ENABLED = coalesce(
|
|
131
|
-
|
|
132
|
-
options.experimental.appsec &&
|
|
133
|
-
(options.experimental.appsec === true || options.experimental.appsec.enabled === true),
|
|
134
|
-
process.env.DD_EXPERIMENTAL_APPSEC_ENABLED,
|
|
125
|
+
appsec && (appsec === true || appsec.enabled === true), // TODO: remove when enabled by default
|
|
135
126
|
process.env.DD_APPSEC_ENABLED,
|
|
136
127
|
false
|
|
137
128
|
)
|
|
129
|
+
|
|
130
|
+
appsec = appsec || {}
|
|
131
|
+
|
|
138
132
|
const DD_APPSEC_RULES = coalesce(
|
|
139
|
-
|
|
133
|
+
appsec.rules,
|
|
140
134
|
process.env.DD_APPSEC_RULES,
|
|
141
135
|
path.join(__dirname, 'appsec', 'recommended.json')
|
|
142
136
|
)
|
|
137
|
+
const DD_APPSEC_TRACE_RATE_LIMIT = coalesce(
|
|
138
|
+
appsec.rateLimit,
|
|
139
|
+
process.env.DD_APPSEC_TRACE_RATE_LIMIT,
|
|
140
|
+
100
|
|
141
|
+
)
|
|
143
142
|
|
|
144
143
|
const sampler = (options.experimental && options.experimental.sampler) || {}
|
|
145
144
|
const ingestion = options.ingestion || {}
|
|
146
145
|
const dogstatsd = coalesce(options.dogstatsd, {})
|
|
147
146
|
|
|
148
147
|
Object.assign(sampler, {
|
|
149
|
-
sampleRate: coalesce(
|
|
148
|
+
sampleRate: coalesce(
|
|
149
|
+
options.sampleRate,
|
|
150
|
+
ingestion.sampleRate,
|
|
151
|
+
sampler.sampleRate,
|
|
152
|
+
process.env.DD_TRACE_SAMPLE_RATE
|
|
153
|
+
),
|
|
150
154
|
rateLimit: coalesce(ingestion.rateLimit, sampler.rateLimit, process.env.DD_TRACE_RATE_LIMIT)
|
|
151
155
|
})
|
|
152
156
|
|
|
153
157
|
const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
|
|
154
158
|
const defaultFlushInterval = inAWSLambda ? 0 : 2000
|
|
155
159
|
|
|
156
|
-
this.
|
|
160
|
+
this.tracing = !isFalse(DD_TRACING_ENABLED)
|
|
157
161
|
this.debug = isTrue(DD_TRACE_DEBUG)
|
|
158
162
|
this.logInjection = isTrue(DD_LOGS_INJECTION)
|
|
159
163
|
this.env = DD_ENV
|
|
@@ -162,7 +166,7 @@ class Config {
|
|
|
162
166
|
this.hostname = DD_AGENT_HOST || (this.url && this.url.hostname)
|
|
163
167
|
this.port = String(DD_TRACE_AGENT_PORT || (this.url && this.url.port))
|
|
164
168
|
this.flushInterval = coalesce(parseInt(options.flushInterval, 10), defaultFlushInterval)
|
|
165
|
-
this.sampleRate = coalesce(Math.min(Math.max(
|
|
169
|
+
this.sampleRate = coalesce(Math.min(Math.max(sampler.sampleRate, 0), 1), 1)
|
|
166
170
|
this.logger = options.logger
|
|
167
171
|
this.plugins = !!coalesce(options.plugins, true)
|
|
168
172
|
this.service = DD_SERVICE
|
|
@@ -180,8 +184,7 @@ class Config {
|
|
|
180
184
|
runtimeId: isTrue(DD_TRACE_RUNTIME_ID_ENABLED),
|
|
181
185
|
exporter: DD_TRACE_EXPORTER,
|
|
182
186
|
enableGetRumData: isTrue(DD_TRACE_GET_RUM_DATA_ENABLED),
|
|
183
|
-
sampler
|
|
184
|
-
internalErrors: isTrue(DD_TRACE_INTERNAL_ERRORS_ENABLED)
|
|
187
|
+
sampler
|
|
185
188
|
}
|
|
186
189
|
this.reportHostname = isTrue(coalesce(options.reportHostname, process.env.DD_TRACE_REPORT_HOSTNAME, false))
|
|
187
190
|
this.scope = process.env.DD_TRACE_SCOPE
|
|
@@ -200,7 +203,8 @@ class Config {
|
|
|
200
203
|
this.protocolVersion = DD_TRACE_AGENT_PROTOCOL_VERSION
|
|
201
204
|
this.appsec = {
|
|
202
205
|
enabled: isTrue(DD_APPSEC_ENABLED),
|
|
203
|
-
rules: DD_APPSEC_RULES
|
|
206
|
+
rules: DD_APPSEC_RULES,
|
|
207
|
+
rateLimit: DD_APPSEC_TRACE_RATE_LIMIT
|
|
204
208
|
}
|
|
205
209
|
|
|
206
210
|
tagger.add(this.tags, {
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
module.exports = {
|
|
4
|
-
SAMPLE_RATE_METRIC_KEY: '_sample_rate',
|
|
5
4
|
SAMPLING_PRIORITY_KEY: '_sampling_priority_v1',
|
|
6
5
|
ANALYTICS_KEY: '_dd1.sr.eausr',
|
|
7
6
|
ORIGIN_KEY: '_dd.origin',
|
|
8
7
|
HOSTNAME_KEY: '_dd.hostname',
|
|
9
|
-
REFERENCE_NOOP: 'noop',
|
|
10
8
|
SAMPLING_RULE_DECISION: '_dd.rule_psr',
|
|
11
9
|
SAMPLING_LIMIT_DECISION: '_dd.limit_psr',
|
|
12
10
|
SAMPLING_AGENT_DECISION: '_dd.agent_psr',
|
|
13
|
-
|
|
11
|
+
SAMPLING_MECHANISM_DEFAULT: 0,
|
|
12
|
+
SAMPLING_MECHANISM_AGENT: 1,
|
|
13
|
+
SAMPLING_MECHANISM_RULE: 3,
|
|
14
|
+
SAMPLING_MECHANISM_MANUAL: 4,
|
|
15
|
+
DATADOG_LAMBDA_EXTENSION_PATH: '/opt/extensions/datadog-agent',
|
|
16
|
+
UPSTREAM_SERVICES_KEY: '_dd.p.upstream_services'
|
|
14
17
|
}
|
|
@@ -4,12 +4,17 @@ const http = require('http')
|
|
|
4
4
|
const https = require('https')
|
|
5
5
|
const docker = require('./docker')
|
|
6
6
|
const log = require('../../log')
|
|
7
|
+
const { storage } = require('../../../../datadog-core')
|
|
7
8
|
|
|
8
9
|
const httpAgent = new http.Agent({ keepAlive: true })
|
|
9
10
|
const httpsAgent = new https.Agent({ keepAlive: true })
|
|
10
11
|
const containerId = docker.id()
|
|
11
12
|
|
|
12
13
|
function retriableRequest (options, callback, client, data) {
|
|
14
|
+
const store = storage.getStore()
|
|
15
|
+
|
|
16
|
+
storage.enterWith({ noop: true })
|
|
17
|
+
|
|
13
18
|
const req = client.request(options, res => {
|
|
14
19
|
let data = ''
|
|
15
20
|
|
|
@@ -29,6 +34,9 @@ function retriableRequest (options, callback, client, data) {
|
|
|
29
34
|
})
|
|
30
35
|
req.setTimeout(options.timeout, req.abort)
|
|
31
36
|
data.forEach(buffer => req.write(buffer))
|
|
37
|
+
|
|
38
|
+
storage.enterWith(store)
|
|
39
|
+
|
|
32
40
|
return req
|
|
33
41
|
}
|
|
34
42
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const constants = require('./constants')
|
|
4
4
|
const tags = require('../../../ext/tags')
|
|
5
|
-
const log = require('./log')
|
|
6
5
|
const id = require('./id')
|
|
7
6
|
const { isError } = require('./util')
|
|
8
7
|
|
|
@@ -25,6 +24,7 @@ function format (span) {
|
|
|
25
24
|
|
|
26
25
|
extractError(formatted, span)
|
|
27
26
|
extractRootTags(formatted, span)
|
|
27
|
+
extractChunkTags(formatted, span)
|
|
28
28
|
extractTags(formatted, span)
|
|
29
29
|
|
|
30
30
|
return formatted
|
|
@@ -37,8 +37,8 @@ function formatSpan (span) {
|
|
|
37
37
|
trace_id: spanContext._traceId,
|
|
38
38
|
span_id: spanContext._spanId,
|
|
39
39
|
parent_id: spanContext._parentId || id('0'),
|
|
40
|
-
name:
|
|
41
|
-
resource:
|
|
40
|
+
name: String(spanContext._name),
|
|
41
|
+
resource: String(spanContext._name),
|
|
42
42
|
error: 0,
|
|
43
43
|
meta: {},
|
|
44
44
|
metrics: {},
|
|
@@ -53,7 +53,6 @@ function extractTags (trace, span) {
|
|
|
53
53
|
const tags = context._tags
|
|
54
54
|
const hostname = context._hostname
|
|
55
55
|
const priority = context._sampling.priority
|
|
56
|
-
const internalErrors = span.tracer()._internalErrors
|
|
57
56
|
|
|
58
57
|
if (tags['span.kind'] && tags['span.kind'] !== 'internal') {
|
|
59
58
|
addTag({}, trace.metrics, MEASURED, 1)
|
|
@@ -75,7 +74,7 @@ function extractTags (trace, span) {
|
|
|
75
74
|
addTag({}, trace.metrics, tag, tags[tag] === undefined || tags[tag] ? 1 : 0)
|
|
76
75
|
break
|
|
77
76
|
case 'error':
|
|
78
|
-
if (tags[tag] && (context._name !== 'fs.operation'
|
|
77
|
+
if (tags[tag] && (context._name !== 'fs.operation')) {
|
|
79
78
|
trace.error = 1
|
|
80
79
|
}
|
|
81
80
|
break
|
|
@@ -83,7 +82,7 @@ function extractTags (trace, span) {
|
|
|
83
82
|
case 'error.msg':
|
|
84
83
|
case 'error.stack':
|
|
85
84
|
// HACK: remove when implemented in the backend
|
|
86
|
-
if (context._name !== 'fs.operation'
|
|
85
|
+
if (context._name !== 'fs.operation') {
|
|
87
86
|
trace.error = 1
|
|
88
87
|
}
|
|
89
88
|
default: // eslint-disable-line no-fallthrough
|
|
@@ -112,6 +111,17 @@ function extractRootTags (trace, span) {
|
|
|
112
111
|
addTag({}, trace.metrics, SAMPLING_AGENT_DECISION, context._trace[SAMPLING_AGENT_DECISION])
|
|
113
112
|
}
|
|
114
113
|
|
|
114
|
+
function extractChunkTags (trace, span) {
|
|
115
|
+
const context = span.context()
|
|
116
|
+
const isLocalRoot = span === context._trace.started[0]
|
|
117
|
+
|
|
118
|
+
if (!isLocalRoot) return
|
|
119
|
+
|
|
120
|
+
for (const key in context._trace.tags) {
|
|
121
|
+
addTag(trace.meta, trace.metrics, key, context._trace.tags[key])
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
115
125
|
function extractError (trace, span) {
|
|
116
126
|
const error = span.context()._tags['error']
|
|
117
127
|
if (isError(error)) {
|
|
@@ -121,7 +131,7 @@ function extractError (trace, span) {
|
|
|
121
131
|
}
|
|
122
132
|
}
|
|
123
133
|
|
|
124
|
-
function addTag (meta, metrics, key, value,
|
|
134
|
+
function addTag (meta, metrics, key, value, nested) {
|
|
125
135
|
switch (typeof value) {
|
|
126
136
|
case 'string':
|
|
127
137
|
if (!value) break
|
|
@@ -131,6 +141,9 @@ function addTag (meta, metrics, key, value, seen) {
|
|
|
131
141
|
if (isNaN(value)) break
|
|
132
142
|
metrics[key] = value
|
|
133
143
|
break
|
|
144
|
+
case 'boolean':
|
|
145
|
+
metrics[key] = value ? 1 : 0
|
|
146
|
+
break
|
|
134
147
|
case 'undefined':
|
|
135
148
|
break
|
|
136
149
|
case 'object':
|
|
@@ -139,41 +152,15 @@ function addTag (meta, metrics, key, value, seen) {
|
|
|
139
152
|
// Special case for Node.js Buffer and URL
|
|
140
153
|
if (isNodeBuffer(value) || isUrl(value)) {
|
|
141
154
|
metrics[key] = value.toString()
|
|
142
|
-
|
|
143
|
-
|
|
155
|
+
} else if (!Array.isArray(value) && !nested) {
|
|
156
|
+
for (const prop in value) {
|
|
157
|
+
if (!value.hasOwnProperty(prop)) continue
|
|
144
158
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
break
|
|
159
|
+
addTag(meta, metrics, `${key}.${prop}`, value[prop], true)
|
|
160
|
+
}
|
|
148
161
|
}
|
|
149
162
|
|
|
150
|
-
|
|
151
|
-
addTag(meta, metrics, key, serialize(value))
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function addObjectTag (meta, metrics, key, value, seen) {
|
|
156
|
-
seen = seen || []
|
|
157
|
-
|
|
158
|
-
if (~seen.indexOf(value)) {
|
|
159
|
-
meta[key] = '[Circular]'
|
|
160
|
-
return
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
seen.push(value)
|
|
164
|
-
|
|
165
|
-
for (const prop in value) {
|
|
166
|
-
addTag(meta, metrics, `${key}.${prop}`, value[prop], seen)
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
seen.pop()
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function serialize (obj) {
|
|
173
|
-
try {
|
|
174
|
-
return obj && typeof obj.toString !== 'function' ? JSON.stringify(obj) : String(obj)
|
|
175
|
-
} catch (e) {
|
|
176
|
-
log.error(e)
|
|
163
|
+
break
|
|
177
164
|
}
|
|
178
165
|
}
|
|
179
166
|
|
|
@@ -6,6 +6,7 @@ const metrics = require('./metrics')
|
|
|
6
6
|
const Loader = require('./loader')
|
|
7
7
|
const { isTrue } = require('./util')
|
|
8
8
|
const plugins = require('./plugins')
|
|
9
|
+
const Plugin = require('./plugins/plugin')
|
|
9
10
|
|
|
10
11
|
const disabledPlugins = process.env.DD_TRACE_DISABLED_PLUGINS
|
|
11
12
|
|
|
@@ -42,6 +43,9 @@ class Instrumenter {
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
use (name, config) {
|
|
46
|
+
if (typeof name !== 'string') return
|
|
47
|
+
const plugin = plugins[name.toLowerCase()]
|
|
48
|
+
if (plugin && plugin.prototype instanceof Plugin) return
|
|
45
49
|
if (typeof config === 'boolean') {
|
|
46
50
|
config = { enabled: config }
|
|
47
51
|
}
|
|
@@ -49,7 +53,7 @@ class Instrumenter {
|
|
|
49
53
|
config = getConfig(name, config)
|
|
50
54
|
|
|
51
55
|
try {
|
|
52
|
-
this._set(
|
|
56
|
+
this._set(plugin, { name, config })
|
|
53
57
|
} catch (e) {
|
|
54
58
|
log.debug(`Could not find a plugin named "${name}".`)
|
|
55
59
|
}
|
|
@@ -69,6 +73,7 @@ class Instrumenter {
|
|
|
69
73
|
Object.keys(plugins)
|
|
70
74
|
.filter(name => !this._plugins.has(plugins[name]))
|
|
71
75
|
.forEach(name => {
|
|
76
|
+
if (plugins[name].prototype instanceof Plugin) return
|
|
72
77
|
const pluginConfig = {}
|
|
73
78
|
if (serviceMapping && serviceMapping[name]) {
|
|
74
79
|
pluginConfig.service = serviceMapping[name]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const { storage } = require('../../datadog-core')
|
|
4
4
|
|
|
5
5
|
const _default = {
|
|
6
6
|
debug: msg => console.debug(msg), /* eslint-disable-line no-console */
|
|
@@ -45,11 +45,11 @@ function processMsg (msg) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
function withNoop (fn) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
const store = storage.getStore()
|
|
49
|
+
|
|
50
|
+
storage.enterWith({ noop: true })
|
|
51
|
+
fn()
|
|
52
|
+
storage.enterWith(store)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
const log = {
|
|
@@ -73,18 +73,9 @@ const log = {
|
|
|
73
73
|
return this
|
|
74
74
|
},
|
|
75
75
|
|
|
76
|
-
_noopSpan () {
|
|
77
|
-
if (!this.__noopSpan) {
|
|
78
|
-
this.__noopSpan = new NoopSpan(this._tracer)
|
|
79
|
-
}
|
|
80
|
-
return this.__noopSpan
|
|
81
|
-
},
|
|
82
|
-
|
|
83
76
|
reset () {
|
|
84
77
|
this._logger = _default
|
|
85
78
|
this._enabled = false
|
|
86
|
-
delete this._tracer
|
|
87
|
-
delete this.__noopSpan
|
|
88
79
|
this._deprecate = memoize((code, message) => {
|
|
89
80
|
withNoop(() => this._logger.error(message))
|
|
90
81
|
return this
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const Tracer = require('opentracing').Tracer
|
|
4
|
-
const ScopeManager = require('../scope/noop/scope_manager')
|
|
5
4
|
const Scope = require('../noop/scope')
|
|
6
5
|
const Span = require('./span')
|
|
7
6
|
|
|
@@ -9,7 +8,6 @@ class NoopTracer extends Tracer {
|
|
|
9
8
|
constructor (config) {
|
|
10
9
|
super(config)
|
|
11
10
|
|
|
12
|
-
this._scopeManager = new ScopeManager()
|
|
13
11
|
this._scope = new Scope()
|
|
14
12
|
this._span = new Span(this)
|
|
15
13
|
}
|
|
@@ -22,10 +20,6 @@ class NoopTracer extends Tracer {
|
|
|
22
20
|
return fn
|
|
23
21
|
}
|
|
24
22
|
|
|
25
|
-
scopeManager () {
|
|
26
|
-
return this._scopeManager
|
|
27
|
-
}
|
|
28
|
-
|
|
29
23
|
scope () {
|
|
30
24
|
return this._scope
|
|
31
25
|
}
|