dd-trace 4.0.0 → 4.1.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/LICENSE-3rdparty.csv +1 -0
- package/MIGRATING.md +39 -0
- package/README.md +18 -11
- package/package.json +3 -2
- package/packages/datadog-esbuild/index.js +13 -1
- package/packages/datadog-instrumentations/src/cucumber.js +13 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/http/client.js +2 -1
- package/packages/datadog-instrumentations/src/http/server.js +14 -0
- package/packages/datadog-instrumentations/src/http2/client.js +4 -0
- package/packages/datadog-instrumentations/src/jest.js +2 -3
- package/packages/datadog-instrumentations/src/next.js +2 -2
- package/packages/datadog-instrumentations/src/pg.js +14 -11
- package/packages/datadog-instrumentations/src/playwright.js +1 -1
- package/packages/datadog-instrumentations/src/sequelize.js +51 -0
- package/packages/datadog-plugin-amqp10/src/consumer.js +1 -3
- package/packages/datadog-plugin-amqp10/src/producer.js +1 -3
- package/packages/datadog-plugin-amqplib/src/client.js +4 -3
- package/packages/datadog-plugin-amqplib/src/consumer.js +1 -3
- package/packages/datadog-plugin-amqplib/src/producer.js +1 -3
- package/packages/datadog-plugin-cucumber/src/index.js +2 -2
- package/packages/datadog-plugin-cypress/src/plugin.js +150 -30
- package/packages/datadog-plugin-cypress/src/support.js +6 -3
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +4 -3
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -3
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +1 -3
- package/packages/datadog-plugin-http/src/client.js +70 -68
- package/packages/datadog-plugin-http2/src/client.js +50 -47
- package/packages/datadog-plugin-jest/src/index.js +5 -4
- package/packages/datadog-plugin-kafkajs/src/consumer.js +1 -4
- package/packages/datadog-plugin-kafkajs/src/producer.js +1 -3
- package/packages/datadog-plugin-memcached/src/index.js +2 -3
- package/packages/datadog-plugin-mocha/src/index.js +4 -2
- package/packages/datadog-plugin-pg/src/index.js +1 -1
- package/packages/datadog-plugin-redis/src/index.js +2 -13
- package/packages/datadog-plugin-rhea/src/consumer.js +1 -3
- package/packages/datadog-plugin-rhea/src/producer.js +1 -5
- package/packages/datadog-plugin-router/src/index.js +12 -1
- package/packages/dd-trace/src/appsec/blocked_templates.js +2 -101
- package/packages/dd-trace/src/appsec/blocking.js +60 -11
- package/packages/dd-trace/src/appsec/channels.js +3 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +7 -5
- package/packages/dd-trace/src/appsec/iast/analyzers/index.js +3 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/insecure-cookie-analyzer.js +31 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +4 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/set-cookies-header-interceptor.js +47 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +30 -5
- package/packages/dd-trace/src/appsec/iast/analyzers/ssrf-analyzer.js +26 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +35 -3
- package/packages/dd-trace/src/appsec/iast/path-line.js +14 -7
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +19 -4
- package/packages/dd-trace/src/appsec/iast/telemetry/logs.js +1 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +25 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +49 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +3 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +7 -5
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +0 -33
- package/packages/dd-trace/src/appsec/recommended.json +45 -46
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +3 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +4 -0
- package/packages/dd-trace/src/appsec/rule_manager.js +49 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +2 -7
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +1 -6
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +10 -4
- package/packages/dd-trace/src/config.js +36 -5
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +11 -3
- package/packages/dd-trace/src/exporters/common/util.js +9 -0
- package/packages/dd-trace/src/exporters/common/writer.js +3 -2
- package/packages/dd-trace/src/plugin_manager.js +2 -0
- package/packages/dd-trace/src/plugins/cache.js +7 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +2 -0
- package/packages/dd-trace/src/plugins/client.js +3 -2
- package/packages/dd-trace/src/plugins/consumer.js +14 -2
- package/packages/dd-trace/src/plugins/database.js +2 -2
- package/packages/dd-trace/src/plugins/inbound.js +7 -0
- package/packages/dd-trace/src/plugins/{outgoing.js → outbound.js} +2 -2
- package/packages/dd-trace/src/plugins/producer.js +19 -2
- package/packages/dd-trace/src/plugins/server.js +2 -2
- package/packages/dd-trace/src/plugins/storage.js +2 -0
- package/packages/dd-trace/src/plugins/tracing.js +11 -0
- package/packages/dd-trace/src/plugins/util/ci.js +1 -1
- package/packages/dd-trace/src/profiling/config.js +4 -2
- package/packages/dd-trace/src/service-naming/index.js +30 -0
- package/packages/dd-trace/src/service-naming/schemas/definition.js +24 -0
- package/packages/dd-trace/src/service-naming/schemas/index.js +6 -0
- package/packages/dd-trace/src/service-naming/schemas/util.js +5 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/index.js +5 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +64 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +33 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/index.js +5 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +52 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +21 -0
- package/packages/dd-trace/src/telemetry/index.js +5 -6
- package/packages/dd-trace/src/telemetry/send-data.js +17 -5
- package/packages/dd-trace/src/tracer.js +3 -3
- package/version.js +8 -4
- package/packages/dd-trace/src/plugins/incoming.js +0 -7
|
@@ -36,6 +36,22 @@ function safeJsonParse (input) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
const namingVersions = ['v0', 'v1']
|
|
40
|
+
const defaultNamingVersion = 'v0'
|
|
41
|
+
|
|
42
|
+
function validateNamingVersion (versionString) {
|
|
43
|
+
if (!versionString) {
|
|
44
|
+
return defaultNamingVersion
|
|
45
|
+
}
|
|
46
|
+
if (!namingVersions.includes(versionString)) {
|
|
47
|
+
log.warn(
|
|
48
|
+
`Unexpected input for config.spanAttributeSchema, picked default ${defaultNamingVersion}`
|
|
49
|
+
)
|
|
50
|
+
return defaultNamingVersion
|
|
51
|
+
}
|
|
52
|
+
return versionString
|
|
53
|
+
}
|
|
54
|
+
|
|
39
55
|
// Shallow clone with property name remapping
|
|
40
56
|
function remapify (input, mappings) {
|
|
41
57
|
if (!input) return
|
|
@@ -200,8 +216,11 @@ class Config {
|
|
|
200
216
|
process.env.DD_TRACE_TELEMETRY_ENABLED,
|
|
201
217
|
!inServerlessEnvironment
|
|
202
218
|
)
|
|
203
|
-
const
|
|
204
|
-
process.env.
|
|
219
|
+
const DD_TELEMETRY_HEARTBEAT_INTERVAL = process.env.DD_TELEMETRY_HEARTBEAT_INTERVAL
|
|
220
|
+
? parseInt(process.env.DD_TELEMETRY_HEARTBEAT_INTERVAL) * 1000
|
|
221
|
+
: 60000
|
|
222
|
+
const DD_TELEMETRY_DEBUG = coalesce(
|
|
223
|
+
process.env.DD_TELEMETRY_DEBUG,
|
|
205
224
|
false
|
|
206
225
|
)
|
|
207
226
|
const DD_TRACE_AGENT_PROTOCOL_VERSION = coalesce(
|
|
@@ -273,7 +292,9 @@ class Config {
|
|
|
273
292
|
process.env.DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
|
|
274
293
|
false
|
|
275
294
|
)
|
|
276
|
-
|
|
295
|
+
const DD_TRACE_SPAN_ATTRIBUTE_SCHEMA = validateNamingVersion(
|
|
296
|
+
process.env.DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
|
|
297
|
+
)
|
|
277
298
|
const DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH = coalesce(
|
|
278
299
|
process.env.DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
|
|
279
300
|
'512'
|
|
@@ -489,13 +510,15 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
489
510
|
sourceMap: !isFalse(DD_PROFILING_SOURCE_MAP),
|
|
490
511
|
exporters: DD_PROFILING_EXPORTERS
|
|
491
512
|
}
|
|
513
|
+
this.spanAttributeSchema = DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
|
|
492
514
|
this.lookup = options.lookup
|
|
493
515
|
this.startupLogs = isTrue(DD_TRACE_STARTUP_LOGS)
|
|
494
516
|
// Disabled for CI Visibility's agentless
|
|
495
517
|
this.telemetry = {
|
|
496
518
|
enabled: DD_TRACE_EXPORTER !== 'datadog' && isTrue(DD_TRACE_TELEMETRY_ENABLED),
|
|
519
|
+
heartbeatInterval: DD_TELEMETRY_HEARTBEAT_INTERVAL,
|
|
497
520
|
logCollection: isTrue(DD_TELEMETRY_LOG_COLLECTION_ENABLED),
|
|
498
|
-
debug: isTrue(
|
|
521
|
+
debug: isTrue(DD_TELEMETRY_DEBUG)
|
|
499
522
|
}
|
|
500
523
|
this.protocolVersion = DD_TRACE_AGENT_PROTOCOL_VERSION
|
|
501
524
|
this.tagsHeaderMaxLength = parseInt(DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH)
|
|
@@ -545,7 +568,15 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
545
568
|
process.env.DD_GIT_PROPERTIES_FILE,
|
|
546
569
|
`${process.cwd()}/git.properties`
|
|
547
570
|
)
|
|
548
|
-
|
|
571
|
+
let gitPropertiesString
|
|
572
|
+
try {
|
|
573
|
+
gitPropertiesString = fs.readFileSync(DD_GIT_PROPERTIES_FILE, 'utf8')
|
|
574
|
+
} catch (e) {
|
|
575
|
+
// Only log error if the user has set a git.properties path
|
|
576
|
+
if (process.env.DD_GIT_PROPERTIES_FILE) {
|
|
577
|
+
log.error(e)
|
|
578
|
+
}
|
|
579
|
+
}
|
|
549
580
|
if (gitPropertiesString) {
|
|
550
581
|
const { commitSHA, repositoryUrl } = getGitMetadataFromGitProperties(gitPropertiesString)
|
|
551
582
|
this.commitSHA = this.commitSHA || commitSHA
|
|
@@ -26,11 +26,19 @@ class CoverageCIVisibilityEncoder extends AgentEncoder {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
encodeCodeCoverage (bytes, coverage) {
|
|
29
|
-
|
|
29
|
+
if (coverage.testId) {
|
|
30
|
+
this._encodeMapPrefix(bytes, 4)
|
|
31
|
+
} else {
|
|
32
|
+
this._encodeMapPrefix(bytes, 3)
|
|
33
|
+
}
|
|
30
34
|
this._encodeString(bytes, 'test_session_id')
|
|
31
|
-
this._encodeId(bytes, coverage.
|
|
35
|
+
this._encodeId(bytes, coverage.sessionId)
|
|
32
36
|
this._encodeString(bytes, 'test_suite_id')
|
|
33
|
-
this._encodeId(bytes, coverage.
|
|
37
|
+
this._encodeId(bytes, coverage.suiteId)
|
|
38
|
+
if (coverage.testId) {
|
|
39
|
+
this._encodeString(bytes, 'span_id')
|
|
40
|
+
this._encodeId(bytes, coverage.testId)
|
|
41
|
+
}
|
|
34
42
|
this._encodeString(bytes, 'files')
|
|
35
43
|
this._encodeArrayPrefix(bytes, coverage.files)
|
|
36
44
|
for (const filename of coverage.files) {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const request = require('./request')
|
|
4
4
|
const log = require('../../log')
|
|
5
|
+
const { safeJSONStringify } = require('./util')
|
|
5
6
|
|
|
6
7
|
class Writer {
|
|
7
8
|
constructor ({ url }) {
|
|
@@ -25,11 +26,11 @@ class Writer {
|
|
|
25
26
|
|
|
26
27
|
append (payload) {
|
|
27
28
|
if (!request.writable) {
|
|
28
|
-
log.debug(() => `Maximum number of active requests reached. Payload discarded: ${
|
|
29
|
+
log.debug(() => `Maximum number of active requests reached. Payload discarded: ${safeJSONStringify(payload)}`)
|
|
29
30
|
return
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
log.debug(() => `Encoding payload: ${
|
|
33
|
+
log.debug(() => `Encoding payload: ${safeJSONStringify(payload)}`)
|
|
33
34
|
|
|
34
35
|
this._encode(payload)
|
|
35
36
|
}
|
|
@@ -4,6 +4,7 @@ const { channel } = require('../../diagnostics_channel')
|
|
|
4
4
|
const { isFalse } = require('./util')
|
|
5
5
|
const plugins = require('./plugins')
|
|
6
6
|
const log = require('./log')
|
|
7
|
+
const Nomenclature = require('./service-naming')
|
|
7
8
|
|
|
8
9
|
const loadChannel = channel('dd-trace:instrumentation:load')
|
|
9
10
|
|
|
@@ -96,6 +97,7 @@ module.exports = class PluginManager {
|
|
|
96
97
|
// like instrumenter.enable()
|
|
97
98
|
configure (config = {}) {
|
|
98
99
|
this._tracerConfig = config
|
|
100
|
+
Nomenclature.configure(config)
|
|
99
101
|
|
|
100
102
|
for (const name in pluginClasses) {
|
|
101
103
|
this.loadPlugin(name)
|
|
@@ -4,6 +4,13 @@ const StoragePlugin = require('./storage')
|
|
|
4
4
|
|
|
5
5
|
class CachePlugin extends StoragePlugin {
|
|
6
6
|
static get operation () { return 'command' }
|
|
7
|
+
|
|
8
|
+
startSpan (options) {
|
|
9
|
+
if (!options.kind) {
|
|
10
|
+
options.kind = this.constructor.kind
|
|
11
|
+
}
|
|
12
|
+
return super.startSpan(this.operationName(), options)
|
|
13
|
+
}
|
|
7
14
|
}
|
|
8
15
|
|
|
9
16
|
module.exports = CachePlugin
|
|
@@ -22,6 +22,8 @@ module.exports = class CiPlugin extends Plugin {
|
|
|
22
22
|
constructor (...args) {
|
|
23
23
|
super(...args)
|
|
24
24
|
|
|
25
|
+
this.rootDir = process.cwd() // fallback in case :session:start events are not emitted
|
|
26
|
+
|
|
25
27
|
this.addSub(`ci:${this.constructor.id}:itr-configuration`, ({ onDone }) => {
|
|
26
28
|
if (!this.tracer._exporter || !this.tracer._exporter.getItrConfiguration) {
|
|
27
29
|
return onDone({ err: new Error('CI Visibility was not initialized correctly') })
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const OutboundPlugin = require('./outbound')
|
|
4
4
|
|
|
5
|
-
class ClientPlugin extends
|
|
5
|
+
class ClientPlugin extends OutboundPlugin {
|
|
6
6
|
static get operation () { return 'request' }
|
|
7
|
+
static get kind () { return 'client' }
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
module.exports = ClientPlugin
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const InboundPlugin = require('./inbound')
|
|
4
4
|
|
|
5
|
-
class ConsumerPlugin extends
|
|
5
|
+
class ConsumerPlugin extends InboundPlugin {
|
|
6
6
|
static get operation () { return 'receive' }
|
|
7
|
+
static get kind () { return 'consumer' }
|
|
8
|
+
static get type () { return 'messaging' }
|
|
9
|
+
|
|
10
|
+
startSpan (options) {
|
|
11
|
+
if (!options.service) {
|
|
12
|
+
options.service = this.config.service || this.serviceName()
|
|
13
|
+
}
|
|
14
|
+
if (!options.kind) {
|
|
15
|
+
options.kind = this.constructor.kind
|
|
16
|
+
}
|
|
17
|
+
return super.startSpan(this.operationName(), options)
|
|
18
|
+
}
|
|
7
19
|
}
|
|
8
20
|
|
|
9
21
|
module.exports = ConsumerPlugin
|
|
@@ -37,12 +37,12 @@ class DatabasePlugin extends StoragePlugin {
|
|
|
37
37
|
`ddps='${encodedDdps}',ddpv='${encodedDdpv}'`
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
injectDbmQuery (query, serviceName) {
|
|
40
|
+
injectDbmQuery (query, serviceName, isPreparedStatement = false) {
|
|
41
41
|
if (this.config.dbmPropagationMode === 'disabled') {
|
|
42
42
|
return query
|
|
43
43
|
}
|
|
44
44
|
const servicePropagation = this.createDBMPropagationCommentService(serviceName)
|
|
45
|
-
if (this.config.dbmPropagationMode === 'service') {
|
|
45
|
+
if (isPreparedStatement || this.config.dbmPropagationMode === 'service') {
|
|
46
46
|
return `/*${servicePropagation}*/ ${query}`
|
|
47
47
|
} else if (this.config.dbmPropagationMode === 'full') {
|
|
48
48
|
this.activeSpan.setTag('_dd.dbm_trace_injected', 'true')
|
|
@@ -4,7 +4,7 @@ const { CLIENT_PORT_KEY } = require('../constants')
|
|
|
4
4
|
const TracingPlugin = require('./tracing')
|
|
5
5
|
|
|
6
6
|
// TODO: Exit span on finish when AsyncResource instances are removed.
|
|
7
|
-
class
|
|
7
|
+
class OutboundPlugin extends TracingPlugin {
|
|
8
8
|
constructor (...args) {
|
|
9
9
|
super(...args)
|
|
10
10
|
|
|
@@ -29,4 +29,4 @@ class OutgoingPlugin extends TracingPlugin {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
module.exports =
|
|
32
|
+
module.exports = OutboundPlugin
|
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const OutboundPlugin = require('./outbound')
|
|
4
4
|
|
|
5
|
-
class ProducerPlugin extends
|
|
5
|
+
class ProducerPlugin extends OutboundPlugin {
|
|
6
6
|
static get operation () { return 'publish' }
|
|
7
|
+
static get kind () { return 'producer' }
|
|
8
|
+
static get type () { return 'messaging' }
|
|
9
|
+
|
|
10
|
+
startSpan (options) {
|
|
11
|
+
const spanDefaults = {
|
|
12
|
+
kind: this.constructor.kind
|
|
13
|
+
}
|
|
14
|
+
if (!options.service) {
|
|
15
|
+
options.service = this.config.service || this.serviceName()
|
|
16
|
+
}
|
|
17
|
+
Object.keys(spanDefaults).forEach(
|
|
18
|
+
key => {
|
|
19
|
+
if (!options[key]) options[key] = spanDefaults[key]
|
|
20
|
+
}
|
|
21
|
+
)
|
|
22
|
+
return super.startSpan(this.operationName(), options)
|
|
23
|
+
}
|
|
7
24
|
}
|
|
8
25
|
|
|
9
26
|
module.exports = ProducerPlugin
|
|
@@ -4,6 +4,7 @@ const Plugin = require('./plugin')
|
|
|
4
4
|
const { storage } = require('../../../datadog-core')
|
|
5
5
|
const analyticsSampler = require('../analytics_sampler')
|
|
6
6
|
const { COMPONENT } = require('../constants')
|
|
7
|
+
const Nomenclature = require('../service-naming')
|
|
7
8
|
|
|
8
9
|
class TracingPlugin extends Plugin {
|
|
9
10
|
constructor (...args) {
|
|
@@ -31,6 +32,16 @@ class TracingPlugin extends Plugin {
|
|
|
31
32
|
return store && store.span
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
serviceName (...serviceArgs) {
|
|
36
|
+
const { type, id, kind } = this.constructor
|
|
37
|
+
return Nomenclature.serviceName(type, kind, id, ...serviceArgs)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
operationName (...opNameArgs) {
|
|
41
|
+
const { type, id, kind } = this.constructor
|
|
42
|
+
return Nomenclature.opName(type, kind, id, ...opNameArgs)
|
|
43
|
+
}
|
|
44
|
+
|
|
34
45
|
configure (config) {
|
|
35
46
|
return super.configure({
|
|
36
47
|
...config,
|
|
@@ -192,7 +192,7 @@ module.exports = {
|
|
|
192
192
|
[GIT_TAG]: CI_COMMIT_TAG,
|
|
193
193
|
[GIT_BRANCH]: CI_COMMIT_REF_NAME,
|
|
194
194
|
[CI_WORKSPACE_PATH]: CI_PROJECT_DIR,
|
|
195
|
-
[CI_PIPELINE_URL]: GITLAB_PIPELINE_URL
|
|
195
|
+
[CI_PIPELINE_URL]: GITLAB_PIPELINE_URL,
|
|
196
196
|
[CI_STAGE_NAME]: CI_JOB_STAGE,
|
|
197
197
|
[CI_JOB_NAME]: GITLAB_CI_JOB_NAME,
|
|
198
198
|
[GIT_COMMIT_MESSAGE]: CI_COMMIT_MESSAGE,
|
|
@@ -91,8 +91,10 @@ class Config {
|
|
|
91
91
|
Number(DD_PROFILING_EXPERIMENTAL_OOM_HEAP_LIMIT_EXTENSION_SIZE), 0)
|
|
92
92
|
const maxHeapExtensionCount = coalesce(options.oomMaxHeapExtensionCount,
|
|
93
93
|
Number(DD_PROFILING_EXPERIMENTAL_OOM_MAX_HEAP_EXTENSION_COUNT), 0)
|
|
94
|
-
const exportStrategies =
|
|
95
|
-
DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES
|
|
94
|
+
const exportStrategies = oomMonitoringEnabled
|
|
95
|
+
? ensureOOMExportStrategies(coalesce(options.oomExportStrategies, DD_PROFILING_EXPERIMENTAL_OOM_EXPORT_STRATEGIES,
|
|
96
|
+
[oomExportStrategies.PROCESS]), this)
|
|
97
|
+
: []
|
|
96
98
|
const exportCommand = oomMonitoringEnabled ? buildExportCommand(this) : undefined
|
|
97
99
|
this.oomMonitoring = {
|
|
98
100
|
enabled: oomMonitoringEnabled,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const { schemaDefinitions } = require('./schemas')
|
|
2
|
+
|
|
3
|
+
class SchemaManager {
|
|
4
|
+
constructor () {
|
|
5
|
+
this.schemas = schemaDefinitions
|
|
6
|
+
this.config = { spanAttributeSchema: 'v0' }
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
get schema () {
|
|
10
|
+
return this.schemas[this.version]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
get version () {
|
|
14
|
+
return this.config.spanAttributeSchema
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
opName (type, kind, plugin, ...opNameArgs) {
|
|
18
|
+
return this.schema.getOpName(type, kind, plugin, ...opNameArgs)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
serviceName (type, kind, plugin, ...serviceNameArgs) {
|
|
22
|
+
return this.schema.getServiceName(type, kind, plugin, this.config.service, ...serviceNameArgs)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
configure (config = {}) {
|
|
26
|
+
this.config = config
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = new SchemaManager()
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class SchemaDefinition {
|
|
2
|
+
constructor (schema) {
|
|
3
|
+
this.schema = schema
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
getSchemaItem (type, kind, plugin) {
|
|
7
|
+
const schema = this.schema
|
|
8
|
+
if (schema && schema[type] && schema[type][kind] && schema[type][kind][plugin]) {
|
|
9
|
+
return schema[type][kind][plugin]
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
getOpName (type, kind, plugin, ...opNameArgs) {
|
|
14
|
+
const item = this.getSchemaItem(type, kind, plugin)
|
|
15
|
+
return item.opName(...opNameArgs)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getServiceName (type, kind, plugin, service, ...serviceNameArgs) {
|
|
19
|
+
const item = this.getSchemaItem(type, kind, plugin)
|
|
20
|
+
return item.serviceName(service, ...serviceNameArgs)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = SchemaDefinition
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const { identityService } = require('../util')
|
|
2
|
+
|
|
3
|
+
function amqpServiceName (service) {
|
|
4
|
+
return `${service}-amqp`
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const messaging = {
|
|
8
|
+
producer: {
|
|
9
|
+
amqplib: {
|
|
10
|
+
opName: () => 'amqp.command',
|
|
11
|
+
serviceName: amqpServiceName
|
|
12
|
+
},
|
|
13
|
+
amqp10: {
|
|
14
|
+
opName: () => 'amqp.send',
|
|
15
|
+
serviceName: amqpServiceName
|
|
16
|
+
},
|
|
17
|
+
'google-cloud-pubsub': {
|
|
18
|
+
opName: () => 'pubsub.request',
|
|
19
|
+
serviceName: service => `${service}-pubsub`
|
|
20
|
+
},
|
|
21
|
+
kafkajs: {
|
|
22
|
+
opName: () => 'kafka.produce',
|
|
23
|
+
serviceName: service => `${service}-kafka`
|
|
24
|
+
},
|
|
25
|
+
rhea: {
|
|
26
|
+
opName: () => 'amqp.send',
|
|
27
|
+
serviceName: service => `${service}-amqp-producer`
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
consumer: {
|
|
31
|
+
amqplib: {
|
|
32
|
+
opName: () => 'amqp.command',
|
|
33
|
+
serviceName: amqpServiceName
|
|
34
|
+
},
|
|
35
|
+
amqp10: {
|
|
36
|
+
opName: () => 'amqp.receive',
|
|
37
|
+
serviceName: amqpServiceName
|
|
38
|
+
},
|
|
39
|
+
'google-cloud-pubsub': {
|
|
40
|
+
opName: () => 'pubsub.receive',
|
|
41
|
+
serviceName: identityService
|
|
42
|
+
},
|
|
43
|
+
kafkajs: {
|
|
44
|
+
opName: () => 'kafka.consume',
|
|
45
|
+
serviceName: service => `${service}-kafka`
|
|
46
|
+
},
|
|
47
|
+
rhea: {
|
|
48
|
+
opName: () => 'amqp.receive',
|
|
49
|
+
serviceName: identityService
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
client: {
|
|
53
|
+
amqplib: {
|
|
54
|
+
opName: () => 'amqp.command',
|
|
55
|
+
serviceName: amqpServiceName
|
|
56
|
+
},
|
|
57
|
+
'google-cloud-pubsub': {
|
|
58
|
+
opName: () => 'pubsub.request',
|
|
59
|
+
serviceName: service => `${service}-pubsub`
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = messaging
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
function getRedisService (config, connectionName) {
|
|
2
|
+
if (config.splitByInstance && connectionName) {
|
|
3
|
+
return config.service
|
|
4
|
+
? `${config.service}-${connectionName}`
|
|
5
|
+
: connectionName
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return config.service
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function fromSystem (service, system) {
|
|
12
|
+
return system ? `${service}-${system}` : undefined
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const redisConfig = {
|
|
16
|
+
opName: () => 'redis.command',
|
|
17
|
+
serviceName: (service, config, system, connectionName) => {
|
|
18
|
+
return getRedisService(config, connectionName) || fromSystem(service, system)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const storage = {
|
|
23
|
+
client: {
|
|
24
|
+
ioredis: redisConfig,
|
|
25
|
+
memcached: {
|
|
26
|
+
opName: () => 'memcached.command',
|
|
27
|
+
serviceName: (service, config, system) => config.service || fromSystem(service, system)
|
|
28
|
+
},
|
|
29
|
+
redis: redisConfig
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = storage
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const { identityService } = require('../util')
|
|
2
|
+
|
|
3
|
+
const amqpInbound = {
|
|
4
|
+
opName: () => 'amqp.process',
|
|
5
|
+
serviceName: identityService
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const amqpOutbound = {
|
|
9
|
+
opName: () => 'amqp.send',
|
|
10
|
+
serviceName: identityService
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const messaging = {
|
|
14
|
+
producer: {
|
|
15
|
+
amqplib: amqpOutbound,
|
|
16
|
+
amqp10: amqpOutbound,
|
|
17
|
+
'google-cloud-pubsub': {
|
|
18
|
+
opName: () => 'gcp.pubsub.send',
|
|
19
|
+
serviceName: identityService
|
|
20
|
+
},
|
|
21
|
+
kafkajs: {
|
|
22
|
+
opName: () => 'kafka.send',
|
|
23
|
+
serviceName: identityService
|
|
24
|
+
},
|
|
25
|
+
rhea: amqpOutbound
|
|
26
|
+
},
|
|
27
|
+
consumer: {
|
|
28
|
+
amqplib: amqpInbound,
|
|
29
|
+
amqp10: amqpInbound,
|
|
30
|
+
'google-cloud-pubsub': {
|
|
31
|
+
opName: () => 'gcp.pubsub.process',
|
|
32
|
+
serviceName: identityService
|
|
33
|
+
},
|
|
34
|
+
kafkajs: {
|
|
35
|
+
opName: () => 'kafka.process',
|
|
36
|
+
serviceName: identityService
|
|
37
|
+
},
|
|
38
|
+
rhea: amqpInbound
|
|
39
|
+
},
|
|
40
|
+
client: {
|
|
41
|
+
amqplib: {
|
|
42
|
+
opName: () => 'amqp.command',
|
|
43
|
+
serviceName: identityService
|
|
44
|
+
},
|
|
45
|
+
'google-cloud-pubsub': {
|
|
46
|
+
opName: () => 'gcp.pubsub.request',
|
|
47
|
+
serviceName: identityService
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = messaging
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
function configWithFallback (service, config) {
|
|
2
|
+
return config.service || service
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
const redisNaming = {
|
|
6
|
+
opName: () => 'redis.command',
|
|
7
|
+
serviceName: configWithFallback
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const storage = {
|
|
11
|
+
client: {
|
|
12
|
+
ioredis: redisNaming,
|
|
13
|
+
memcached: {
|
|
14
|
+
opName: () => 'memcached.command',
|
|
15
|
+
serviceName: configWithFallback
|
|
16
|
+
},
|
|
17
|
+
redis: redisNaming
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = storage
|
|
@@ -6,10 +6,6 @@ const os = require('os')
|
|
|
6
6
|
const dependencies = require('./dependencies')
|
|
7
7
|
const { sendData } = require('./send-data')
|
|
8
8
|
|
|
9
|
-
const HEARTBEAT_INTERVAL = process.env.DD_TELEMETRY_HEARTBEAT_INTERVAL
|
|
10
|
-
? Number(process.env.DD_TELEMETRY_HEARTBEAT_INTERVAL) * 1000
|
|
11
|
-
: 60000
|
|
12
|
-
|
|
13
9
|
const telemetryStartChannel = dc.channel('datadog:telemetry:start')
|
|
14
10
|
const telemetryStopChannel = dc.channel('datadog:telemetry:stop')
|
|
15
11
|
|
|
@@ -19,6 +15,7 @@ let pluginManager
|
|
|
19
15
|
let application
|
|
20
16
|
let host
|
|
21
17
|
let interval
|
|
18
|
+
let heartbeatInterval
|
|
22
19
|
const sentIntegrations = new Set()
|
|
23
20
|
|
|
24
21
|
function getIntegrations () {
|
|
@@ -108,7 +105,7 @@ function createHostObject () {
|
|
|
108
105
|
}
|
|
109
106
|
|
|
110
107
|
function getTelemetryData () {
|
|
111
|
-
return { config, application, host, heartbeatInterval
|
|
108
|
+
return { config, application, host, heartbeatInterval }
|
|
112
109
|
}
|
|
113
110
|
|
|
114
111
|
function start (aConfig, thePluginManager) {
|
|
@@ -119,11 +116,13 @@ function start (aConfig, thePluginManager) {
|
|
|
119
116
|
pluginManager = thePluginManager
|
|
120
117
|
application = createAppObject()
|
|
121
118
|
host = createHostObject()
|
|
119
|
+
heartbeatInterval = config.telemetry.heartbeatInterval
|
|
120
|
+
|
|
122
121
|
dependencies.start(config, application, host)
|
|
123
122
|
sendData(config, application, host, 'app-started', appStarted())
|
|
124
123
|
interval = setInterval(() => {
|
|
125
124
|
sendData(config, application, host, 'app-heartbeat')
|
|
126
|
-
},
|
|
125
|
+
}, heartbeatInterval)
|
|
127
126
|
interval.unref()
|
|
128
127
|
process.on('beforeExit', onBeforeExit)
|
|
129
128
|
|