dd-trace 2.0.0-beta.0 → 2.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.
Files changed (31) hide show
  1. package/MIGRATING.md +65 -0
  2. package/NOTICE +4 -0
  3. package/package.json +2 -2
  4. package/packages/datadog-instrumentations/index.js +1 -0
  5. package/packages/datadog-instrumentations/src/dns.js +2 -2
  6. package/packages/datadog-instrumentations/src/helpers/instrument.js +24 -25
  7. package/packages/datadog-instrumentations/src/memcached.js +3 -5
  8. package/packages/datadog-instrumentations/src/mysql.js +7 -9
  9. package/packages/datadog-instrumentations/src/mysql2.js +76 -0
  10. package/packages/datadog-instrumentations/src/q.js +9 -1
  11. package/packages/datadog-plugin-aws-sdk/src/helpers.js +4 -3
  12. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +48 -0
  13. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +56 -6
  14. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +33 -6
  15. package/packages/datadog-plugin-mysql/src/index.js +4 -4
  16. package/packages/datadog-plugin-mysql2/src/index.js +5 -88
  17. package/packages/datadog-plugin-next/src/index.js +10 -6
  18. package/packages/datadog-plugin-pino/src/index.js +25 -1
  19. package/packages/datadog-plugin-winston/src/index.js +30 -12
  20. package/packages/dd-trace/lib/version.js +1 -1
  21. package/packages/dd-trace/src/appsec/index.js +13 -16
  22. package/packages/dd-trace/src/appsec/recommended.json +5708 -1
  23. package/packages/dd-trace/src/appsec/reporter.js +15 -3
  24. package/packages/dd-trace/src/config.js +7 -1
  25. package/packages/dd-trace/src/profiling/config.js +5 -1
  26. package/packages/dd-trace/src/profiling/profiler.js +15 -6
  27. package/packages/dd-trace/src/profiling/profilers/cpu.js +1 -1
  28. package/packages/dd-trace/src/profiling/profilers/heap.js +3 -2
  29. package/scripts/publish_docs.js +1 -1
  30. package/scripts/tracer-runner.js +13 -0
  31. package/packages/dd-trace/src/profiling/mapper.js +0 -91
@@ -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',
@@ -85,8 +89,11 @@ function reportAttack (attackData, store) {
85
89
  const currentTags = topSpan.context()._tags
86
90
 
87
91
  const newTags = {
88
- 'appsec.event': true,
89
- 'manual.keep': true // TODO: figure out how to keep appsec traces with sampling revamp
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
 
92
99
  // TODO: maybe add this to format.js later (to take decision as late as possible)
@@ -136,11 +143,16 @@ function finishAttacks (req, context) {
136
143
  topSpan.addTags(newTags)
137
144
  }
138
145
 
146
+ function setRateLimit (rateLimit) {
147
+ limiter = new Limiter(rateLimit)
148
+ }
149
+
139
150
  module.exports = {
140
151
  resolveHTTPRequest,
141
152
  resolveHTTPResponse,
142
153
  filterHeaders,
143
154
  formatHeaderName,
144
155
  reportAttack,
145
- finishAttacks
156
+ finishAttacks,
157
+ setRateLimit
146
158
  }
@@ -134,6 +134,11 @@ class Config {
134
134
  process.env.DD_APPSEC_RULES,
135
135
  path.join(__dirname, 'appsec', 'recommended.json')
136
136
  )
137
+ const DD_APPSEC_TRACE_RATE_LIMIT = coalesce(
138
+ appsec.rateLimit,
139
+ process.env.DD_APPSEC_TRACE_RATE_LIMIT,
140
+ 100
141
+ )
137
142
 
138
143
  const sampler = (options.experimental && options.experimental.sampler) || {}
139
144
  const ingestion = options.ingestion || {}
@@ -198,7 +203,8 @@ class Config {
198
203
  this.protocolVersion = DD_TRACE_AGENT_PROTOCOL_VERSION
199
204
  this.appsec = {
200
205
  enabled: isTrue(DD_APPSEC_ENABLED),
201
- rules: DD_APPSEC_RULES
206
+ rules: DD_APPSEC_RULES,
207
+ rateLimit: DD_APPSEC_TRACE_RATE_LIMIT
202
208
  }
203
209
 
204
210
  tagger.add(this.tags, {
@@ -20,7 +20,8 @@ const {
20
20
  DD_TRACE_AGENT_URL,
21
21
  DD_AGENT_HOST,
22
22
  DD_TRACE_AGENT_PORT,
23
- DD_PROFILING_UPLOAD_TIMEOUT
23
+ DD_PROFILING_UPLOAD_TIMEOUT,
24
+ DD_PROFILING_SOURCE_MAP
24
25
  } = process.env
25
26
 
26
27
  class Config {
@@ -34,6 +35,8 @@ class Config {
34
35
  const flushInterval = coalesce(options.interval, 65 * 1000)
35
36
  const uploadTimeout = coalesce(options.uploadTimeout,
36
37
  DD_PROFILING_UPLOAD_TIMEOUT, 60 * 1000)
38
+ const sourceMap = coalesce(options.sourceMap,
39
+ DD_PROFILING_SOURCE_MAP, true)
37
40
 
38
41
  this.enabled = String(enabled) !== 'false'
39
42
  this.service = service
@@ -49,6 +52,7 @@ class Config {
49
52
  this.logger = ensureLogger(options.logger)
50
53
  this.flushInterval = flushInterval
51
54
  this.uploadTimeout = uploadTimeout
55
+ this.sourceMap = sourceMap
52
56
 
53
57
  const hostname = coalesce(options.hostname, DD_AGENT_HOST, 'localhost')
54
58
  const port = coalesce(options.port, DD_TRACE_AGENT_PORT, 8126)
@@ -2,7 +2,15 @@
2
2
 
3
3
  const { EventEmitter } = require('events')
4
4
  const { Config } = require('./config')
5
- const { SourceMapper } = require('./mapper')
5
+
6
+ function maybeSourceMap (sourceMap) {
7
+ if (!sourceMap) return
8
+
9
+ const { SourceMapper } = require('@datadog/pprof')
10
+ return SourceMapper.create([
11
+ process.cwd()
12
+ ])
13
+ }
6
14
 
7
15
  class Profiler extends EventEmitter {
8
16
  constructor () {
@@ -15,18 +23,21 @@ class Profiler extends EventEmitter {
15
23
  }
16
24
 
17
25
  start (options) {
26
+ this._start(options).catch(() => {})
27
+ return this
28
+ }
29
+
30
+ async _start (options) {
18
31
  if (this._enabled) return
19
32
 
20
33
  const config = this._config = new Config(options)
21
-
22
34
  if (!config.enabled) return
23
35
 
24
36
  this._logger = config.logger
25
-
26
37
  this._enabled = true
27
38
 
28
39
  try {
29
- const mapper = config.sourceMap ? new SourceMapper() : null
40
+ const mapper = await maybeSourceMap(config.sourceMap)
30
41
 
31
42
  for (const profiler of config.profilers) {
32
43
  // TODO: move this out of Profiler when restoring sourcemap support
@@ -39,8 +50,6 @@ class Profiler extends EventEmitter {
39
50
  this._logger.error(e)
40
51
  this.stop()
41
52
  }
42
-
43
- return this
44
53
  }
45
54
 
46
55
  stop () {
@@ -39,7 +39,7 @@ class NativeCpuProfiler {
39
39
 
40
40
  _record () {
41
41
  this._stop = this._pprof.time.start(this._samplingInterval, null,
42
- this._mapper)
42
+ this._mapper, false)
43
43
  }
44
44
  }
45
45
 
@@ -8,13 +8,14 @@ class NativeHeapProfiler {
8
8
  this._pprof = undefined
9
9
  }
10
10
 
11
- start () {
11
+ start ({ mapper } = {}) {
12
+ this._mapper = mapper
12
13
  this._pprof = require('@datadog/pprof')
13
14
  this._pprof.heap.start(this._samplingInterval, this._stackDepth)
14
15
  }
15
16
 
16
17
  profile () {
17
- return this._pprof.heap.profile()
18
+ return this._pprof.heap.profile(undefined, this._mapper)
18
19
  }
19
20
 
20
21
  encode (profile) {
@@ -18,4 +18,4 @@ exec('git init', { cwd: './docs/out' }) // cloning would overwrite generated doc
18
18
  exec('git remote add origin git@github.com:DataDog/dd-trace-js.git', { cwd: './docs/out' })
19
19
  exec('git add -A', { cwd: './docs/out' })
20
20
  exec(`git commit -m "${msg}"`, { cwd: './docs/out' })
21
- exec('git push -f origin master:gh-pages', { cwd: './docs/out' })
21
+ exec('git push -f origin main:gh-pages', { cwd: './docs/out' })
@@ -0,0 +1,13 @@
1
+ 'use strict'
2
+
3
+ const spawnWrap = require('spawn-wrap')
4
+ const path = require('path')
5
+
6
+ spawnWrap(['--require', path.join(__dirname, '..', 'init.js')])
7
+
8
+ const { spawn } = require('child_process')
9
+
10
+ const [command, ...argv] = process.argv.slice(2)
11
+ spawn(command, argv, {
12
+ stdio: 'inherit'
13
+ })
@@ -1,91 +0,0 @@
1
- 'use strict'
2
-
3
- // TODO: use sourceRoot when set, possibly from source-map-resolve
4
-
5
- const fs = require('fs')
6
- const { SourceMapConsumer } = require('source-map')
7
- const sourceMapResolve = require('source-map-resolve')
8
- const { fileURLToPath, pathToFileURL } = require('url')
9
-
10
- class SourceMapper {
11
- constructor () {
12
- this._consumers = Object.create(null)
13
- this._sources = Object.create(null)
14
- }
15
-
16
- async getSource (callFrame) {
17
- const { url, lineNumber, columnNumber, functionName } = callFrame
18
- const key = `${url}:${functionName}:${lineNumber}:${columnNumber}`
19
-
20
- if (!this._sources[key]) {
21
- this._sources[key] = await this._getMapping(callFrame)
22
- }
23
-
24
- return this._sources[key]
25
- }
26
-
27
- async _getConsumer (url) {
28
- if (this._consumers[url] === undefined) {
29
- this._consumers[url] = this._createConsumer(url)
30
- }
31
-
32
- return this._consumers[url]
33
- }
34
-
35
- async _createConsumer (url) {
36
- try {
37
- const map = await this._resolve(url)
38
-
39
- return map ? new SourceMapConsumer(map) : null
40
- } catch (e) {
41
- return null
42
- }
43
- }
44
-
45
- async _getMapping (callFrame) {
46
- const { url, functionName, lineNumber, columnNumber } = callFrame
47
-
48
- // Runtime.CallFrame is 0-based for both line and column numbers.
49
- // When the line or column number is not known the value is -1.
50
- // https://chromedevtools.github.io/devtools-protocol/v8/Runtime/#type-CallFrame
51
- if (lineNumber < 0 || columnNumber < 0) return callFrame
52
-
53
- const consumer = await this._getConsumer(url)
54
-
55
- if (!consumer) return callFrame
56
-
57
- // SourceMapConsumer is 1-based for lines and 0-based for columns
58
- // https://github.com/mozilla/source-map/blob/0.7.3/lib/source-map-consumer.js#L464-L487
59
- const map = consumer.originalPositionFor({
60
- line: lineNumber + 1,
61
- column: columnNumber
62
- })
63
-
64
- if (!map || !map.source || !map.line) return callFrame
65
-
66
- return {
67
- url: pathToFileURL(map.source).href,
68
- lineNumber: map.line - 1, // reset to 0-based from 1-based
69
- columnNumber: map.column !== null ? map.column : -1,
70
- functionName: map.name || functionName
71
- }
72
- }
73
-
74
- async _resolve (url) {
75
- const filename = fileURLToPath(url)
76
- const code = (await fs.promises.readFile(filename)).toString()
77
-
78
- return new Promise((resolve, reject) => {
79
- sourceMapResolve.resolve(code, filename, fs.readFile, (error, result) => {
80
- if (!result || error) return resolve(null)
81
-
82
- result.map.sourcesContent = result.sourcesContent
83
- result.map.sources = result.sourcesResolved
84
-
85
- resolve(result.map)
86
- })
87
- })
88
- }
89
- }
90
-
91
- module.exports = { SourceMapper }