dd-trace 3.3.1 → 3.12.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 (198) hide show
  1. package/LICENSE-3rdparty.csv +8 -0
  2. package/README.md +108 -43
  3. package/ci/init.js +6 -1
  4. package/ext/exporters.d.ts +2 -1
  5. package/ext/exporters.js +2 -1
  6. package/index.d.ts +129 -36
  7. package/package.json +18 -9
  8. package/packages/datadog-instrumentations/src/body-parser.js +26 -0
  9. package/packages/datadog-instrumentations/src/cassandra-driver.js +7 -7
  10. package/packages/datadog-instrumentations/src/child-process.js +30 -0
  11. package/packages/datadog-instrumentations/src/connect.js +15 -15
  12. package/packages/datadog-instrumentations/src/cucumber.js +1 -3
  13. package/packages/datadog-instrumentations/src/elasticsearch.js +51 -47
  14. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +1 -1
  15. package/packages/datadog-instrumentations/src/helpers/hooks.js +9 -0
  16. package/packages/datadog-instrumentations/src/helpers/register.js +5 -0
  17. package/packages/datadog-instrumentations/src/http/server.js +20 -12
  18. package/packages/datadog-instrumentations/src/http2/server.js +67 -1
  19. package/packages/datadog-instrumentations/src/jest.js +182 -25
  20. package/packages/datadog-instrumentations/src/koa.js +32 -32
  21. package/packages/datadog-instrumentations/src/ldapjs.js +91 -0
  22. package/packages/datadog-instrumentations/src/mariadb.js +63 -0
  23. package/packages/datadog-instrumentations/src/memcached.js +1 -4
  24. package/packages/datadog-instrumentations/src/mocha.js +135 -24
  25. package/packages/datadog-instrumentations/src/next.js +10 -2
  26. package/packages/datadog-instrumentations/src/opensearch.js +10 -0
  27. package/packages/datadog-instrumentations/src/oracledb.js +8 -8
  28. package/packages/datadog-instrumentations/src/pg.js +7 -3
  29. package/packages/datadog-instrumentations/src/qs.js +24 -0
  30. package/packages/datadog-instrumentations/src/redis.js +12 -3
  31. package/packages/datadog-instrumentations/src/restify.js +5 -1
  32. package/packages/datadog-instrumentations/src/rhea.js +29 -15
  33. package/packages/datadog-instrumentations/src/router.js +23 -23
  34. package/packages/datadog-plugin-amqp10/src/consumer.js +32 -0
  35. package/packages/datadog-plugin-amqp10/src/index.js +11 -101
  36. package/packages/datadog-plugin-amqp10/src/producer.js +34 -0
  37. package/packages/datadog-plugin-amqp10/src/util.js +15 -0
  38. package/packages/datadog-plugin-amqplib/src/client.js +38 -0
  39. package/packages/datadog-plugin-amqplib/src/consumer.js +40 -0
  40. package/packages/datadog-plugin-amqplib/src/index.js +14 -102
  41. package/packages/datadog-plugin-amqplib/src/producer.js +37 -0
  42. package/packages/datadog-plugin-amqplib/src/util.js +14 -0
  43. package/packages/datadog-plugin-cassandra-driver/src/index.js +22 -60
  44. package/packages/datadog-plugin-cucumber/src/index.js +14 -33
  45. package/packages/datadog-plugin-cypress/src/plugin.js +2 -1
  46. package/packages/datadog-plugin-dns/src/index.js +16 -91
  47. package/packages/datadog-plugin-dns/src/lookup.js +40 -0
  48. package/packages/datadog-plugin-dns/src/lookup_service.js +24 -0
  49. package/packages/datadog-plugin-dns/src/resolve.js +24 -0
  50. package/packages/datadog-plugin-dns/src/reverse.js +21 -0
  51. package/packages/datadog-plugin-elasticsearch/src/index.js +24 -60
  52. package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +24 -0
  53. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +41 -0
  54. package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +14 -99
  55. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +33 -0
  56. package/packages/datadog-plugin-graphql/src/execute.js +73 -0
  57. package/packages/datadog-plugin-graphql/src/index.js +14 -176
  58. package/packages/datadog-plugin-graphql/src/parse.js +32 -0
  59. package/packages/datadog-plugin-graphql/src/resolve.js +70 -76
  60. package/packages/datadog-plugin-graphql/src/validate.js +28 -0
  61. package/packages/datadog-plugin-grpc/src/client.js +46 -55
  62. package/packages/datadog-plugin-grpc/src/index.js +7 -24
  63. package/packages/datadog-plugin-grpc/src/server.js +50 -52
  64. package/packages/datadog-plugin-grpc/src/util.js +15 -14
  65. package/packages/datadog-plugin-http/src/client.js +15 -5
  66. package/packages/datadog-plugin-http/src/index.js +7 -22
  67. package/packages/datadog-plugin-http/src/server.js +19 -3
  68. package/packages/datadog-plugin-http2/src/client.js +20 -1
  69. package/packages/datadog-plugin-http2/src/index.js +8 -26
  70. package/packages/datadog-plugin-http2/src/server.js +44 -0
  71. package/packages/datadog-plugin-jest/src/index.js +41 -65
  72. package/packages/datadog-plugin-kafkajs/src/consumer.js +42 -0
  73. package/packages/datadog-plugin-kafkajs/src/index.js +11 -87
  74. package/packages/datadog-plugin-kafkajs/src/producer.js +31 -0
  75. package/packages/datadog-plugin-mariadb/src/index.js +10 -0
  76. package/packages/datadog-plugin-memcached/src/index.js +17 -52
  77. package/packages/datadog-plugin-mocha/src/index.js +40 -60
  78. package/packages/datadog-plugin-moleculer/src/client.js +22 -36
  79. package/packages/datadog-plugin-moleculer/src/index.js +8 -26
  80. package/packages/datadog-plugin-moleculer/src/server.js +18 -30
  81. package/packages/datadog-plugin-mongodb-core/src/index.js +23 -51
  82. package/packages/datadog-plugin-mysql/src/index.js +23 -52
  83. package/packages/datadog-plugin-mysql2/src/index.js +1 -3
  84. package/packages/datadog-plugin-net/src/index.js +4 -0
  85. package/packages/datadog-plugin-net/src/ipc.js +21 -0
  86. package/packages/datadog-plugin-net/src/tcp.js +46 -0
  87. package/packages/datadog-plugin-next/src/index.js +3 -0
  88. package/packages/datadog-plugin-opensearch/src/index.js +11 -0
  89. package/packages/datadog-plugin-oracledb/src/index.js +29 -55
  90. package/packages/datadog-plugin-pg/src/index.js +27 -51
  91. package/packages/datadog-plugin-redis/src/index.js +29 -60
  92. package/packages/datadog-plugin-rhea/src/consumer.js +55 -0
  93. package/packages/datadog-plugin-rhea/src/index.js +11 -96
  94. package/packages/datadog-plugin-rhea/src/producer.js +45 -0
  95. package/packages/datadog-plugin-router/src/index.js +13 -2
  96. package/packages/datadog-plugin-sharedb/src/index.js +22 -39
  97. package/packages/datadog-plugin-tedious/src/index.js +20 -41
  98. package/packages/dd-trace/src/appsec/addresses.js +3 -1
  99. package/packages/dd-trace/src/appsec/blocking.js +44 -0
  100. package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +8 -6
  101. package/packages/dd-trace/src/appsec/gateway/engine/engine.js +1 -1
  102. package/packages/dd-trace/src/appsec/gateway/engine/index.js +7 -2
  103. package/packages/dd-trace/src/appsec/gateway/engine/runner.js +0 -1
  104. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +4 -1
  105. package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +11 -0
  106. package/packages/dd-trace/src/appsec/iast/analyzers/injection-analyzer.js +19 -0
  107. package/packages/dd-trace/src/appsec/iast/analyzers/ldap-injection-analyzer.js +11 -0
  108. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +13 -0
  109. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +43 -5
  110. package/packages/dd-trace/src/appsec/iast/iast-context.js +3 -1
  111. package/packages/dd-trace/src/appsec/iast/index.js +24 -8
  112. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +20 -1
  113. package/packages/dd-trace/src/appsec/iast/path-line.js +17 -6
  114. package/packages/dd-trace/src/appsec/iast/taint-tracking/csi-methods.js +17 -0
  115. package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +16 -0
  116. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +18 -0
  117. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +98 -0
  118. package/packages/dd-trace/src/appsec/iast/taint-tracking/origin-types.js +4 -0
  119. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +38 -0
  120. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +67 -0
  121. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +103 -0
  122. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +98 -30
  123. package/packages/dd-trace/src/appsec/index.js +79 -25
  124. package/packages/dd-trace/src/{plugins/util → appsec}/ip_blocklist.js +0 -0
  125. package/packages/dd-trace/src/appsec/ip_extractor.js +98 -0
  126. package/packages/dd-trace/src/appsec/recommended.json +134 -53
  127. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +7 -0
  128. package/packages/dd-trace/src/appsec/remote_config/index.js +56 -0
  129. package/packages/dd-trace/src/appsec/remote_config/manager.js +264 -0
  130. package/packages/dd-trace/src/{exporters → appsec/remote_config}/scheduler.js +9 -9
  131. package/packages/dd-trace/src/appsec/rule_manager.js +61 -1
  132. package/packages/dd-trace/src/appsec/templates/blocked.html +99 -0
  133. package/packages/dd-trace/src/appsec/templates/blocked.json +8 -0
  134. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +66 -0
  135. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +9 -5
  136. package/packages/dd-trace/src/ci-visibility/exporters/agentless/index.js +19 -51
  137. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +10 -5
  138. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +202 -0
  139. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +51 -62
  140. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +89 -0
  141. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +82 -0
  142. package/packages/dd-trace/src/config.js +119 -35
  143. package/packages/dd-trace/src/constants.js +9 -1
  144. package/packages/dd-trace/src/dogstatsd.js +42 -10
  145. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +10 -2
  146. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +0 -1
  147. package/packages/dd-trace/src/exporter.js +3 -0
  148. package/packages/dd-trace/src/exporters/agent/index.js +10 -2
  149. package/packages/dd-trace/src/exporters/agent/writer.js +2 -9
  150. package/packages/dd-trace/src/exporters/common/agent-info-exporter.js +82 -0
  151. package/packages/dd-trace/src/exporters/common/request.js +51 -1
  152. package/packages/dd-trace/src/exporters/span-stats/index.js +6 -2
  153. package/packages/dd-trace/src/format.js +29 -10
  154. package/packages/dd-trace/src/lambda/handler.js +72 -0
  155. package/packages/dd-trace/src/lambda/index.js +5 -0
  156. package/packages/dd-trace/src/lambda/runtime/errors.js +20 -0
  157. package/packages/dd-trace/src/lambda/runtime/patch.js +74 -0
  158. package/packages/dd-trace/src/lambda/runtime/ritm.js +138 -0
  159. package/packages/dd-trace/src/metrics.js +15 -2
  160. package/packages/dd-trace/src/opentracing/propagation/text_map.js +1 -5
  161. package/packages/dd-trace/src/opentracing/span.js +2 -1
  162. package/packages/dd-trace/src/opentracing/span_context.js +9 -0
  163. package/packages/dd-trace/src/plugin_manager.js +11 -17
  164. package/packages/dd-trace/src/plugins/cache.js +9 -0
  165. package/packages/dd-trace/src/plugins/ci_plugin.js +97 -0
  166. package/packages/dd-trace/src/plugins/client.js +9 -0
  167. package/packages/dd-trace/src/plugins/composite.js +26 -0
  168. package/packages/dd-trace/src/plugins/consumer.js +9 -0
  169. package/packages/dd-trace/src/plugins/database.js +55 -0
  170. package/packages/dd-trace/src/plugins/incoming.js +7 -0
  171. package/packages/dd-trace/src/plugins/index.js +3 -0
  172. package/packages/dd-trace/src/plugins/log_plugin.js +2 -2
  173. package/packages/dd-trace/src/plugins/outgoing.js +31 -0
  174. package/packages/dd-trace/src/plugins/plugin.js +3 -0
  175. package/packages/dd-trace/src/plugins/producer.js +9 -0
  176. package/packages/dd-trace/src/plugins/server.js +9 -0
  177. package/packages/dd-trace/src/plugins/storage.js +21 -0
  178. package/packages/dd-trace/src/plugins/tracing.js +94 -0
  179. package/packages/dd-trace/src/plugins/util/ci.js +40 -4
  180. package/packages/dd-trace/src/plugins/util/git.js +58 -18
  181. package/packages/dd-trace/src/plugins/util/test.js +71 -8
  182. package/packages/dd-trace/src/plugins/util/user-provided-git.js +14 -1
  183. package/packages/dd-trace/src/plugins/util/web.js +11 -114
  184. package/packages/dd-trace/src/priority_sampler.js +6 -2
  185. package/packages/dd-trace/src/profiling/config.js +11 -6
  186. package/packages/dd-trace/src/profiling/exporters/agent.js +4 -0
  187. package/packages/dd-trace/src/profiling/index.js +2 -2
  188. package/packages/dd-trace/src/profiling/profiler.js +43 -7
  189. package/packages/dd-trace/src/proxy.js +8 -16
  190. package/packages/dd-trace/src/ritm.js +25 -14
  191. package/packages/dd-trace/src/span_processor.js +17 -0
  192. package/packages/dd-trace/src/span_sampler.js +77 -0
  193. package/packages/dd-trace/src/span_stats.js +2 -2
  194. package/packages/dd-trace/src/telemetry/dependencies.js +21 -7
  195. package/packages/dd-trace/src/telemetry/index.js +7 -1
  196. package/packages/dd-trace/src/telemetry/send-data.js +3 -1
  197. package/packages/dd-trace/src/tracer.js +10 -5
  198. package/packages/dd-trace/src/util.js +43 -1
@@ -1,65 +1,41 @@
1
1
  'use strict'
2
2
 
3
- const Plugin = require('../../dd-trace/src/plugins/plugin')
4
- const { storage } = require('../../datadog-core')
5
- const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
6
-
7
- class PGPlugin extends Plugin {
8
- static get name () {
9
- return 'pg'
10
- }
11
-
12
- constructor (...args) {
13
- super(...args)
14
-
15
- this.addSub(`apm:pg:query:start`, ({ params, statement }) => {
16
- const service = getServiceName(this.tracer, this.config, params)
17
- const store = storage.getStore()
18
- const childOf = store ? store.span : store
19
- const span = this.tracer.startSpan('pg.query', {
20
- childOf,
21
- tags: {
22
- 'service.name': service,
23
- 'span.type': 'sql',
24
- 'span.kind': 'client',
25
- 'db.type': 'postgres',
26
- 'resource.name': statement
27
- }
28
- })
29
-
30
- if (params) {
31
- span.addTags({
32
- 'db.name': params.database,
33
- 'db.user': params.user,
34
- 'out.host': params.host,
35
- 'out.port': params.port
36
- })
3
+ const DatabasePlugin = require('../../dd-trace/src/plugins/database')
4
+
5
+ class PGPlugin extends DatabasePlugin {
6
+ static get name () { return 'pg' }
7
+ static get operation () { return 'query' }
8
+ static get system () { return 'postgres' }
9
+
10
+ start ({ params = {}, query, processId }) {
11
+ const service = getServiceName(this.config, params)
12
+ const originalStatement = query.text
13
+
14
+ this.startSpan('pg.query', {
15
+ service,
16
+ resource: originalStatement,
17
+ type: 'sql',
18
+ kind: 'client',
19
+ meta: {
20
+ 'db.type': 'postgres',
21
+ 'db.pid': processId,
22
+ 'db.name': params.database,
23
+ 'db.user': params.user,
24
+ 'out.host': params.host,
25
+ 'out.port': params.port
37
26
  }
38
-
39
- analyticsSampler.sample(span, this.config.measured)
40
- this.enter(span, store)
41
- })
42
-
43
- this.addSub(`apm:pg:query:error`, err => {
44
- const span = storage.getStore().span
45
- span.setTag('error', err)
46
27
  })
47
28
 
48
- this.addSub(`apm:pg:query:finish`, () => {
49
- const span = storage.getStore().span
50
- span.finish()
51
- })
29
+ query.text = this.injectDbmQuery(query.text, service)
52
30
  }
53
31
  }
54
32
 
55
- function getServiceName (tracer, config, params) {
33
+ function getServiceName (config, params) {
56
34
  if (typeof config.service === 'function') {
57
35
  return config.service(params)
58
- } else if (config.service) {
59
- return config.service
60
- } else {
61
- return `${tracer._service}-postgres`
62
36
  }
37
+
38
+ return config.service
63
39
  }
64
40
 
65
41
  module.exports = PGPlugin
@@ -1,68 +1,27 @@
1
1
  'use strict'
2
2
 
3
- const Plugin = require('../../dd-trace/src/plugins/plugin')
4
- const { storage } = require('../../datadog-core')
5
- const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
3
+ const CachePlugin = require('../../dd-trace/src/plugins/cache')
6
4
  const urlFilter = require('../../dd-trace/src/plugins/util/urlfilter')
7
5
 
8
- class RedisPlugin extends Plugin {
9
- static get name () {
10
- return 'redis'
11
- }
12
-
13
- constructor (...args) {
14
- super(...args)
15
-
16
- this.addSub(`apm:${this.constructor.name}:command:start`, (
17
- { db, command, args, connectionOptions, connectionName }
18
- ) => {
19
- if (!this.config.filter(command)) {
20
- return this.skip()
21
- }
22
- const store = storage.getStore()
23
- const childOf = store ? store.span : store
24
- const span = this.tracer.startSpan('redis.command', {
25
- childOf,
26
- tags: {
27
- 'span.kind': 'client',
28
- 'resource.name': command,
29
- 'span.type': 'redis',
30
- 'db.type': 'redis',
31
- 'db.name': db || '0',
32
- 'redis.raw_command': formatCommand(command, args)
33
- }
34
- })
35
-
36
- span.setTag('service.name', this.config.service || `${span.context()._tags['service.name']}-redis`)
37
-
38
- analyticsSampler.sample(span, this.config.measured)
39
-
40
- if (connectionOptions) {
41
- span.addTags({
42
- 'out.host': connectionOptions.host,
43
- 'out.port': connectionOptions.port
44
- })
6
+ class RedisPlugin extends CachePlugin {
7
+ static get name () { return 'redis' }
8
+ static get system () { return 'redis' }
9
+
10
+ start ({ db, command, args, connectionOptions = {}, connectionName }) {
11
+ if (!this.config.filter(command)) return this.skip()
12
+
13
+ this.startSpan('redis.command', {
14
+ service: getService(this.config, connectionName),
15
+ resource: command,
16
+ type: 'redis',
17
+ kind: 'client',
18
+ meta: {
19
+ 'db.type': 'redis',
20
+ 'db.name': db || '0',
21
+ 'redis.raw_command': formatCommand(command, args),
22
+ 'out.host': connectionOptions.host,
23
+ 'out.port': connectionOptions.port
45
24
  }
46
-
47
- if (this.config.splitByInstance && connectionName) {
48
- const service = this.config.service
49
- ? `${this.config.service}-${connectionName}`
50
- : connectionName
51
-
52
- span.setTag('service.name', service)
53
- }
54
-
55
- this.enter(span, store)
56
- })
57
-
58
- this.addSub(`apm:${this.constructor.name}:command:error`, err => {
59
- const span = storage.getStore().span
60
- span.setTag('error', err)
61
- })
62
-
63
- this.addSub(`apm:${this.constructor.name}:command:finish`, () => {
64
- const span = storage.getStore().span
65
- span.finish()
66
25
  })
67
26
  }
68
27
 
@@ -71,6 +30,16 @@ class RedisPlugin extends Plugin {
71
30
  }
72
31
  }
73
32
 
33
+ function getService (config, connectionName) {
34
+ if (config.splitByInstance && connectionName) {
35
+ return config.service
36
+ ? `${config.service}-${connectionName}`
37
+ : connectionName
38
+ }
39
+
40
+ return config.service
41
+ }
42
+
74
43
  function formatCommand (command, args) {
75
44
  command = command.toUpperCase()
76
45
 
@@ -0,0 +1,55 @@
1
+ 'use strict'
2
+
3
+ const ConsumerPlugin = require('../../dd-trace/src/plugins/consumer')
4
+ const { storage } = require('../../datadog-core')
5
+
6
+ class RheaConsumerPlugin extends ConsumerPlugin {
7
+ static get name () { return 'rhea' }
8
+
9
+ constructor (...args) {
10
+ super(...args)
11
+
12
+ this.addTraceSub('dispatch', ({ state }) => {
13
+ const span = storage.getStore().span
14
+ span.setTag('amqp.delivery.state', state)
15
+ })
16
+ }
17
+
18
+ start ({ msgObj }) {
19
+ const name = getResourceNameFromMessage(msgObj)
20
+ const childOf = extractTextMap(msgObj, this.tracer)
21
+
22
+ this.startSpan('amqp.receive', {
23
+ childOf,
24
+ service: this.config.service,
25
+ resource: name,
26
+ type: 'worker',
27
+ kind: 'consumer',
28
+ meta: {
29
+ 'component': 'rhea',
30
+ 'amqp.link.source.address': name,
31
+ 'amqp.link.role': 'receiver'
32
+ }
33
+ })
34
+ }
35
+ }
36
+
37
+ function getResourceNameFromMessage (msgObj) {
38
+ let resourceName = 'amq.topic'
39
+ let options = {}
40
+ if (msgObj.receiver && msgObj.receiver.options) {
41
+ options = msgObj.receiver.options
42
+ }
43
+ if (options.source && options.source.address) {
44
+ resourceName = options.source.address
45
+ }
46
+ return resourceName
47
+ }
48
+
49
+ function extractTextMap (msgObj, tracer) {
50
+ if (msgObj.message) {
51
+ return tracer.extract('text_map', msgObj.message.delivery_annotations)
52
+ }
53
+ }
54
+
55
+ module.exports = RheaConsumerPlugin
@@ -1,101 +1,16 @@
1
1
  'use strict'
2
2
 
3
- const Plugin = require('../../dd-trace/src/plugins/plugin')
4
- const { storage } = require('../../datadog-core')
5
- const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
6
-
7
- class RheaPlugin extends Plugin {
8
- static get name () {
9
- return 'rhea'
10
- }
11
-
12
- constructor (...args) {
13
- super(...args)
14
-
15
- this.addSub(`apm:rhea:send:start`, ({ targetAddress, host, port, msg }) => {
16
- const store = storage.getStore()
17
- const childOf = store ? store.span : store
18
- const name = targetAddress || 'amq.topic'
19
- const span = this.tracer.startSpan('amqp.send', {
20
- childOf,
21
- tags: {
22
- 'component': 'rhea',
23
- 'resource.name': name,
24
- 'service.name': this.config.service || `${this.tracer._service}-amqp-producer`,
25
- 'span.kind': 'producer',
26
- 'amqp.link.target.address': name,
27
- 'amqp.link.role': 'sender',
28
- 'out.host': host,
29
- 'out.port': port
30
- }
31
- })
32
- analyticsSampler.sample(span, this.config.measured)
33
- addDeliveryAnnotations(msg, this.tracer, span)
34
-
35
- this.enter(span, store)
36
- })
37
-
38
- this.addSub(`apm:rhea:receive:start`, ({ msgObj, connection }) => {
39
- const name = getResourceNameFromMessage(msgObj)
40
-
41
- const store = storage.getStore()
42
- const childOf = extractTextMap(msgObj, this.tracer)
43
- const span = this.tracer.startSpan('amqp.receive', {
44
- childOf,
45
- tags: {
46
- 'span.type': 'worker',
47
- 'component': 'rhea',
48
- 'resource.name': name,
49
- 'service.name': this.config.service || this.tracer._service,
50
- 'span.kind': 'consumer',
51
- 'amqp.link.source.address': name,
52
- 'amqp.link.role': 'receiver'
53
- }
54
- })
55
- analyticsSampler.sample(span, this.config.measured, true)
56
-
57
- this.enter(span, store)
58
- })
59
-
60
- this.addSub(`apm:rhea:error`, error => {
61
- storage.getStore().span.setTag('error', error)
62
- })
63
-
64
- this.addSub(`apm:rhea:finish`, () => {
65
- const span = storage.getStore().span
66
- span.finish()
67
- })
68
-
69
- this.addSub(`apm:rhea:dispatch`, ({ state }) => {
70
- const span = storage.getStore().span
71
- span.setTag('amqp.delivery.state', state)
72
- })
73
- }
74
- }
75
-
76
- function getResourceNameFromMessage (msgObj) {
77
- let resourceName = 'amq.topic'
78
- let options = {}
79
- if (msgObj.receiver && msgObj.receiver.options) {
80
- options = msgObj.receiver.options
81
- }
82
- if (options.source && options.source.address) {
83
- resourceName = options.source.address
84
- }
85
- return resourceName
86
- }
87
-
88
- function extractTextMap (msgObj, tracer) {
89
- if (msgObj.message) {
90
- return tracer.extract('text_map', msgObj.message.delivery_annotations)
91
- }
92
- }
93
-
94
- function addDeliveryAnnotations (msg, tracer, span) {
95
- if (msg) {
96
- msg.delivery_annotations = msg.delivery_annotations || {}
97
-
98
- tracer.inject(span, 'text_map', msg.delivery_annotations)
3
+ const ProducerPlugin = require('./producer')
4
+ const ConsumerPlugin = require('./consumer')
5
+ const CompositePlugin = require('../../dd-trace/src/plugins/composite')
6
+
7
+ class RheaPlugin extends CompositePlugin {
8
+ static get name () { return 'rhea' }
9
+ static get plugins () {
10
+ return {
11
+ producer: ProducerPlugin,
12
+ consumer: ConsumerPlugin
13
+ }
99
14
  }
100
15
  }
101
16
 
@@ -0,0 +1,45 @@
1
+ 'use strict'
2
+
3
+ const ProducerPlugin = require('../../dd-trace/src/plugins/producer')
4
+
5
+ class RheaProducerPlugin extends ProducerPlugin {
6
+ static get name () { return 'rhea' }
7
+ static get operation () { return 'send' }
8
+
9
+ constructor (...args) {
10
+ super(...args)
11
+
12
+ this.addTraceSub('encode', this.encode.bind(this))
13
+ }
14
+
15
+ start ({ targetAddress, host, port }) {
16
+ const name = targetAddress || 'amq.topic'
17
+
18
+ this.startSpan('amqp.send', {
19
+ service: this.config.service || `${this.tracer._service}-amqp-producer`,
20
+ resource: name,
21
+ kind: 'producer',
22
+ meta: {
23
+ 'component': 'rhea',
24
+ 'amqp.link.target.address': name,
25
+ 'amqp.link.role': 'sender',
26
+ 'out.host': host,
27
+ 'out.port': port
28
+ }
29
+ })
30
+ }
31
+
32
+ encode (msg) {
33
+ addDeliveryAnnotations(msg, this.tracer, this.activeSpan)
34
+ }
35
+ }
36
+
37
+ function addDeliveryAnnotations (msg, tracer, span) {
38
+ if (msg) {
39
+ msg.delivery_annotations = msg.delivery_annotations || {}
40
+
41
+ tracer.inject(span, 'text_map', msg.delivery_annotations)
42
+ }
43
+ }
44
+
45
+ module.exports = RheaProducerPlugin
@@ -4,6 +4,7 @@ const web = require('../../dd-trace/src/plugins/util/web')
4
4
  const WebPlugin = require('../../datadog-plugin-web/src')
5
5
  const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
6
6
  const { storage } = require('../../datadog-core')
7
+ const { COMPONENT } = require('../../dd-trace/src/constants')
7
8
 
8
9
  class RouterPlugin extends WebPlugin {
9
10
  static get name () {
@@ -13,6 +14,7 @@ class RouterPlugin extends WebPlugin {
13
14
  constructor (...args) {
14
15
  super(...args)
15
16
 
17
+ this._storeStack = []
16
18
  this._contexts = new WeakMap()
17
19
 
18
20
  this.addSub(`apm:${this.constructor.name}:middleware:enter`, ({ req, name, route }) => {
@@ -27,7 +29,9 @@ class RouterPlugin extends WebPlugin {
27
29
  context.middleware.push(span)
28
30
  }
29
31
 
30
- this.enter(span)
32
+ const store = storage.getStore()
33
+ this._storeStack.push(store)
34
+ this.enter(span, store)
31
35
 
32
36
  web.patch(req)
33
37
  web.setRoute(req, context.route)
@@ -41,7 +45,7 @@ class RouterPlugin extends WebPlugin {
41
45
  context.stack.pop()
42
46
  })
43
47
 
44
- this.addSub(`apm:${this.constructor.name}:middleware:exit`, ({ req }) => {
48
+ this.addSub(`apm:${this.constructor.name}:middleware:finish`, ({ req }) => {
45
49
  const context = this._contexts.get(req)
46
50
 
47
51
  if (!context || context.middleware.length === 0) return
@@ -49,6 +53,12 @@ class RouterPlugin extends WebPlugin {
49
53
  context.middleware.pop().finish()
50
54
  })
51
55
 
56
+ this.addSub(`apm:${this.constructor.name}:middleware:exit`, ({ req }) => {
57
+ const savedStore = this._storeStack.pop()
58
+ const span = savedStore && savedStore.span
59
+ this.enter(span, savedStore)
60
+ })
61
+
52
62
  this.addSub(`apm:${this.constructor.name}:middleware:error`, ({ req, error }) => {
53
63
  web.addError(req, error)
54
64
 
@@ -97,6 +107,7 @@ class RouterPlugin extends WebPlugin {
97
107
  const span = this.tracer.startSpan(`${this.constructor.name}.middleware`, {
98
108
  childOf,
99
109
  tags: {
110
+ [COMPONENT]: this.constructor.name,
100
111
  'resource.name': name || '<anonymous>'
101
112
  }
102
113
  })
@@ -1,48 +1,31 @@
1
1
  'use strict'
2
2
 
3
- const Plugin = require('../../dd-trace/src/plugins/plugin')
4
- const { storage } = require('../../datadog-core')
5
-
6
- class SharedbPlugin extends Plugin {
7
- static get name () {
8
- return 'sharedb'
9
- }
10
-
11
- constructor (...args) {
12
- super(...args)
13
-
14
- this.addSub(`apm:sharedb:request:start`, ({ actionName, request }) => {
15
- const store = storage.getStore()
16
- const childOf = store ? store.span : store
17
- const span = this.tracer.startSpan('sharedb.request', {
18
- childOf,
19
- tags: {
20
- 'service.name': this.config.service || this.tracer._service,
21
- 'span.kind': 'server',
22
- 'sharedb.action': actionName,
23
- 'resource.name': getReadableResourceName(actionName, request.c, request.q)
24
- }
25
- })
26
-
27
- if (this.config.hooks && this.config.hooks.receive) {
28
- this.config.hooks.receive(span, request)
3
+ const ServerPlugin = require('../../dd-trace/src/plugins/server')
4
+
5
+ class SharedbPlugin extends ServerPlugin {
6
+ static get name () { return 'sharedb' }
7
+
8
+ start ({ actionName, request }) {
9
+ const span = this.startSpan('sharedb.request', {
10
+ service: this.config.service,
11
+ resource: getReadableResourceName(actionName, request.c, request.q),
12
+ kind: 'server',
13
+ meta: {
14
+ 'sharedb.action': actionName
29
15
  }
30
-
31
- this.enter(span, store)
32
16
  })
33
17
 
34
- this.addSub(`apm:sharedb:request:error`, err => {
35
- const span = storage.getStore().span
36
- span.setTag('error', err)
37
- })
18
+ if (this.config.hooks && this.config.hooks.receive) {
19
+ this.config.hooks.receive(span, request)
20
+ }
21
+ }
38
22
 
39
- this.addSub(`apm:sharedb:request:finish`, ({ request, res }) => {
40
- const span = storage.getStore().span
41
- if (this.config.hooks && this.config.hooks.reply) {
42
- this.config.hooks.reply(span, request, res)
43
- }
44
- span.finish()
45
- })
23
+ finish ({ request, res }) {
24
+ const span = this.activeSpan
25
+ if (this.config.hooks && this.config.hooks.reply) {
26
+ this.config.hooks.reply(span, request, res)
27
+ }
28
+ span.finish()
46
29
  }
47
30
  }
48
31
 
@@ -1,48 +1,27 @@
1
1
  'use strict'
2
2
 
3
- const Plugin = require('../../dd-trace/src/plugins/plugin')
4
- const { storage } = require('../../datadog-core')
5
- const analyticsSampler = require('../../dd-trace/src/analytics_sampler')
3
+ const DatabasePlugin = require('../../dd-trace/src/plugins/database')
6
4
 
7
- class TediousPlugin extends Plugin {
8
- static get name () {
9
- return 'tedious'
10
- }
11
-
12
- constructor (...args) {
13
- super(...args)
14
-
15
- this.addSub(`apm:tedious:request:start`, ({ queryOrProcedure, connectionConfig }) => {
16
- const store = storage.getStore()
17
- const childOf = store ? store.span : store
18
- const span = this.tracer.startSpan('tedious.request', {
19
- childOf,
20
- tags: {
21
- 'span.kind': 'client',
22
- 'db.type': 'mssql',
23
- 'span.type': 'sql',
24
- 'component': 'tedious',
25
- 'service.name': this.config.service || `${this.tracer._service}-mssql`,
26
- 'resource.name': queryOrProcedure,
27
- 'out.host': connectionConfig.server,
28
- 'out.port': connectionConfig.options.port,
29
- 'db.user': connectionConfig.userName || connectionConfig.authentication.options.userName,
30
- 'db.name': connectionConfig.options.database,
31
- 'db.instance': connectionConfig.options.instanceName
32
- }
33
- })
34
- analyticsSampler.sample(span, this.config.measured)
35
- this.enter(span, store)
36
- })
37
-
38
- this.addSub(`apm:tedious:request:error`, err => {
39
- const span = storage.getStore().span
40
- span.setTag('error', err)
41
- })
5
+ class TediousPlugin extends DatabasePlugin {
6
+ static get name () { return 'tedious' }
7
+ static get operation () { return 'request' } // TODO: change to match other database plugins
8
+ static get system () { return 'mssql' }
42
9
 
43
- this.addSub(`apm:tedious:request:finish`, () => {
44
- const span = storage.getStore().span
45
- span.finish()
10
+ start ({ queryOrProcedure, connectionConfig }) {
11
+ this.startSpan('tedious.request', {
12
+ service: this.config.service,
13
+ resource: queryOrProcedure,
14
+ type: 'sql',
15
+ kind: 'client',
16
+ meta: {
17
+ 'db.type': 'mssql',
18
+ 'component': 'tedious',
19
+ 'out.host': connectionConfig.server,
20
+ 'out.port': connectionConfig.options.port,
21
+ 'db.user': connectionConfig.userName || connectionConfig.authentication.options.userName,
22
+ 'db.name': connectionConfig.options.database,
23
+ 'db.instance': connectionConfig.options.instanceName
24
+ }
46
25
  })
47
26
  }
48
27
  }
@@ -14,5 +14,7 @@ module.exports = {
14
14
  HTTP_INCOMING_RESPONSE_HEADERS: 'server.response.headers.no_cookies',
15
15
  // TODO: 'server.response.trailers',
16
16
  HTTP_INCOMING_REMOTE_IP: 'server.request.client_ip',
17
- HTTP_INCOMING_REMOTE_PORT: 'server.request.client_port'
17
+ HTTP_INCOMING_REMOTE_PORT: 'server.request.client_port',
18
+
19
+ HTTP_CLIENT_IP: 'http.client_ip'
18
20
  }
@@ -0,0 +1,44 @@
1
+ 'use strict'
2
+
3
+ const fs = require('fs')
4
+ let templateHtml, templateJson
5
+ function block (req, res, topSpan, abortController) {
6
+ let type
7
+ let body
8
+
9
+ // parse the Accept header, ex: Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8
10
+ const accept = req.headers.accept && req.headers.accept.split(',').map((str) => str.split(';', 1)[0].trim())
11
+
12
+ if (accept && accept.includes('text/html') && !accept.includes('application/json')) {
13
+ type = 'text/html'
14
+ body = templateHtml
15
+ } else {
16
+ type = 'application/json'
17
+ body = templateJson
18
+ }
19
+
20
+ topSpan.addTags({
21
+ 'appsec.blocked': 'true'
22
+ })
23
+
24
+ res.statusCode = 403
25
+ res.setHeader('Content-Type', type)
26
+ res.setHeader('Content-Length', Buffer.byteLength(body))
27
+ res.end(body)
28
+
29
+ abortController.abort()
30
+ }
31
+
32
+ function loadTemplates (config) {
33
+ templateHtml = fs.readFileSync(config.appsec.blockedTemplateHtml)
34
+ templateJson = fs.readFileSync(config.appsec.blockedTemplateJson)
35
+ }
36
+
37
+ async function loadTemplatesAsync (config) {
38
+ templateHtml = await fs.promises.readFile(config.appsec.blockedTemplateHtml)
39
+ templateJson = await fs.promises.readFile(config.appsec.blockedTemplateJson)
40
+ }
41
+
42
+ module.exports = {
43
+ block, loadTemplates, loadTemplatesAsync
44
+ }