dd-trace 3.0.0-pre.1 → 3.1.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.
Files changed (71) hide show
  1. package/LICENSE-3rdparty.csv +2 -2
  2. package/MIGRATING.md +119 -0
  3. package/ci/init.js +0 -1
  4. package/ext/formats.js +3 -5
  5. package/index.d.ts +1 -11
  6. package/package.json +7 -7
  7. package/packages/datadog-core/src/storage/async_resource.js +19 -1
  8. package/packages/datadog-core/src/storage/index.js +1 -1
  9. package/packages/datadog-instrumentations/index.js +1 -52
  10. package/packages/datadog-instrumentations/src/connect.js +1 -1
  11. package/packages/datadog-instrumentations/src/cucumber.js +15 -0
  12. package/packages/datadog-instrumentations/src/grpc/client.js +2 -2
  13. package/packages/datadog-instrumentations/src/grpc/server.js +1 -1
  14. package/packages/datadog-instrumentations/src/hapi.js +3 -31
  15. package/packages/datadog-instrumentations/src/helpers/hooks.js +68 -0
  16. package/packages/datadog-instrumentations/src/helpers/instrument.js +5 -34
  17. package/packages/datadog-instrumentations/src/helpers/instrumentations.js +7 -0
  18. package/packages/datadog-instrumentations/src/helpers/register.js +59 -0
  19. package/packages/datadog-instrumentations/src/jest.js +33 -11
  20. package/packages/datadog-instrumentations/src/koa.js +1 -1
  21. package/packages/datadog-instrumentations/src/mocha.js +4 -1
  22. package/packages/datadog-instrumentations/src/pg.js +2 -2
  23. package/packages/datadog-instrumentations/src/restify.js +27 -5
  24. package/packages/datadog-instrumentations/src/router.js +1 -1
  25. package/packages/datadog-plugin-aws-sdk/src/base.js +1 -2
  26. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -2
  27. package/packages/datadog-plugin-cucumber/src/index.js +4 -0
  28. package/packages/datadog-plugin-jest/src/index.js +25 -4
  29. package/packages/datadog-plugin-mocha/src/index.js +2 -2
  30. package/packages/datadog-plugin-mongodb-core/src/index.js +21 -6
  31. package/packages/datadog-plugin-oracledb/src/index.js +12 -4
  32. package/packages/datadog-plugin-restify/src/index.js +7 -0
  33. package/packages/dd-trace/index.js +1 -1
  34. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +50 -0
  35. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +53 -8
  36. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +23 -24
  37. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +220 -0
  38. package/packages/dd-trace/src/config.js +13 -0
  39. package/packages/dd-trace/src/encode/0.4.js +51 -58
  40. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +13 -34
  41. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +84 -0
  42. package/packages/dd-trace/src/exporters/agent/index.js +13 -7
  43. package/packages/dd-trace/src/exporters/agent/writer.js +1 -1
  44. package/packages/dd-trace/src/{profiling/exporters → exporters/common}/form-data.js +0 -0
  45. package/packages/dd-trace/src/exporters/common/request.js +23 -11
  46. package/packages/dd-trace/src/exporters/common/writer.js +9 -6
  47. package/packages/dd-trace/src/id.js +16 -13
  48. package/packages/dd-trace/src/iitm.js +1 -1
  49. package/packages/dd-trace/src/index.js +10 -0
  50. package/packages/dd-trace/src/noop/proxy.js +77 -0
  51. package/packages/dd-trace/src/noop/scope.js +2 -6
  52. package/packages/dd-trace/src/noop/span.js +12 -12
  53. package/packages/dd-trace/src/noop/tracer.js +8 -5
  54. package/packages/dd-trace/src/opentracing/propagation/text_map.js +6 -6
  55. package/packages/dd-trace/src/opentracing/span.js +63 -49
  56. package/packages/dd-trace/src/opentracing/span_context.js +1 -5
  57. package/packages/dd-trace/src/opentracing/tracer.js +31 -36
  58. package/packages/dd-trace/src/plugin_manager.js +101 -68
  59. package/packages/dd-trace/src/plugins/index.js +57 -44
  60. package/packages/dd-trace/src/plugins/util/ci.js +34 -9
  61. package/packages/dd-trace/src/plugins/util/git.js +52 -2
  62. package/packages/dd-trace/src/plugins/util/tags.js +4 -1
  63. package/packages/dd-trace/src/plugins/util/web.js +1 -1
  64. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
  65. package/packages/dd-trace/src/profiling/profilers/cpu.js +3 -3
  66. package/packages/dd-trace/src/proxy.js +18 -71
  67. package/packages/dd-trace/src/scope.js +1 -58
  68. package/packages/dd-trace/src/startup-log.js +8 -19
  69. package/packages/dd-trace/src/telemetry.js +2 -15
  70. package/scripts/install_plugin_modules.js +17 -26
  71. package/ci/jest/env.js +0 -38
@@ -3,11 +3,11 @@ require,@datadog/native-appsec,Apache license 2.0,Copyright 2018 Datadog Inc.
3
3
  require,@datadog/native-metrics,Apache license 2.0,Copyright 2018 Datadog Inc.
4
4
  require,@datadog/pprof,Apache license 2.0,Copyright 2019 Google Inc.
5
5
  require,@datadog/sketches-js,Apache license 2.0,Copyright 2020 Datadog Inc.
6
- require,@types/node,MIT,Copyright Authors
7
6
  require,crypto-randomuuid,MIT,Copyright 2021 Node.js Foundation and contributors
8
7
  require,diagnostics_channel,MIT,Copyright 2021 Simon D.
9
8
  require,ignore,MIT,Copyright 2013 Kael Zhang and contributors
10
9
  require,import-in-the-middle,Apache license 2.0,Copyright 2021 Datadog Inc.
10
+ require,istanbul-lib-coverage,BSD-3-Clause,Copyright 2012-2015 Yahoo! Inc.
11
11
  require,koalas,MIT,Copyright 2013-2017 Brian Woodward
12
12
  require,limiter,MIT,Copyright 2011 John Hurliman
13
13
  require,lodash.kebabcase,MIT,Copyright JS Foundation and other contributors
@@ -18,9 +18,9 @@ require,methods,MIT,Copyright 2013-2014 TJ Holowaychuk
18
18
  require,module-details-from-path,MIT,Copyright 2016 Thomas Watson Steen
19
19
  require,opentracing,MIT,Copyright 2016 Resonance Labs Inc
20
20
  require,path-to-regexp,MIT,Copyright 2014 Blake Embrey
21
- require,performance-now,MIT,Copyright 2013 Braveg1rl
22
21
  require,retry,MIT,Copyright 2011 Tim Koschützki Felix Geisendörfer
23
22
  require,semver,ISC,Copyright Isaac Z. Schlueter and Contributors
23
+ dev,@types/node,MIT,Copyright Authors
24
24
  dev,autocannon,MIT,Copyright 2016 Matteo Collina
25
25
  dev,axios,MIT,Copyright 2014-present Matt Zabriskie
26
26
  dev,benchmark,MIT,Copyright 2010-2016 Mathias Bynens Robert Kieffer John-David Dalton
package/MIGRATING.md CHANGED
@@ -4,6 +4,125 @@ This guide describes the steps to upgrade dd-trace from a major version to the
4
4
  next. If you are having any issues related to migrating, please feel free to
5
5
  open an issue or contact our [support](https://www.datadoghq.com/support/) team.
6
6
 
7
+ ## 2.0 to 3.0
8
+
9
+ ### Node 12 is no longer supported
10
+
11
+ Node.js 12 has been EOL since April 2022 and is no longer supported. Generally
12
+ speaking, we highly recommend always keeping Node.js up to date regardless of our
13
+ support policy.
14
+
15
+ ### HTTP query string reported by default
16
+
17
+ HTTP query strings are now reported by default as part of the `http.url` tag.
18
+ This change is considered breaking only because there might be sensitive data
19
+ in the query string. A default regular expression based obfuscator is provided
20
+ for common use cases like API keys, but if your use case is not covered, the
21
+ [DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP](https://datadoghq.dev/dd-trace-js/#tracer-settings)
22
+ environment variable can be used to control what is obfuscated, and a value of
23
+ `.*` would redact the query string entirely.
24
+
25
+ ### HTTP operation name change
26
+
27
+ The HTTP integration now uses `web.request` for incoming requests and continues
28
+ to use `http.request` for outgoing requests. When using a supported web
29
+ framework like Express, this change will have no effect because the root span
30
+ would already have an operation name override like `express.request`.
31
+ Any [monitor](https://docs.datadoghq.com/monitors/create/types/apm/?tab=apmmetrics)
32
+ on `http.request` for incoming requests should be updated to `web.request`.
33
+
34
+ With this change, both operation names also appear under the main service name
35
+ and are no longer split between the server service name and a separate client
36
+ service name suffixed with `-http-client`.
37
+
38
+ ### gRPC operation name change
39
+
40
+ The gRPC integration now uses `grpc.server` for incoming requests and
41
+ `grpc.client` for outgoing requests. Any
42
+ [monitor](https://docs.datadoghq.com/monitors/create/types/apm/?tab=apmmetrics)
43
+ on `grpc.request` should be updated to one of these.
44
+
45
+ With this change, both operation names also appear under the main service name
46
+ and are no longer split between the server service name and a separate client
47
+ service name suffixed with `-http-client`.
48
+
49
+ ### Removal of `fs` integration
50
+
51
+ The `fs` integration was removed as it was originally added without an actual
52
+ use case, and it's been problematic ever since. It's noisy, the output is
53
+ confusing when using streams, errors that are handled higher in the stack end up
54
+ being captured, etc.
55
+
56
+ If you had any use for file system instrumentation, please let us know so we can
57
+ provide an alternative.
58
+
59
+ ### Scope binding for promises and event emitters
60
+
61
+ It's no longer possible to bind promises using `tracer.scope().bind(promise)` or
62
+ event emitters using `tracer.scope().bind(emitter)`. These were historically
63
+ added mostly for internal use, and changes to context propagation over the years
64
+ made them unnecessary, both internally and externaly. If one of these is used
65
+ anywhere, the call will simply be ignored and no binding will occur.
66
+
67
+ To bind the `then` handler of a promise, bind the function directly directly:
68
+
69
+ ```js
70
+ promise.then(tracer.scope().bind(handler))
71
+ ```
72
+
73
+ To bind all listeners for an event, wrap the call to `emit` directly instead:
74
+
75
+ ```js
76
+ tracer.scope().activate(span, () => {
77
+ emitter.emit('event')
78
+ })
79
+ ```
80
+
81
+ To bind individual listeners, bind the listener function directly instead:
82
+
83
+ ```js
84
+ emitter.on('event', tracer.scope().bind(listener, span))
85
+ ```
86
+
87
+ ### Removed APIs
88
+
89
+ The following APIs have been deprecated for a long time and have now been
90
+ completely removed:
91
+
92
+ - `tracer.currentSpan()`
93
+ - `tracer.bindEmitter()`
94
+
95
+ Since these have not been recommended nor publicly documented for years at this
96
+ point, there should be no impact as no application is expected to be using them.
97
+
98
+ ### CI Visibility new entrypoints
99
+
100
+ #### Cypress
101
+
102
+ `dd-trace/cypress/plugin` and `dd-trace/cypress/support` are removed, so you won't
103
+ be able to use them for your `cypress` instrumentation. Use `dd-trace/ci/cypress/plugin`
104
+ and `dd-trace/ci/cypress/support` instead for your plugin and support configuration
105
+ respectively.
106
+
107
+ #### Jest
108
+
109
+ The use of `'dd-trace/ci/jest/env'` in [`testEnvironment`](https://jestjs.io/docs/configuration#testenvironment-string)
110
+ is no longer supported.
111
+ To instrument `jest` tests now, add `'-r dd-trace/ci/init'` to the `NODE_OPTIONS` environment
112
+ variable passed to the process running the tests, for example, `NODE_OPTIONS='-r dd-trace/ci/init' yarn test`.
113
+
114
+ #### Mocha
115
+
116
+ The use of `--require dd-trace/ci/init` as a `mocha` flag is no longer supported.
117
+ To instrument `mocha` tests now, add `'-r dd-trace/ci/init'` to the `NODE_OPTIONS` environment
118
+ variable passed to the process running the tests, for example, `NODE_OPTIONS='-r dd-trace/ci/init' yarn test`.
119
+
120
+ #### Cucumber
121
+
122
+ The use of `--require-module dd-trace/ci/init` as a `cucumber-js` flag is no longer supported.
123
+ To instrument `cucumber-js` tests now, add `'-r dd-trace/ci/init'` to the `NODE_OPTIONS` environment
124
+ variable passed to the process running the tests, for example, `NODE_OPTIONS='-r dd-trace/ci/init' yarn test`.
125
+
7
126
  ## 1.0 to 2.0
8
127
 
9
128
  ### Configuration
package/ci/init.js CHANGED
@@ -29,7 +29,6 @@ so dd-trace will not be initialized.`)
29
29
 
30
30
  if (shouldInit) {
31
31
  tracer.init(options)
32
- tracer.use('fs', false)
33
32
  }
34
33
 
35
34
  module.exports = tracer
package/ext/formats.js CHANGED
@@ -1,10 +1,8 @@
1
1
  'use strict'
2
2
 
3
- const opentracing = require('opentracing')
4
-
5
3
  module.exports = {
6
- TEXT_MAP: opentracing.FORMAT_TEXT_MAP,
7
- HTTP_HEADERS: opentracing.FORMAT_HTTP_HEADERS,
8
- BINARY: opentracing.FORMAT_BINARY,
4
+ TEXT_MAP: 'text_map',
5
+ HTTP_HEADERS: 'http_headers',
6
+ BINARY: 'binary',
9
7
  LOG: 'log'
10
8
  }
package/index.d.ts CHANGED
@@ -491,15 +491,6 @@ export declare interface TracerOptions {
491
491
  [key: string]: string | undefined
492
492
  }
493
493
 
494
- /** @hidden */
495
- interface EventEmitter {
496
- emit(eventName: string | symbol, ...args: any[]): any;
497
- on?(eventName: string | symbol, listener: (...args: any[]) => any): any;
498
- off?(eventName: string | symbol, listener: (...args: any[]) => any): any;
499
- addListener?(eventName: string | symbol, listener: (...args: any[]) => any): any;
500
- removeListener?(eventName: string | symbol, listener: (...args: any[]) => any): any;
501
- }
502
-
503
494
  /** @hidden */
504
495
  declare type anyObject = {
505
496
  [key: string]: any;
@@ -537,14 +528,13 @@ export declare interface Scope {
537
528
  /**
538
529
  * Binds a target to the provided span, or the active span if omitted.
539
530
  *
540
- * @param {Function|Promise|EventEmitter} target Target that will have the span activated on its scope.
531
+ * @param {Function|Promise} target Target that will have the span activated on its scope.
541
532
  * @param {Span} [span=scope.active()] The span to activate.
542
533
  * @returns The bound target.
543
534
  */
544
535
  bind<T extends (...args: any[]) => void>(fn: T, span?: Span | null): T;
545
536
  bind<V, T extends (...args: any[]) => V>(fn: T, span?: Span | null): T;
546
537
  bind<T>(fn: Promise<T>, span?: Span | null): Promise<T>;
547
- bind(emitter: EventEmitter, span?: Span | null): EventEmitter;
548
538
  }
549
539
 
550
540
  /** @hidden */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "3.0.0-pre.1",
3
+ "version": "3.1.0",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -55,18 +55,18 @@
55
55
  },
56
56
  "homepage": "https://github.com/DataDog/dd-trace-js#readme",
57
57
  "engines": {
58
- "node": ">=12"
58
+ "node": ">=14"
59
59
  },
60
60
  "dependencies": {
61
61
  "@datadog/native-appsec": "^1.2.1",
62
- "@datadog/native-metrics": "^1.4.1",
63
- "@datadog/pprof": "^1.0.0",
64
- "@datadog/sketches-js": "^1.0.5",
65
- "@types/node": ">=12",
62
+ "@datadog/native-metrics": "^1.4.2",
63
+ "@datadog/pprof": "^1.0.2",
64
+ "@datadog/sketches-js": "^2.0.0",
66
65
  "crypto-randomuuid": "^1.0.0",
67
66
  "diagnostics_channel": "^1.1.0",
68
67
  "ignore": "^5.2.0",
69
68
  "import-in-the-middle": "^1.3.0",
69
+ "istanbul-lib-coverage": "3.2.0",
70
70
  "koalas": "^1.0.2",
71
71
  "limiter": "^1.1.4",
72
72
  "lodash.kebabcase": "^4.1.1",
@@ -77,11 +77,11 @@
77
77
  "module-details-from-path": "^1.0.3",
78
78
  "opentracing": ">=0.12.1",
79
79
  "path-to-regexp": "^0.1.2",
80
- "performance-now": "^2.1.0",
81
80
  "retry": "^0.10.1",
82
81
  "semver": "^5.5.0"
83
82
  },
84
83
  "devDependencies": {
84
+ "@types/node": ">=14",
85
85
  "autocannon": "^4.5.2",
86
86
  "axios": "^0.21.2",
87
87
  "benchmark": "^2.1.4",
@@ -6,9 +6,27 @@ const { channel } = require('diagnostics_channel')
6
6
  const beforeCh = channel('dd-trace:storage:before')
7
7
  const afterCh = channel('dd-trace:storage:after')
8
8
 
9
+ let PrivateSymbol = Symbol
10
+ function makePrivateSymbol () {
11
+ // eslint-disable-next-line no-new-func
12
+ PrivateSymbol = new Function('name', 'return %CreatePrivateSymbol(name)')
13
+ }
14
+
15
+ try {
16
+ makePrivateSymbol()
17
+ } catch (e) {
18
+ try {
19
+ const v8 = require('v8')
20
+ v8.setFlagsFromString('--allow-natives-syntax')
21
+ makePrivateSymbol()
22
+ v8.setFlagsFromString('--no-allow-natives-syntax')
23
+ // eslint-disable-next-line no-empty
24
+ } catch (e) {}
25
+ }
26
+
9
27
  class AsyncResourceStorage {
10
28
  constructor () {
11
- this._ddResourceStore = Symbol('ddResourceStore')
29
+ this._ddResourceStore = PrivateSymbol('ddResourceStore')
12
30
  this._enabled = false
13
31
  this._hook = createHook(this._createHook())
14
32
  }
@@ -5,7 +5,7 @@
5
5
  const semver = require('semver')
6
6
 
7
7
  // https://github.com/nodejs/node/pull/33801
8
- const hasJavaScriptAsyncHooks = semver.satisfies(process.versions.node, '>=14.5 || ^12.19.0')
8
+ const hasJavaScriptAsyncHooks = semver.satisfies(process.versions.node, '>=14.5')
9
9
 
10
10
  if (hasJavaScriptAsyncHooks) {
11
11
  module.exports = require('./async_resource')
@@ -1,54 +1,3 @@
1
1
  'use strict'
2
2
 
3
- require('./src/amqplib')
4
- require('./src/amqp10')
5
- require('./src/aws-sdk')
6
- require('./src/bluebird')
7
- require('./src/bunyan')
8
- require('./src/cassandra-driver')
9
- require('./src/connect')
10
- require('./src/couchbase')
11
- require('./src/cucumber')
12
- require('./src/dns')
13
- require('./src/elasticsearch')
14
- require('./src/express')
15
- require('./src/fastify')
16
- require('./src/find-my-way')
17
- require('./src/generic-pool')
18
- require('./src/google-cloud-pubsub')
19
- require('./src/graphql')
20
- require('./src/grpc')
21
- require('./src/hapi')
22
- require('./src/http')
23
- require('./src/http2')
24
- require('./src/ioredis')
25
- require('./src/jest')
26
- require('./src/kafkajs')
27
- require('./src/knex')
28
- require('./src/koa')
29
- require('./src/memcached')
30
- require('./src/microgateway-core')
31
- require('./src/moleculer')
32
- require('./src/mongodb-core')
33
- require('./src/mongoose')
34
- require('./src/mysql')
35
- require('./src/mysql2')
36
- require('./src/mocha')
37
- require('./src/net')
38
- require('./src/next')
39
- require('./src/oracledb')
40
- require('./src/paperplane')
41
- require('./src/pino')
42
- require('./src/pg')
43
- require('./src/promise')
44
- require('./src/promise-js')
45
- require('./src/q')
46
- require('./src/redis')
47
- require('./src/restify')
48
- require('./src/router')
49
- require('./src/rhea')
50
- require('./src/sharedb')
51
- require('./src/tedious')
52
- require('./src/when')
53
- require('./src/winston')
54
- require('./src/limitd-client')
3
+ require('./src/helpers/register')
@@ -98,7 +98,7 @@ function wrapNext (req, next) {
98
98
  nextChannel.publish({ req })
99
99
  exitChannel.publish({ req })
100
100
 
101
- next.apply(null, arguments)
101
+ next.apply(this, arguments)
102
102
  }
103
103
  }
104
104
 
@@ -7,6 +7,7 @@ const runStartCh = channel('ci:cucumber:run:start')
7
7
  const runFinishCh = channel('ci:cucumber:run:finish')
8
8
  const runStepStartCh = channel('ci:cucumber:run-step:start')
9
9
  const errorCh = channel('ci:cucumber:error')
10
+ const sessionFinishCh = channel('ci:cucumber:session:finish')
10
11
 
11
12
  // TODO: remove in a later major version
12
13
  const patched = new WeakSet()
@@ -128,4 +129,18 @@ addHook({
128
129
  file: 'lib/runtime/test_case_runner.js'
129
130
  }, testCaseHook)
130
131
 
132
+ addHook({
133
+ name: '@cucumber/cucumber',
134
+ versions: ['>=7.0.0'],
135
+ file: 'lib/runtime/index.js'
136
+ }, (Runtime) => {
137
+ shimmer.wrap(Runtime.default.prototype, 'start', start => async function () {
138
+ const result = await start.apply(this, arguments)
139
+ sessionFinishCh.publish(undefined)
140
+ return result
141
+ })
142
+
143
+ return Runtime
144
+ })
145
+
131
146
  module.exports = { pickleHook, testCaseHook }
@@ -232,9 +232,9 @@ function patch (grpc) {
232
232
  return grpc
233
233
  }
234
234
 
235
- addHook({ name: 'grpc', versions: ['>=1.20.2'] }, patch)
235
+ addHook({ name: 'grpc', versions: ['>=1.24.3'] }, patch)
236
236
 
237
- addHook({ name: 'grpc', versions: ['>=1.20.2'], file: 'src/client.js' }, client => {
237
+ addHook({ name: 'grpc', versions: ['>=1.24.3'], file: 'src/client.js' }, client => {
238
238
  shimmer.wrap(client, 'makeClientConstructor', createWrapMakeClientConstructor())
239
239
 
240
240
  return client
@@ -131,7 +131,7 @@ function isEmitter (obj) {
131
131
  return typeof obj.emit === 'function' && typeof obj.once === 'function'
132
132
  }
133
133
 
134
- addHook({ name: 'grpc', versions: ['>=1.20.2'], file: 'src/server.js' }, server => {
134
+ addHook({ name: 'grpc', versions: ['>=1.24.3'], file: 'src/server.js' }, server => {
135
135
  shimmer.wrap(server.Server.prototype, 'register', wrapRegister)
136
136
 
137
137
  return server
@@ -62,16 +62,6 @@ function wrapDispatch (dispatch) {
62
62
  }
63
63
  }
64
64
 
65
- function wrapLifecycle (lifecycle) {
66
- return function () {
67
- const result = lifecycle.apply(this, arguments)
68
-
69
- if (Array.isArray(result)) return result.map(wrapHandler)
70
-
71
- return result
72
- }
73
- }
74
-
75
65
  function wrapRebuild (rebuild) {
76
66
  return function (event) {
77
67
  const result = rebuild.apply(this, arguments)
@@ -166,20 +156,14 @@ addHook({ name: 'hapi', versions: ['>=17'] }, hapi => {
166
156
  return hapi
167
157
  })
168
158
 
169
- addHook({ name: 'hapi', versions: ['2 - 7.1', '8 - 16'] }, hapi => {
159
+ addHook({ name: 'hapi', versions: ['16'] }, hapi => {
170
160
  shimmer.wrap(hapi.Server.prototype, 'start', wrapStart)
171
161
  shimmer.wrap(hapi.Server.prototype, 'ext', wrapExt)
172
162
 
173
163
  return hapi
174
164
  })
175
165
 
176
- addHook({ name: 'hapi', versions: ['^7.2'] }, hapi => {
177
- shimmer.wrap(hapi, 'createServer', wrapServer)
178
-
179
- return hapi
180
- })
181
-
182
- addHook({ name: 'hapi', versions: ['7.2 - 16'], file: 'lib/connection.js' }, Connection => {
166
+ addHook({ name: 'hapi', versions: ['16'], file: 'lib/connection.js' }, Connection => {
183
167
  shimmer.wrap(Connection.prototype, '_dispatch', wrapDispatch)
184
168
 
185
169
  return Connection
@@ -191,20 +175,8 @@ addHook({ name: 'hapi', versions: ['>=17'], file: 'lib/core.js' }, Core => {
191
175
  return Core
192
176
  })
193
177
 
194
- addHook({ name: 'hapi', versions: ['2 - 7.1'], file: 'lib/server.js' }, Server => {
195
- shimmer.wrap(Server.prototype, '_dispatch', wrapDispatch)
196
-
197
- return Server
198
- })
199
-
200
- addHook({ name: 'hapi', versions: ['>=10.4'], file: 'lib/route.js' }, Route => {
178
+ addHook({ name: 'hapi', versions: ['>=16'], file: 'lib/route.js' }, Route => {
201
179
  shimmer.wrap(Route.prototype, 'rebuild', wrapRebuild)
202
180
 
203
181
  return Route
204
182
  })
205
-
206
- addHook({ name: 'hapi', versions: ['2 - 10.3'], file: 'lib/route.js' }, Route => {
207
- shimmer.wrap(Route.prototype, 'lifecycle', wrapLifecycle)
208
-
209
- return Route
210
- })
@@ -0,0 +1,68 @@
1
+ 'use strict'
2
+
3
+ module.exports = {
4
+ '@cucumber/cucumber': () => require('../cucumber'),
5
+ '@elastic/elasticsearch': () => require('../elasticsearch'),
6
+ '@elastic/transport': () => require('../elasticsearch'),
7
+ '@google-cloud/pubsub': () => require('../google-cloud-pubsub'),
8
+ '@grpc/grpc-js': () => require('../grpc'),
9
+ '@hapi/hapi': () => require('../hapi'),
10
+ '@koa/router': () => require('../koa'),
11
+ '@node-redis/client': () => require('../redis'),
12
+ 'amqp10': () => require('../amqp10'),
13
+ 'amqplib': () => require('../amqplib'),
14
+ 'aws-sdk': () => require('../aws-sdk'),
15
+ 'bluebird': () => require('../bluebird'),
16
+ 'bunyan': () => require('../bunyan'),
17
+ 'cassandra-driver': () => require('../cassandra-driver'),
18
+ 'connect': () => require('../connect'),
19
+ 'couchbase': () => require('../couchbase'),
20
+ 'cypress': () => require('../cypress'),
21
+ 'dns': () => require('../dns'),
22
+ 'elasticsearch': () => require('../elasticsearch'),
23
+ 'express': () => require('../express'),
24
+ 'fastify': () => require('../fastify'),
25
+ 'find-my-way': () => require('../find-my-way'),
26
+ 'graphql': () => require('../graphql'),
27
+ 'grpc': () => require('../grpc'),
28
+ 'hapi': () => require('../hapi'),
29
+ 'http': () => require('../http'),
30
+ 'http2': () => require('../http2'),
31
+ 'https': () => require('../http'),
32
+ 'ioredis': () => require('../ioredis'),
33
+ 'jest-environment-node': () => require('../jest'),
34
+ 'jest-environment-jsdom': () => require('../jest'),
35
+ 'jest-jasmine2': () => require('../jest'),
36
+ 'koa': () => require('../koa'),
37
+ 'koa-router': () => require('../koa'),
38
+ 'kafkajs': () => require('../kafkajs'),
39
+ 'limitd-client': () => require('../limitd-client'),
40
+ 'memcached': () => require('../memcached'),
41
+ 'microgateway-core': () => require('../microgateway-core'),
42
+ 'mocha': () => require('../mocha'),
43
+ 'mocha-each': () => require('../mocha'),
44
+ 'moleculer': () => require('../moleculer'),
45
+ 'mongodb': () => require('../mongodb-core'),
46
+ 'mongodb-core': () => require('../mongodb-core'),
47
+ 'mongoose': () => require('../mongoose'),
48
+ 'mysql': () => require('../mysql'),
49
+ 'mysql2': () => require('../mysql2'),
50
+ 'net': () => require('../net'),
51
+ 'next': () => require('../next'),
52
+ 'oracledb': () => require('../oracledb'),
53
+ 'paperplane': () => require('../paperplane'),
54
+ 'pg': () => require('../pg'),
55
+ 'pino': () => require('../pino'),
56
+ 'pino-pretty': () => require('../pino'),
57
+ 'promise-js': () => require('../promise-js'),
58
+ 'promise': () => require('../promise'),
59
+ 'q': () => require('../q'),
60
+ 'redis': () => require('../redis'),
61
+ 'restify': () => require('../restify'),
62
+ 'rhea': () => require('../rhea'),
63
+ 'router': () => require('../router'),
64
+ 'sharedb': () => require('../sharedb'),
65
+ 'tedious': () => require('../tedious'),
66
+ 'when': () => require('../when'),
67
+ 'winston': () => require('../winston')
68
+ }
@@ -1,16 +1,12 @@
1
1
  'use strict'
2
2
 
3
3
  const dc = require('diagnostics_channel')
4
- const path = require('path')
5
4
  const semver = require('semver')
6
- const Hook = require('./hook')
7
- const requirePackageJson = require('../../../dd-trace/src/require-package-json')
5
+ const instrumentations = require('./instrumentations')
8
6
  const { AsyncResource } = require('async_hooks')
9
- const log = require('../../../dd-trace/src/log')
10
7
 
11
- const pathSepExpr = new RegExp(`\\${path.sep}`, 'g')
12
8
  const channelMap = {}
13
- exports.channel = function channel (name) {
9
+ exports.channel = function (name) {
14
10
  const maybe = channelMap[name]
15
11
  if (maybe) return maybe
16
12
  const ch = dc.channel(name)
@@ -19,36 +15,11 @@ exports.channel = function channel (name) {
19
15
  }
20
16
 
21
17
  exports.addHook = function addHook ({ name, versions, file }, hook) {
22
- const fullFilename = filename(name, file)
23
-
24
- Hook([name], (moduleExports, moduleName, moduleBaseDir) => {
25
- moduleName = moduleName.replace(pathSepExpr, '/')
26
-
27
- if (moduleName !== fullFilename || !matchVersion(getVersion(moduleBaseDir), versions)) {
28
- return moduleExports
29
- }
30
-
31
- try {
32
- return hook(moduleExports)
33
- } catch (e) {
34
- log.error(e)
35
- return moduleExports
36
- }
37
- })
38
- }
39
-
40
- function matchVersion (version, ranges) {
41
- return !version || (ranges && ranges.some(range => semver.satisfies(semver.coerce(version), range)))
42
- }
43
-
44
- function getVersion (moduleBaseDir) {
45
- if (moduleBaseDir) {
46
- return requirePackageJson(moduleBaseDir, module).version
18
+ if (!instrumentations[name]) {
19
+ instrumentations[name] = []
47
20
  }
48
- }
49
21
 
50
- function filename (name, file) {
51
- return [name, file].filter(val => val).join('/')
22
+ instrumentations[name].push({ name, versions, file, hook })
52
23
  }
53
24
 
54
25
  // AsyncResource.bind exists and binds `this` properly only from 17.8.0 and up.
@@ -0,0 +1,7 @@
1
+ 'use strict'
2
+
3
+ const sym = Symbol.for('_ddtrace_instrumentations')
4
+
5
+ global[sym] = global[sym] || {}
6
+
7
+ module.exports = global[sym]
@@ -0,0 +1,59 @@
1
+ 'use strict'
2
+
3
+ const { channel } = require('diagnostics_channel')
4
+ const path = require('path')
5
+ const semver = require('semver')
6
+ const Hook = require('./hook')
7
+ const requirePackageJson = require('../../../dd-trace/src/require-package-json')
8
+ const log = require('../../../dd-trace/src/log')
9
+
10
+ const hooks = require('./hooks')
11
+ const instrumentations = require('./instrumentations')
12
+ const names = Object.keys(hooks)
13
+ const pathSepExpr = new RegExp(`\\${path.sep}`, 'g')
14
+
15
+ const loadChannel = channel('dd-trace:instrumentation:load')
16
+
17
+ // TODO: make this more efficient
18
+
19
+ for (const packageName of names) {
20
+ Hook([packageName], (moduleExports, moduleName, moduleBaseDir) => {
21
+ moduleName = moduleName.replace(pathSepExpr, '/')
22
+
23
+ hooks[packageName]()
24
+
25
+ for (const { name, file, versions, hook } of instrumentations[packageName]) {
26
+ const fullFilename = filename(name, file)
27
+
28
+ if (moduleName === fullFilename) {
29
+ const version = getVersion(moduleBaseDir)
30
+
31
+ if (matchVersion(version, versions)) {
32
+ try {
33
+ loadChannel.publish({ name, version, file })
34
+
35
+ moduleExports = hook(moduleExports)
36
+ } catch (e) {
37
+ log.error(e)
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ return moduleExports
44
+ })
45
+ }
46
+
47
+ function matchVersion (version, ranges) {
48
+ return !version || (ranges && ranges.some(range => semver.satisfies(semver.coerce(version), range)))
49
+ }
50
+
51
+ function getVersion (moduleBaseDir) {
52
+ if (moduleBaseDir) {
53
+ return requirePackageJson(moduleBaseDir, module).version
54
+ }
55
+ }
56
+
57
+ function filename (name, file) {
58
+ return [name, file].filter(val => val).join('/')
59
+ }