dd-trace 2.4.2 → 2.7.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 +1 -2
- package/ci/init.js +6 -0
- package/ci/jest/env.js +16 -3
- package/ext/exporters.d.ts +2 -1
- package/ext/exporters.js +2 -1
- package/index.d.ts +17 -8
- package/package.json +20 -23
- package/packages/datadog-instrumentations/index.js +14 -0
- package/packages/datadog-instrumentations/src/connect.js +111 -0
- package/packages/datadog-instrumentations/src/cypress.js +8 -0
- package/packages/datadog-instrumentations/src/express.js +27 -0
- package/packages/datadog-instrumentations/src/fastify.js +187 -0
- package/packages/datadog-instrumentations/src/find-my-way.js +30 -0
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +100 -0
- package/packages/datadog-instrumentations/src/http/server.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +175 -0
- package/packages/datadog-instrumentations/src/kafkajs.js +112 -0
- package/packages/datadog-instrumentations/src/knex.js +20 -0
- package/packages/datadog-instrumentations/src/koa.js +159 -0
- package/packages/datadog-instrumentations/src/limitd-client.js +21 -0
- package/packages/datadog-instrumentations/src/oracledb.js +128 -0
- package/packages/datadog-instrumentations/src/paperplane.js +77 -0
- package/packages/datadog-instrumentations/src/pg.js +2 -2
- package/packages/datadog-instrumentations/src/restify.js +58 -0
- package/packages/datadog-instrumentations/src/rhea.js +1 -1
- package/packages/datadog-instrumentations/src/router.js +177 -0
- package/packages/datadog-plugin-aws-sdk/src/helpers.js +4 -4
- package/packages/datadog-plugin-aws-sdk/src/index.js +1 -1
- package/packages/datadog-plugin-connect/src/index.js +10 -114
- package/packages/datadog-plugin-cucumber/src/index.js +16 -16
- package/packages/datadog-plugin-cypress/src/index.js +10 -5
- package/packages/datadog-plugin-cypress/src/plugin.js +18 -17
- package/packages/datadog-plugin-dns/src/index.js +12 -1
- package/packages/datadog-plugin-express/src/index.js +11 -25
- package/packages/datadog-plugin-fastify/src/index.js +17 -4
- package/packages/datadog-plugin-find-my-way/src/index.js +20 -0
- package/packages/datadog-plugin-fs/src/index.js +2 -0
- package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +56 -111
- package/packages/datadog-plugin-http/src/server.js +2 -10
- package/packages/datadog-plugin-jest/src/index.js +101 -3
- package/packages/datadog-plugin-jest/src/util.js +1 -29
- package/packages/datadog-plugin-kafkajs/src/index.js +64 -90
- package/packages/datadog-plugin-koa/src/index.js +12 -164
- package/packages/datadog-plugin-mocha/src/index.js +14 -15
- package/packages/datadog-plugin-oracledb/src/index.js +34 -100
- package/packages/datadog-plugin-paperplane/src/index.js +14 -100
- package/packages/datadog-plugin-paperplane/src/logger.js +11 -0
- package/packages/datadog-plugin-paperplane/src/server.js +24 -0
- package/packages/datadog-plugin-restify/src/index.js +13 -75
- package/packages/datadog-plugin-router/src/index.js +67 -164
- package/packages/datadog-plugin-web/src/index.js +20 -0
- package/packages/dd-trace/lib/version.js +1 -1
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +34 -12
- package/packages/dd-trace/src/appsec/index.js +7 -3
- package/packages/dd-trace/src/appsec/recommended.json +15 -5
- package/packages/dd-trace/src/appsec/reporter.js +33 -3
- package/packages/dd-trace/src/appsec/rule_manager.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +32 -0
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +51 -0
- package/packages/dd-trace/src/config.js +33 -4
- package/packages/dd-trace/src/encode/0.4.js +0 -1
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +193 -0
- package/packages/dd-trace/src/encode/tags-processors.js +116 -0
- package/packages/dd-trace/src/exporter.js +3 -0
- package/packages/dd-trace/src/exporters/agent/index.js +1 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +7 -32
- package/packages/dd-trace/src/exporters/{agent → common}/docker.js +0 -0
- package/packages/dd-trace/src/exporters/common/request.js +83 -0
- package/packages/dd-trace/src/exporters/common/writer.js +36 -0
- package/packages/dd-trace/src/exporters/{agent/scheduler.js → scheduler.js} +0 -0
- package/packages/dd-trace/src/format.js +9 -5
- package/packages/dd-trace/src/instrumenter.js +3 -0
- package/packages/dd-trace/src/pkg.js +11 -6
- package/packages/dd-trace/src/plugin_manager.js +13 -7
- package/packages/dd-trace/src/plugins/index.js +1 -2
- package/packages/dd-trace/src/plugins/log_plugin.js +8 -4
- package/packages/dd-trace/src/plugins/plugin.js +8 -0
- package/packages/dd-trace/src/plugins/util/test.js +79 -1
- package/packages/dd-trace/src/plugins/util/web.js +41 -12
- package/packages/dd-trace/src/profiling/config.js +8 -8
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/profiling/index.js +4 -4
- package/packages/dd-trace/src/profiling/profilers/{heap.js → space.js} +2 -2
- package/packages/dd-trace/src/profiling/profilers/{cpu.js → wall.js} +3 -3
- package/packages/dd-trace/src/proxy.js +2 -0
- package/packages/dd-trace/src/span_processor.js +4 -1
- package/packages/dd-trace/src/telemetry.js +187 -0
- package/scripts/install_plugin_modules.js +1 -0
- package/packages/datadog-plugin-fastify/src/fastify.js +0 -198
- package/packages/datadog-plugin-fastify/src/find-my-way.js +0 -37
- package/packages/datadog-plugin-jest/src/jest-environment.js +0 -272
- package/packages/datadog-plugin-jest/src/jest-jasmine2.js +0 -185
- package/packages/datadog-plugin-knex/src/index.js +0 -23
- package/packages/datadog-plugin-limitd-client/src/index.js +0 -30
- package/packages/dd-trace/src/exporters/agent/request.js +0 -86
- package/scripts/postpublish.js +0 -24
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const request = require('
|
|
3
|
+
const request = require('../common/request')
|
|
4
4
|
const { startupLog } = require('../../startup-log')
|
|
5
5
|
const metrics = require('../../metrics')
|
|
6
6
|
const log = require('../../log')
|
|
7
7
|
const tracerVersion = require('../../../lib/version')
|
|
8
|
+
const BaseWriter = require('../common/writer')
|
|
8
9
|
|
|
9
10
|
const METRIC_PREFIX = 'datadog.tracer.node.exporter.agent'
|
|
10
11
|
|
|
11
|
-
class Writer {
|
|
12
|
-
constructor ({
|
|
12
|
+
class Writer extends BaseWriter {
|
|
13
|
+
constructor ({ prioritySampler, lookup, protocolVersion }) {
|
|
14
|
+
super(...arguments)
|
|
13
15
|
const AgentEncoder = getEncoder(protocolVersion)
|
|
14
16
|
|
|
15
|
-
this._url = url
|
|
16
17
|
this._prioritySampler = prioritySampler
|
|
17
18
|
this._lookup = lookup
|
|
18
19
|
this._protocolVersion = protocolVersion
|
|
19
|
-
this.
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
append (spans) {
|
|
23
|
-
log.debug(() => `Encoding trace: ${JSON.stringify(spans)}`)
|
|
24
|
-
|
|
25
|
-
this._encode(spans)
|
|
20
|
+
this._encoder = new AgentEncoder(this)
|
|
26
21
|
}
|
|
27
22
|
|
|
28
23
|
_sendPayload (data, count, done) {
|
|
@@ -62,26 +57,6 @@ class Writer {
|
|
|
62
57
|
done()
|
|
63
58
|
})
|
|
64
59
|
}
|
|
65
|
-
|
|
66
|
-
setUrl (url) {
|
|
67
|
-
this._url = url
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
_encode (trace) {
|
|
71
|
-
this._encoderForVersion.encode(trace)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
flush (done = () => {}) {
|
|
75
|
-
const count = this._encoderForVersion.count()
|
|
76
|
-
|
|
77
|
-
if (count > 0) {
|
|
78
|
-
const payload = this._encoderForVersion.makePayload()
|
|
79
|
-
|
|
80
|
-
this._sendPayload(payload, count, done)
|
|
81
|
-
} else {
|
|
82
|
-
done()
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
60
|
}
|
|
86
61
|
|
|
87
62
|
function setHeader (headers, key, value) {
|
|
@@ -124,7 +99,7 @@ function makeRequest (version, data, count, url, lookup, needsStartupLog, cb) {
|
|
|
124
99
|
|
|
125
100
|
log.debug(() => `Request to the agent: ${JSON.stringify(options)}`)
|
|
126
101
|
|
|
127
|
-
request(
|
|
102
|
+
request(data, options, true, (err, res, status) => {
|
|
128
103
|
if (needsStartupLog) {
|
|
129
104
|
// Note that logging will only happen once, regardless of how many times this is called.
|
|
130
105
|
startupLog({
|
|
File without changes
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const http = require('http')
|
|
4
|
+
const https = require('https')
|
|
5
|
+
const log = require('../../log')
|
|
6
|
+
const docker = require('./docker')
|
|
7
|
+
const { storage } = require('../../../../datadog-core')
|
|
8
|
+
|
|
9
|
+
const httpAgent = new http.Agent({ keepAlive: true })
|
|
10
|
+
const httpsAgent = new https.Agent({ keepAlive: true })
|
|
11
|
+
const containerId = docker.id()
|
|
12
|
+
|
|
13
|
+
function request (data, options, keepAlive, callback) {
|
|
14
|
+
if (!options.headers) {
|
|
15
|
+
options.headers = {}
|
|
16
|
+
}
|
|
17
|
+
const isSecure = options.protocol === 'https:'
|
|
18
|
+
const client = isSecure ? https : http
|
|
19
|
+
const dataArray = [].concat(data)
|
|
20
|
+
options.headers['Content-Length'] = byteLength(dataArray)
|
|
21
|
+
|
|
22
|
+
if (containerId) {
|
|
23
|
+
options.headers['Datadog-Container-ID'] = containerId
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (keepAlive) {
|
|
27
|
+
options.agent = isSecure ? httpsAgent : httpAgent
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const firstRequest = retriableRequest(options, client, callback)
|
|
31
|
+
dataArray.forEach(buffer => firstRequest.write(buffer))
|
|
32
|
+
|
|
33
|
+
// The first request will be retried
|
|
34
|
+
const firstRequestErrorHandler = () => {
|
|
35
|
+
log.debug('Retrying request to the intake')
|
|
36
|
+
const retriedReq = retriableRequest(options, client, callback)
|
|
37
|
+
dataArray.forEach(buffer => retriedReq.write(buffer))
|
|
38
|
+
// The retried request will fail normally
|
|
39
|
+
retriedReq.on('error', e => callback(new Error(`Network error trying to reach the intake: ${e.message}`)))
|
|
40
|
+
retriedReq.end()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
firstRequest.on('error', firstRequestErrorHandler)
|
|
44
|
+
firstRequest.end()
|
|
45
|
+
|
|
46
|
+
return firstRequest
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function retriableRequest (options, client, callback) {
|
|
50
|
+
const store = storage.getStore()
|
|
51
|
+
|
|
52
|
+
storage.enterWith({ noop: true })
|
|
53
|
+
|
|
54
|
+
const timeout = options.timeout || 15000
|
|
55
|
+
|
|
56
|
+
const request = client.request(options, res => {
|
|
57
|
+
let responseData = ''
|
|
58
|
+
|
|
59
|
+
res.setTimeout(timeout)
|
|
60
|
+
|
|
61
|
+
res.on('data', chunk => { responseData += chunk })
|
|
62
|
+
res.on('end', () => {
|
|
63
|
+
if (res.statusCode >= 200 && res.statusCode <= 299) {
|
|
64
|
+
callback(null, responseData, res.statusCode)
|
|
65
|
+
} else {
|
|
66
|
+
const error = new Error(`Error from the endpoint: ${res.statusCode} ${http.STATUS_CODES[res.statusCode]}`)
|
|
67
|
+
error.status = res.statusCode
|
|
68
|
+
|
|
69
|
+
callback(error, null, res.statusCode)
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
request.setTimeout(timeout, request.abort)
|
|
74
|
+
storage.enterWith(store)
|
|
75
|
+
|
|
76
|
+
return request
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function byteLength (data) {
|
|
80
|
+
return data.length > 0 ? data.reduce((prev, next) => prev + next.length, 0) : 0
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
module.exports = request
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const log = require('../../log')
|
|
3
|
+
|
|
4
|
+
class Writer {
|
|
5
|
+
constructor ({ url }) {
|
|
6
|
+
this._url = url
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
flush (done = () => {}) {
|
|
10
|
+
const count = this._encoder.count()
|
|
11
|
+
|
|
12
|
+
if (count > 0) {
|
|
13
|
+
const payload = this._encoder.makePayload()
|
|
14
|
+
|
|
15
|
+
this._sendPayload(payload, count, done)
|
|
16
|
+
} else {
|
|
17
|
+
done()
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
append (spans) {
|
|
22
|
+
log.debug(() => `Encoding trace: ${JSON.stringify(spans)}`)
|
|
23
|
+
|
|
24
|
+
this._encode(spans)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
_encode (trace) {
|
|
28
|
+
this._encoder.encode(trace)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
setUrl (url) {
|
|
32
|
+
this._url = url
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = Writer
|
|
File without changes
|
|
@@ -22,7 +22,6 @@ const map = {
|
|
|
22
22
|
function format (span) {
|
|
23
23
|
const formatted = formatSpan(span)
|
|
24
24
|
|
|
25
|
-
extractError(formatted, span)
|
|
26
25
|
extractRootTags(formatted, span)
|
|
27
26
|
extractChunkTags(formatted, span)
|
|
28
27
|
extractTags(formatted, span)
|
|
@@ -74,8 +73,8 @@ function extractTags (trace, span) {
|
|
|
74
73
|
addTag({}, trace.metrics, tag, tags[tag] === undefined || tags[tag] ? 1 : 0)
|
|
75
74
|
break
|
|
76
75
|
case 'error':
|
|
77
|
-
if (
|
|
78
|
-
trace
|
|
76
|
+
if (context._name !== 'fs.operation') {
|
|
77
|
+
extractError(trace, tags[tag])
|
|
79
78
|
}
|
|
80
79
|
break
|
|
81
80
|
case 'error.type':
|
|
@@ -84,6 +83,8 @@ function extractTags (trace, span) {
|
|
|
84
83
|
// HACK: remove when implemented in the backend
|
|
85
84
|
if (context._name !== 'fs.operation') {
|
|
86
85
|
trace.error = 1
|
|
86
|
+
} else {
|
|
87
|
+
break
|
|
87
88
|
}
|
|
88
89
|
default: // eslint-disable-line no-fallthrough
|
|
89
90
|
addTag(trace.meta, trace.metrics, tag, tags[tag])
|
|
@@ -122,8 +123,11 @@ function extractChunkTags (trace, span) {
|
|
|
122
123
|
}
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
function extractError (trace,
|
|
126
|
-
|
|
126
|
+
function extractError (trace, error) {
|
|
127
|
+
if (!error) return
|
|
128
|
+
|
|
129
|
+
trace.error = 1
|
|
130
|
+
|
|
127
131
|
if (isError(error)) {
|
|
128
132
|
addTag(trace.meta, trace.metrics, 'error.msg', error.message)
|
|
129
133
|
addTag(trace.meta, trace.metrics, 'error.type', error.name)
|
|
@@ -7,6 +7,7 @@ const Loader = require('./loader')
|
|
|
7
7
|
const { isTrue } = require('./util')
|
|
8
8
|
const plugins = require('./plugins')
|
|
9
9
|
const Plugin = require('./plugins/plugin')
|
|
10
|
+
const telemetry = require('./telemetry')
|
|
10
11
|
|
|
11
12
|
const disabledPlugins = process.env.DD_TRACE_DISABLED_PLUGINS
|
|
12
13
|
|
|
@@ -54,6 +55,7 @@ class Instrumenter {
|
|
|
54
55
|
|
|
55
56
|
try {
|
|
56
57
|
this._set(plugin, { name, config })
|
|
58
|
+
telemetry.updateIntegrations()
|
|
57
59
|
} catch (e) {
|
|
58
60
|
log.debug(`Could not find a plugin named "${name}".`)
|
|
59
61
|
}
|
|
@@ -154,6 +156,7 @@ class Instrumenter {
|
|
|
154
156
|
|
|
155
157
|
if (!instrumented) {
|
|
156
158
|
this._instrumented.set(instrumentation, instrumented = new Set())
|
|
159
|
+
telemetry.updateIntegrations()
|
|
157
160
|
}
|
|
158
161
|
|
|
159
162
|
if (!instrumented.has(this._defaultExport(moduleExports))) {
|
|
@@ -11,7 +11,14 @@ function findRoot () {
|
|
|
11
11
|
|
|
12
12
|
function findPkg () {
|
|
13
13
|
const cwd = findRoot()
|
|
14
|
-
const
|
|
14
|
+
const directory = path.resolve(cwd)
|
|
15
|
+
const res = path.parse(directory)
|
|
16
|
+
|
|
17
|
+
if (!res) return {}
|
|
18
|
+
|
|
19
|
+
const { root } = res
|
|
20
|
+
|
|
21
|
+
const filePath = findUp('package.json', root, directory)
|
|
15
22
|
|
|
16
23
|
try {
|
|
17
24
|
return JSON.parse(fs.readFileSync(filePath, 'utf8'))
|
|
@@ -20,18 +27,16 @@ function findPkg () {
|
|
|
20
27
|
}
|
|
21
28
|
}
|
|
22
29
|
|
|
23
|
-
function findUp (name,
|
|
24
|
-
let directory = path.resolve(cwd)
|
|
25
|
-
const { root } = path.parse(directory)
|
|
26
|
-
|
|
30
|
+
function findUp (name, root, directory) {
|
|
27
31
|
while (true) {
|
|
28
32
|
const current = path.resolve(directory, name)
|
|
29
33
|
|
|
30
34
|
if (fs.existsSync(current)) return current
|
|
35
|
+
|
|
31
36
|
if (directory === root) return
|
|
32
37
|
|
|
33
38
|
directory = path.dirname(directory)
|
|
34
39
|
}
|
|
35
40
|
}
|
|
36
41
|
|
|
37
|
-
module.exports = findPkg()
|
|
42
|
+
module.exports = Object.assign(findPkg(), { findRoot, findUp })
|
|
@@ -27,9 +27,11 @@ function getConfig (name, config = {}) {
|
|
|
27
27
|
module.exports = class PluginManager {
|
|
28
28
|
constructor (tracer) {
|
|
29
29
|
this._pluginsByName = {}
|
|
30
|
+
this._configsByName = {}
|
|
30
31
|
for (const PluginClass of Object.values(plugins)) {
|
|
31
32
|
if (typeof PluginClass !== 'function') continue
|
|
32
33
|
this._pluginsByName[PluginClass.name] = new PluginClass(tracer)
|
|
34
|
+
this._configsByName[PluginClass.name] = {}
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
|
|
@@ -40,25 +42,29 @@ module.exports = class PluginManager {
|
|
|
40
42
|
pluginConfig = { enabled: pluginConfig }
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
const config = {
|
|
46
|
+
...this._configsByName[name],
|
|
47
|
+
...pluginConfig
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
this._pluginsByName[name].configure(getConfig(name, config))
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
// like instrumenter.enable()
|
|
47
54
|
configure (config) {
|
|
48
|
-
const serviceMapping = config
|
|
55
|
+
const { logInjection, serviceMapping } = config
|
|
49
56
|
|
|
50
57
|
if (config.plugins !== false) {
|
|
51
58
|
for (const name in this._pluginsByName) {
|
|
52
|
-
const pluginConfig = {
|
|
59
|
+
const pluginConfig = {
|
|
60
|
+
...this._configsByName[name],
|
|
61
|
+
logInjection
|
|
62
|
+
}
|
|
53
63
|
if (serviceMapping && serviceMapping[name]) {
|
|
54
64
|
pluginConfig.service = serviceMapping[name]
|
|
55
65
|
}
|
|
56
66
|
this.configurePlugin(name, pluginConfig)
|
|
57
67
|
}
|
|
58
|
-
} else {
|
|
59
|
-
for (const name in this._pluginsByName) {
|
|
60
|
-
this.configurePlugin(name, false)
|
|
61
|
-
}
|
|
62
68
|
}
|
|
63
69
|
}
|
|
64
70
|
|
|
@@ -14,6 +14,7 @@ module.exports = {
|
|
|
14
14
|
'elasticsearch': require('../../../datadog-plugin-elasticsearch/src'),
|
|
15
15
|
'express': require('../../../datadog-plugin-express/src'),
|
|
16
16
|
'fastify': require('../../../datadog-plugin-fastify/src'),
|
|
17
|
+
'find-my-way': require('../../../datadog-plugin-find-my-way/src'),
|
|
17
18
|
'fs': require('../../../datadog-plugin-fs/src'),
|
|
18
19
|
'google-cloud-pubsub': require('../../../datadog-plugin-google-cloud-pubsub/src'),
|
|
19
20
|
'graphql': require('../../../datadog-plugin-graphql/src'),
|
|
@@ -23,10 +24,8 @@ module.exports = {
|
|
|
23
24
|
'http2': require('../../../datadog-plugin-http2/src'),
|
|
24
25
|
'ioredis': require('../../../datadog-plugin-ioredis/src'),
|
|
25
26
|
'jest': require('../../../datadog-plugin-jest/src'),
|
|
26
|
-
'knex': require('../../../datadog-plugin-knex/src'),
|
|
27
27
|
'koa': require('../../../datadog-plugin-koa/src'),
|
|
28
28
|
'kafkajs': require('../../../datadog-plugin-kafkajs/src'),
|
|
29
|
-
'limitd-client': require('../../../datadog-plugin-limitd-client/src'),
|
|
30
29
|
'memcached': require('../../../datadog-plugin-memcached/src'),
|
|
31
30
|
'microgateway-core': require('../../../datadog-plugin-microgateway-core/src'),
|
|
32
31
|
'mocha': require('../../../datadog-plugin-mocha/src'),
|
|
@@ -31,11 +31,8 @@ function messageProxy (message, holder) {
|
|
|
31
31
|
module.exports = class LogPlugin extends Plugin {
|
|
32
32
|
constructor (...args) {
|
|
33
33
|
super(...args)
|
|
34
|
-
this.addSub(`apm:${this.constructor.name}:log`, (arg) => {
|
|
35
|
-
// TODO rather than checking this every time, setting it ought to enable/disable any plugin
|
|
36
|
-
// extending from this one
|
|
37
|
-
if (!this.tracer._logInjection) return
|
|
38
34
|
|
|
35
|
+
this.addSub(`apm:${this.constructor.name}:log`, (arg) => {
|
|
39
36
|
const store = storage.getStore()
|
|
40
37
|
const span = store && store.span
|
|
41
38
|
|
|
@@ -46,4 +43,11 @@ module.exports = class LogPlugin extends Plugin {
|
|
|
46
43
|
arg.message = messageProxy(arg.message, holder)
|
|
47
44
|
})
|
|
48
45
|
}
|
|
46
|
+
|
|
47
|
+
configure (config) {
|
|
48
|
+
return super.configure({
|
|
49
|
+
...config,
|
|
50
|
+
enabled: config.enabled && config.logInjection
|
|
51
|
+
})
|
|
52
|
+
}
|
|
49
53
|
}
|
|
@@ -56,6 +56,14 @@ module.exports = class Plugin {
|
|
|
56
56
|
this._subscriptions.push(new Subscription(channelName, handler))
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
addError (error) {
|
|
60
|
+
const store = storage.getStore()
|
|
61
|
+
|
|
62
|
+
if (!store || !store.span) return
|
|
63
|
+
|
|
64
|
+
store.span.setTag('error', error)
|
|
65
|
+
}
|
|
66
|
+
|
|
59
67
|
configure (config) {
|
|
60
68
|
if (typeof config === 'boolean') {
|
|
61
69
|
config = { enabled: config }
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
|
|
4
|
+
const ignore = require('ignore')
|
|
2
5
|
|
|
3
6
|
const { getGitMetadata } = require('./git')
|
|
4
7
|
const { getUserProviderGitMetadata } = require('./user-provided-git')
|
|
@@ -16,6 +19,10 @@ const {
|
|
|
16
19
|
} = require('./tags')
|
|
17
20
|
const id = require('../../id')
|
|
18
21
|
|
|
22
|
+
const { SPAN_TYPE, RESOURCE_NAME, SAMPLING_PRIORITY } = require('../../../../../ext/tags')
|
|
23
|
+
const { SAMPLING_RULE_DECISION } = require('../../constants')
|
|
24
|
+
const { AUTO_KEEP } = require('../../../../../ext/priority')
|
|
25
|
+
|
|
19
26
|
const TEST_FRAMEWORK = 'test.framework'
|
|
20
27
|
const TEST_FRAMEWORK_VERSION = 'test.framework_version'
|
|
21
28
|
const TEST_TYPE = 'test.type'
|
|
@@ -25,6 +32,7 @@ const TEST_STATUS = 'test.status'
|
|
|
25
32
|
const TEST_PARAMETERS = 'test.parameters'
|
|
26
33
|
const TEST_SKIP_REASON = 'test.skip_reason'
|
|
27
34
|
const TEST_IS_RUM_ACTIVE = 'test.is_rum_active'
|
|
35
|
+
const TEST_CODE_OWNERS = 'test.codeowners'
|
|
28
36
|
|
|
29
37
|
const ERROR_TYPE = 'error.type'
|
|
30
38
|
const ERROR_MESSAGE = 'error.msg'
|
|
@@ -35,6 +43,7 @@ const CI_APP_ORIGIN = 'ciapp-test'
|
|
|
35
43
|
const JEST_TEST_RUNNER = 'test.jest.test_runner'
|
|
36
44
|
|
|
37
45
|
module.exports = {
|
|
46
|
+
TEST_CODE_OWNERS,
|
|
38
47
|
TEST_FRAMEWORK,
|
|
39
48
|
TEST_FRAMEWORK_VERSION,
|
|
40
49
|
JEST_TEST_RUNNER,
|
|
@@ -53,7 +62,10 @@ module.exports = {
|
|
|
53
62
|
getTestParametersString,
|
|
54
63
|
finishAllTraceSpans,
|
|
55
64
|
getTestParentSpan,
|
|
56
|
-
getTestSuitePath
|
|
65
|
+
getTestSuitePath,
|
|
66
|
+
getCodeOwnersFileEntries,
|
|
67
|
+
getCodeOwnersForFilename,
|
|
68
|
+
getTestCommonTags
|
|
57
69
|
}
|
|
58
70
|
|
|
59
71
|
function getTestEnvironmentMetadata (testFramework, config) {
|
|
@@ -127,6 +139,20 @@ function getTestParentSpan (tracer) {
|
|
|
127
139
|
'x-datadog-parent-id': '0000000000000000'
|
|
128
140
|
})
|
|
129
141
|
}
|
|
142
|
+
|
|
143
|
+
function getTestCommonTags (name, suite, version) {
|
|
144
|
+
return {
|
|
145
|
+
[SPAN_TYPE]: 'test',
|
|
146
|
+
[TEST_TYPE]: 'test',
|
|
147
|
+
[SAMPLING_RULE_DECISION]: 1,
|
|
148
|
+
[SAMPLING_PRIORITY]: AUTO_KEEP,
|
|
149
|
+
[TEST_NAME]: name,
|
|
150
|
+
[TEST_SUITE]: suite,
|
|
151
|
+
[RESOURCE_NAME]: `${suite}.${name}`,
|
|
152
|
+
[TEST_FRAMEWORK_VERSION]: version
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
130
156
|
/**
|
|
131
157
|
* We want to make sure that test suites are reported the same way for
|
|
132
158
|
* every OS, so we replace `path.sep` by `/`
|
|
@@ -140,3 +166,55 @@ function getTestSuitePath (testSuiteAbsolutePath, sourceRoot) {
|
|
|
140
166
|
|
|
141
167
|
return testSuitePath.replace(path.sep, '/')
|
|
142
168
|
}
|
|
169
|
+
|
|
170
|
+
const POSSIBLE_CODEOWNERS_LOCATIONS = [
|
|
171
|
+
'CODEOWNERS',
|
|
172
|
+
'.github/CODEOWNERS',
|
|
173
|
+
'docs/CODEOWNERS',
|
|
174
|
+
'.gitlab/CODEOWNERS'
|
|
175
|
+
]
|
|
176
|
+
|
|
177
|
+
function getCodeOwnersFileEntries (rootDir = process.cwd()) {
|
|
178
|
+
let codeOwnersContent
|
|
179
|
+
|
|
180
|
+
POSSIBLE_CODEOWNERS_LOCATIONS.forEach(location => {
|
|
181
|
+
try {
|
|
182
|
+
codeOwnersContent = fs.readFileSync(`${rootDir}/${location}`).toString()
|
|
183
|
+
} catch (e) {
|
|
184
|
+
// retry with next path
|
|
185
|
+
}
|
|
186
|
+
})
|
|
187
|
+
if (!codeOwnersContent) {
|
|
188
|
+
return null
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const entries = []
|
|
192
|
+
const lines = codeOwnersContent.split('\n')
|
|
193
|
+
|
|
194
|
+
for (const line of lines) {
|
|
195
|
+
const [content] = line.split('#')
|
|
196
|
+
const trimmed = content.trim()
|
|
197
|
+
if (trimmed === '') continue
|
|
198
|
+
const [pattern, ...owners] = trimmed.split(/\s+/)
|
|
199
|
+
entries.push({ pattern, owners })
|
|
200
|
+
}
|
|
201
|
+
// Reverse because rules defined last take precedence
|
|
202
|
+
return entries.reverse()
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function getCodeOwnersForFilename (filename, entries) {
|
|
206
|
+
if (!entries) {
|
|
207
|
+
return null
|
|
208
|
+
}
|
|
209
|
+
for (const entry of entries) {
|
|
210
|
+
try {
|
|
211
|
+
const isResponsible = ignore().add(entry.pattern).ignores(filename)
|
|
212
|
+
if (isResponsible) {
|
|
213
|
+
return JSON.stringify(entry.owners)
|
|
214
|
+
}
|
|
215
|
+
} catch (e) {
|
|
216
|
+
return null
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return null
|
|
220
|
+
}
|
|
@@ -52,10 +52,38 @@ const web = {
|
|
|
52
52
|
})
|
|
53
53
|
},
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
setFramework (req, name, config) {
|
|
56
56
|
const context = this.patch(req)
|
|
57
|
+
const span = context.span
|
|
58
|
+
|
|
59
|
+
if (!span) return
|
|
60
|
+
|
|
61
|
+
span.context()._name = `${name}.request`
|
|
62
|
+
|
|
63
|
+
web.setConfig(req, config)
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
setConfig (req, config) {
|
|
67
|
+
const context = contexts.get(req)
|
|
68
|
+
const span = context.span
|
|
69
|
+
|
|
57
70
|
context.config = config
|
|
58
71
|
|
|
72
|
+
if (!config.filter(req.url)) {
|
|
73
|
+
span.setTag(MANUAL_DROP, true)
|
|
74
|
+
span.context()._trace.isRecording = false
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (config.service) {
|
|
78
|
+
span.setTag(SERVICE_NAME, config.service)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
analyticsSampler.sample(span, config.measured, true)
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
startSpan (tracer, config, req, res, name) {
|
|
85
|
+
const context = this.patch(req)
|
|
86
|
+
|
|
59
87
|
let span
|
|
60
88
|
|
|
61
89
|
if (context.span) {
|
|
@@ -69,6 +97,8 @@ const web = {
|
|
|
69
97
|
context.span = span
|
|
70
98
|
context.res = res
|
|
71
99
|
|
|
100
|
+
this.setConfig(req, config)
|
|
101
|
+
|
|
72
102
|
return span
|
|
73
103
|
},
|
|
74
104
|
wrap (req) {
|
|
@@ -83,16 +113,6 @@ const web = {
|
|
|
83
113
|
instrument (tracer, config, req, res, name, callback) {
|
|
84
114
|
const span = this.startSpan(tracer, config, req, res, name)
|
|
85
115
|
|
|
86
|
-
if (!config.filter(req.url)) {
|
|
87
|
-
span.setTag(MANUAL_DROP, true)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (config.service) {
|
|
91
|
-
span.setTag(SERVICE_NAME, config.service)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
analyticsSampler.sample(span, config.measured, true)
|
|
95
|
-
|
|
96
116
|
this.wrap(req)
|
|
97
117
|
|
|
98
118
|
return callback && tracer.scope().activate(span, () => callback(span))
|
|
@@ -110,6 +130,14 @@ const web = {
|
|
|
110
130
|
}
|
|
111
131
|
},
|
|
112
132
|
|
|
133
|
+
setRoute (req, path) {
|
|
134
|
+
const context = contexts.get(req)
|
|
135
|
+
|
|
136
|
+
if (!context) return
|
|
137
|
+
|
|
138
|
+
context.paths = [path]
|
|
139
|
+
},
|
|
140
|
+
|
|
113
141
|
// Remove the current route segment.
|
|
114
142
|
exitRoute (req) {
|
|
115
143
|
contexts.get(req).paths.pop()
|
|
@@ -231,8 +259,9 @@ const web = {
|
|
|
231
259
|
const context = contexts.get(req)
|
|
232
260
|
const span = context.span
|
|
233
261
|
const error = context.error
|
|
262
|
+
const hasMiddlewareError = span.context()._tags['error'] || span.context()._tags['error.msg']
|
|
234
263
|
|
|
235
|
-
if (!context.config.validateStatus(statusCode)) {
|
|
264
|
+
if (!hasMiddlewareError && !context.config.validateStatus(statusCode)) {
|
|
236
265
|
span.setTag(ERROR, error || true)
|
|
237
266
|
}
|
|
238
267
|
},
|
|
@@ -6,8 +6,8 @@ const { URL } = require('url')
|
|
|
6
6
|
const { AgentExporter } = require('./exporters/agent')
|
|
7
7
|
const { FileExporter } = require('./exporters/file')
|
|
8
8
|
const { ConsoleLogger } = require('./loggers/console')
|
|
9
|
-
const
|
|
10
|
-
const
|
|
9
|
+
const WallProfiler = require('./profilers/wall')
|
|
10
|
+
const SpaceProfiler = require('./profilers/space')
|
|
11
11
|
const { tagger } = require('./tagger')
|
|
12
12
|
|
|
13
13
|
const {
|
|
@@ -64,8 +64,8 @@ class Config {
|
|
|
64
64
|
], this)
|
|
65
65
|
|
|
66
66
|
const profilers = coalesce(options.profilers, DD_PROFILING_PROFILERS, [
|
|
67
|
-
new
|
|
68
|
-
new
|
|
67
|
+
new WallProfiler(),
|
|
68
|
+
new SpaceProfiler()
|
|
69
69
|
])
|
|
70
70
|
|
|
71
71
|
this.profilers = ensureProfilers(profilers, this)
|
|
@@ -100,10 +100,10 @@ function ensureExporters (exporters, options) {
|
|
|
100
100
|
|
|
101
101
|
function getProfiler (name, options) {
|
|
102
102
|
switch (name) {
|
|
103
|
-
case '
|
|
104
|
-
return new
|
|
105
|
-
case '
|
|
106
|
-
return new
|
|
103
|
+
case 'wall':
|
|
104
|
+
return new WallProfiler(options)
|
|
105
|
+
case 'space':
|
|
106
|
+
return new SpaceProfiler(options)
|
|
107
107
|
default:
|
|
108
108
|
options.logger.error(`Unknown profiler "${name}"`)
|
|
109
109
|
}
|
|
@@ -5,7 +5,7 @@ const { request } = require('http')
|
|
|
5
5
|
const FormData = require('form-data')
|
|
6
6
|
|
|
7
7
|
// TODO: avoid using dd-trace internals. Make this a separate module?
|
|
8
|
-
const docker = require('../../exporters/
|
|
8
|
+
const docker = require('../../exporters/common/docker')
|
|
9
9
|
const version = require('../../../lib/version')
|
|
10
10
|
|
|
11
11
|
const containerId = docker.id()
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { Profiler } = require('./profiler')
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const WallProfiler = require('./profilers/wall')
|
|
5
|
+
const SpaceProfiler = require('./profilers/space')
|
|
6
6
|
const { AgentExporter } = require('./exporters/agent')
|
|
7
7
|
const { FileExporter } = require('./exporters/file')
|
|
8
8
|
const { ConsoleLogger } = require('./loggers/console')
|
|
@@ -13,7 +13,7 @@ module.exports = {
|
|
|
13
13
|
profiler,
|
|
14
14
|
AgentExporter,
|
|
15
15
|
FileExporter,
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
WallProfiler,
|
|
17
|
+
SpaceProfiler,
|
|
18
18
|
ConsoleLogger
|
|
19
19
|
}
|