dd-trace 2.3.1 → 2.4.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 (33) hide show
  1. package/index.d.ts +51 -0
  2. package/package.json +2 -2
  3. package/packages/datadog-instrumentations/index.js +8 -0
  4. package/packages/datadog-instrumentations/src/amqp10.js +70 -0
  5. package/packages/datadog-instrumentations/src/amqplib.js +58 -0
  6. package/packages/datadog-instrumentations/src/cassandra-driver.js +191 -0
  7. package/packages/datadog-instrumentations/src/cucumber.js +2 -0
  8. package/packages/datadog-instrumentations/src/helpers/instrument.js +3 -3
  9. package/packages/datadog-instrumentations/src/mocha.js +122 -0
  10. package/packages/datadog-instrumentations/src/mongodb-core.js +179 -0
  11. package/packages/datadog-instrumentations/src/pg.js +75 -0
  12. package/packages/datadog-instrumentations/src/rhea.js +224 -0
  13. package/packages/datadog-instrumentations/src/tedious.js +66 -0
  14. package/packages/datadog-plugin-amqp10/src/index.js +79 -122
  15. package/packages/datadog-plugin-amqplib/src/index.js +77 -142
  16. package/packages/datadog-plugin-cassandra-driver/src/index.js +52 -224
  17. package/packages/datadog-plugin-cucumber/src/index.js +3 -1
  18. package/packages/datadog-plugin-jest/src/jest-jasmine2.js +5 -3
  19. package/packages/datadog-plugin-mocha/src/index.js +96 -207
  20. package/packages/datadog-plugin-mongodb-core/src/index.js +119 -3
  21. package/packages/datadog-plugin-pg/src/index.js +32 -69
  22. package/packages/datadog-plugin-rhea/src/index.js +59 -225
  23. package/packages/datadog-plugin-tedious/src/index.js +38 -86
  24. package/packages/dd-trace/lib/version.js +1 -1
  25. package/packages/dd-trace/src/appsec/recommended.json +137 -116
  26. package/packages/dd-trace/src/config.js +6 -0
  27. package/packages/dd-trace/src/noop/tracer.js +4 -0
  28. package/packages/dd-trace/src/opentracing/propagation/text_map.js +34 -1
  29. package/packages/dd-trace/src/proxy.js +4 -0
  30. package/packages/dd-trace/src/tracer.js +16 -0
  31. package/packages/datadog-plugin-mongodb-core/src/legacy.js +0 -59
  32. package/packages/datadog-plugin-mongodb-core/src/unified.js +0 -138
  33. package/packages/datadog-plugin-mongodb-core/src/util.js +0 -143
@@ -1,9 +1,12 @@
1
1
  {
2
- "version": "2.1",
2
+ "version": "2.2",
3
+ "metadata": {
4
+ "rules_version": "1.2.6"
5
+ },
3
6
  "rules": [
4
7
  {
5
8
  "id": "crs-913-110",
6
- "name": "Found request header associated with Acunetix security scanner",
9
+ "name": "Acunetix",
7
10
  "tags": {
8
11
  "type": "security_scanner",
9
12
  "crs_id": "913110",
@@ -21,7 +24,8 @@
21
24
  "acunetix-product",
22
25
  "(acunetix web vulnerability scanner",
23
26
  "acunetix-scanning-agreement",
24
- "acunetix-user-agreement"
27
+ "acunetix-user-agreement",
28
+ "md5(acunetix_wvs_security_test)"
25
29
  ]
26
30
  },
27
31
  "operator": "phrase_match"
@@ -33,7 +37,7 @@
33
37
  },
34
38
  {
35
39
  "id": "crs-913-120",
36
- "name": "Found request filename/argument associated with security scanner",
40
+ "name": "Known security scanner filename/argument",
37
41
  "tags": {
38
42
  "type": "security_scanner",
39
43
  "crs_id": "913120",
@@ -228,7 +232,9 @@
228
232
  "operator": "match_regex"
229
233
  }
230
234
  ],
231
- "transformers": []
235
+ "transformers": [
236
+ "normalizePath"
237
+ ]
232
238
  },
233
239
  {
234
240
  "id": "crs-930-110",
@@ -1400,12 +1406,13 @@
1400
1406
  }
1401
1407
  ],
1402
1408
  "transformers": [
1403
- "lowercase"
1409
+ "lowercase",
1410
+ "normalizePath"
1404
1411
  ]
1405
1412
  },
1406
1413
  {
1407
1414
  "id": "crs-931-110",
1408
- "name": "Possible Remote File Inclusion (RFI) Attack: Common RFI Vulnerable Parameter Name used w/URL Payload",
1415
+ "name": "RFI: Common RFI Vulnerable Parameter Name used w/ URL Payload",
1409
1416
  "tags": {
1410
1417
  "type": "rfi",
1411
1418
  "crs_id": "931110",
@@ -1431,7 +1438,7 @@
1431
1438
  },
1432
1439
  {
1433
1440
  "id": "crs-931-120",
1434
- "name": "Possible Remote File Inclusion (RFI) Attack: URL Payload Used w/Trailing Question Mark Character (?)",
1441
+ "name": "RFI: URL Payload Used w/Trailing Question Mark Character (?)",
1435
1442
  "tags": {
1436
1443
  "type": "rfi",
1437
1444
  "crs_id": "931120",
@@ -2867,44 +2874,6 @@
2867
2874
  "removeNulls"
2868
2875
  ]
2869
2876
  },
2870
- {
2871
- "id": "crs-942-140",
2872
- "name": "SQL Injection Attack: Common DB Names Detected",
2873
- "tags": {
2874
- "type": "sql_injection",
2875
- "crs_id": "942140",
2876
- "category": "attack_attempt"
2877
- },
2878
- "conditions": [
2879
- {
2880
- "parameters": {
2881
- "inputs": [
2882
- {
2883
- "address": "server.request.cookies"
2884
- },
2885
- {
2886
- "address": "server.request.query"
2887
- },
2888
- {
2889
- "address": "server.request.body"
2890
- },
2891
- {
2892
- "address": "server.request.path_params"
2893
- },
2894
- {
2895
- "address": "grpc.server.request.message"
2896
- }
2897
- ],
2898
- "regex": "\\b(?:(?:m(?:s(?:ys(?:ac(?:cess(?:objects|storage|xml)|es)|(?:relationship|object|querie)s|modules2?)|db)|aster\\.\\.sysdatabases|ysql\\.db)|pg_(?:catalog|toast)|information_schema|northwind|tempdb)\\b|s(?:(?:ys(?:\\.database_name|aux)|qlite(?:_temp)?_master)\\b|chema(?:_name\\b|\\W*\\())|d(?:atabas|b_nam)e\\W*\\()",
2899
- "options": {
2900
- "min_length": 4
2901
- }
2902
- },
2903
- "operator": "match_regex"
2904
- }
2905
- ],
2906
- "transformers": []
2907
- },
2908
2877
  {
2909
2878
  "id": "crs-942-160",
2910
2879
  "name": "Detects blind sqli tests using sleep() or benchmark()",
@@ -2982,45 +2951,6 @@
2982
2951
  ],
2983
2952
  "transformers": []
2984
2953
  },
2985
- {
2986
- "id": "crs-942-220",
2987
- "name": "Looking for integer overflow attacks, these are taken from skipfish, except 2.2.2250738585072011e-308 is the \\\"magic number\\\" crash",
2988
- "tags": {
2989
- "type": "sql_injection",
2990
- "crs_id": "942220",
2991
- "category": "attack_attempt"
2992
- },
2993
- "conditions": [
2994
- {
2995
- "parameters": {
2996
- "inputs": [
2997
- {
2998
- "address": "server.request.cookies"
2999
- },
3000
- {
3001
- "address": "server.request.query"
3002
- },
3003
- {
3004
- "address": "server.request.body"
3005
- },
3006
- {
3007
- "address": "server.request.path_params"
3008
- },
3009
- {
3010
- "address": "grpc.server.request.message"
3011
- }
3012
- ],
3013
- "regex": "^(?i:-0000023456|4294967295|4294967296|2147483648|2147483647|0000012345|-2147483648|-2147483649|0000023456|2.2250738585072007e-308|2.2250738585072011e-308|1e309)$",
3014
- "options": {
3015
- "case_sensitive": true,
3016
- "min_length": 5
3017
- }
3018
- },
3019
- "operator": "match_regex"
3020
- }
3021
- ],
3022
- "transformers": []
3023
- },
3024
2954
  {
3025
2955
  "id": "crs-942-240",
3026
2956
  "name": "Detects MySQL charset switch and MSSQL DoS attempts",
@@ -3100,7 +3030,7 @@
3100
3030
  },
3101
3031
  {
3102
3032
  "id": "crs-942-270",
3103
- "name": "Looking for basic sql injection. Common attack string for mysql, oracle and others",
3033
+ "name": "Basic SQL injection",
3104
3034
  "tags": {
3105
3035
  "type": "sql_injection",
3106
3036
  "crs_id": "942270",
@@ -3138,7 +3068,7 @@
3138
3068
  },
3139
3069
  {
3140
3070
  "id": "crs-942-280",
3141
- "name": "Detects Postgres pg_sleep injection, waitfor delay attacks and database shutdown attempts",
3071
+ "name": "SQL Injection with delay functions",
3142
3072
  "tags": {
3143
3073
  "type": "sql_injection",
3144
3074
  "crs_id": "942280",
@@ -3528,6 +3458,116 @@
3528
3458
  "lowercase"
3529
3459
  ]
3530
3460
  },
3461
+ {
3462
+ "id": "dog-000-001",
3463
+ "name": "Look for Cassandra injections",
3464
+ "tags": {
3465
+ "type": "nosql_injection",
3466
+ "category": "attack_attempt"
3467
+ },
3468
+ "conditions": [
3469
+ {
3470
+ "parameters": {
3471
+ "inputs": [
3472
+ {
3473
+ "address": "server.request.query"
3474
+ },
3475
+ {
3476
+ "address": "server.request.body"
3477
+ },
3478
+ {
3479
+ "address": "server.request.path_params"
3480
+ },
3481
+ {
3482
+ "address": "server.request.headers.no_cookies"
3483
+ }
3484
+ ],
3485
+ "regex": "\\ballow\\s+filtering\\b"
3486
+ },
3487
+ "operator": "match_regex"
3488
+ }
3489
+ ],
3490
+ "transformers": [
3491
+ "removeComments"
3492
+ ]
3493
+ },
3494
+ {
3495
+ "id": "dog-000-002",
3496
+ "name": "OGNL - Look for formatting injection patterns",
3497
+ "tags": {
3498
+ "type": "java_code_injection",
3499
+ "category": "attack_attempt"
3500
+ },
3501
+ "conditions": [
3502
+ {
3503
+ "operator": "match_regex",
3504
+ "parameters": {
3505
+ "inputs": [
3506
+ {
3507
+ "address": "server.request.cookies"
3508
+ },
3509
+ {
3510
+ "address": "server.request.query"
3511
+ },
3512
+ {
3513
+ "address": "server.request.body"
3514
+ },
3515
+ {
3516
+ "address": "server.request.path_params"
3517
+ },
3518
+ {
3519
+ "address": "grpc.server.request.message"
3520
+ }
3521
+ ],
3522
+ "regex": "[#%$]{[^}]+[^\\w\\s][^}]+}",
3523
+ "options": {
3524
+ "case_sensitive": true
3525
+ }
3526
+ }
3527
+ }
3528
+ ],
3529
+ "transformers": []
3530
+ },
3531
+ {
3532
+ "id": "dog-000-003",
3533
+ "name": "OGNL - Detect OGNL exploitation primitives",
3534
+ "tags": {
3535
+ "type": "java_code_injection",
3536
+ "category": "attack_attempt"
3537
+ },
3538
+ "conditions": [
3539
+ {
3540
+ "operator": "match_regex",
3541
+ "parameters": {
3542
+ "inputs": [
3543
+ {
3544
+ "address": "server.request.cookies"
3545
+ },
3546
+ {
3547
+ "address": "server.request.query"
3548
+ },
3549
+ {
3550
+ "address": "server.request.body"
3551
+ },
3552
+ {
3553
+ "address": "server.request.path_params"
3554
+ },
3555
+ {
3556
+ "address": "server.request.headers.no_cookies"
3557
+ },
3558
+ {
3559
+ "address": "grpc.server.request.message"
3560
+ }
3561
+ ],
3562
+ "regex": "[@#]ognl",
3563
+ "options": {
3564
+ "case_sensitive": true
3565
+ }
3566
+ }
3567
+ }
3568
+ ],
3569
+ "transformers": []
3570
+ },
3531
3571
  {
3532
3572
  "id": "nfd-000-001",
3533
3573
  "name": "Detect common directory discovery scans",
@@ -5229,31 +5269,6 @@
5229
5269
  ],
5230
5270
  "transformers": []
5231
5271
  },
5232
- {
5233
- "id": "ua0-600-41x",
5234
- "name": "Acunetix",
5235
- "tags": {
5236
- "type": "security_scanner",
5237
- "category": "attack_attempt"
5238
- },
5239
- "conditions": [
5240
- {
5241
- "parameters": {
5242
- "inputs": [
5243
- {
5244
- "address": "server.request.headers.no_cookies",
5245
- "key_path": [
5246
- "user-agent"
5247
- ]
5248
- }
5249
- ],
5250
- "regex": "md5\\(acunetix_wvs_security_test\\)"
5251
- },
5252
- "operator": "match_regex"
5253
- }
5254
- ],
5255
- "transformers": []
5256
- },
5257
5272
  {
5258
5273
  "id": "ua0-600-42x",
5259
5274
  "name": "OpenVAS",
@@ -5506,7 +5521,7 @@
5506
5521
  },
5507
5522
  {
5508
5523
  "id": "ua0-600-52x",
5509
- "name": "Nuclei is a fast tool for configurable targeted scanning based on templates offering massive extensibility and ease of use",
5524
+ "name": "Nuclei",
5510
5525
  "tags": {
5511
5526
  "type": "security_scanner",
5512
5527
  "category": "attack_attempt"
@@ -5531,7 +5546,7 @@
5531
5546
  },
5532
5547
  {
5533
5548
  "id": "ua0-600-53x",
5534
- "name": "Tsunami is a general purpose network security scanner with an extensible plugin system for detecting high severity vulnerabilities with high confidence",
5549
+ "name": "Tsunami",
5535
5550
  "tags": {
5536
5551
  "type": "security_scanner",
5537
5552
  "category": "attack_attempt"
@@ -5556,7 +5571,7 @@
5556
5571
  },
5557
5572
  {
5558
5573
  "id": "ua0-600-54x",
5559
- "name": "Nimbostratus is a vulnerability scanner that scan websites unprompted",
5574
+ "name": "Nimbostratus",
5560
5575
  "tags": {
5561
5576
  "type": "security_scanner",
5562
5577
  "category": "attack_attempt"
@@ -5595,6 +5610,12 @@
5595
5610
  "key_path": [
5596
5611
  "user-agent"
5597
5612
  ]
5613
+ },
5614
+ {
5615
+ "address": "grpc.server.request.metadata",
5616
+ "key_path": [
5617
+ "dd-canary"
5618
+ ]
5598
5619
  }
5599
5620
  ],
5600
5621
  "regex": "^dd-test-scanner-log$"
@@ -5606,7 +5627,7 @@
5606
5627
  },
5607
5628
  {
5608
5629
  "id": "ua0-600-5xx",
5609
- "name": "Blind Sql Injection Brute Forcer",
5630
+ "name": "Blind SQL Injection Brute Forcer",
5610
5631
  "tags": {
5611
5632
  "type": "security_scanner",
5612
5633
  "category": "attack_attempt"
@@ -109,6 +109,11 @@ class Config {
109
109
  process.env.DD_TRACE_EXPERIMENTAL_B3_ENABLED,
110
110
  false
111
111
  )
112
+ const DD_TRACE_TRACEPARENT_ENABLED = coalesce(
113
+ options.experimental && options.experimental.traceparent,
114
+ process.env.DD_TRACE_EXPERIMENTAL_TRACEPARENT_ENABLED,
115
+ false
116
+ )
112
117
  const DD_TRACE_RUNTIME_ID_ENABLED = coalesce(
113
118
  options.experimental && options.experimental.runtimeId,
114
119
  process.env.DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED,
@@ -187,6 +192,7 @@ class Config {
187
192
  this.runtimeMetrics = isTrue(DD_RUNTIME_METRICS_ENABLED)
188
193
  this.experimental = {
189
194
  b3: isTrue(DD_TRACE_B3_ENABLED),
195
+ traceparent: isTrue(DD_TRACE_TRACEPARENT_ENABLED),
190
196
  runtimeId: isTrue(DD_TRACE_RUNTIME_ID_ENABLED),
191
197
  exporter: DD_TRACE_EXPORTER,
192
198
  enableGetRumData: isTrue(DD_TRACE_GET_RUM_DATA_ENABLED),
@@ -38,6 +38,10 @@ class NoopTracer extends Tracer {
38
38
  _startSpan (name, options) {
39
39
  return this._span
40
40
  }
41
+
42
+ setUser () {
43
+ return this
44
+ }
41
45
  }
42
46
 
43
47
  module.exports = NoopTracer
@@ -26,6 +26,8 @@ const baggageExpr = new RegExp(`^${baggagePrefix}(.+)$`)
26
26
  const ddKeys = [traceKey, spanKey, samplingKey, originKey]
27
27
  const b3Keys = [b3TraceKey, b3SpanKey, b3ParentKey, b3SampledKey, b3FlagsKey, b3HeaderKey]
28
28
  const logKeys = ddKeys.concat(b3Keys)
29
+ const traceparentExpr = /^(\d{2})-([A-Fa-f0-9]{32})-([A-Fa-f0-9]{16})-(\d{2})$/i
30
+ const traceparentKey = 'traceparent'
29
31
 
30
32
  class TextMapPropagator {
31
33
  constructor (config) {
@@ -40,6 +42,7 @@ class TextMapPropagator {
40
42
  this._injectSamplingPriority(spanContext, carrier)
41
43
  this._injectBaggageItems(spanContext, carrier)
42
44
  this._injectB3(spanContext, carrier)
45
+ this._injectTraceparent(spanContext, carrier)
43
46
 
44
47
  log.debug(() => `Inject into carrier: ${JSON.stringify(pick(carrier, logKeys))}.`)
45
48
  }
@@ -92,8 +95,20 @@ class TextMapPropagator {
92
95
  }
93
96
  }
94
97
 
98
+ _injectTraceparent (spanContext, carrier) {
99
+ if (!this._config.experimental.traceparent) return
100
+
101
+ const sampling = spanContext._sampling.priority >= AUTO_KEEP ? '01' : '00'
102
+ const traceId = spanContext._traceId.toString('hex').padStart(32, '0')
103
+ const spanId = spanContext._spanId.toString('hex').padStart(16, '0')
104
+ carrier[traceparentKey] = `01-${traceId}-${spanId}-${sampling}`
105
+ }
106
+
95
107
  _extractSpanContext (carrier) {
96
- return this._extractDatadogContext(carrier) || this._extractB3Context(carrier) || this._extractSqsdContext(carrier)
108
+ return this._extractDatadogContext(carrier) ||
109
+ this._extractTraceparentContext(carrier) ||
110
+ this._extractB3Context(carrier) ||
111
+ this._extractSqsdContext(carrier)
97
112
  }
98
113
 
99
114
  _extractDatadogContext (carrier) {
@@ -146,6 +161,24 @@ class TextMapPropagator {
146
161
  return this._extractDatadogContext(parsed)
147
162
  }
148
163
 
164
+ _extractTraceparentContext (carrier) {
165
+ if (!this._config.experimental.traceparent) return null
166
+
167
+ const headerValue = carrier[traceparentKey]
168
+ if (!headerValue) {
169
+ return null
170
+ }
171
+ const matches = headerValue.match(traceparentExpr)
172
+ if (matches.length) {
173
+ return new DatadogSpanContext({
174
+ traceId: id(matches[2], 16),
175
+ spanId: id(matches[3], 16),
176
+ sampling: { priority: matches[4] === '01' ? 1 : 0 }
177
+ })
178
+ }
179
+ return null
180
+ }
181
+
149
182
  _extractGenericContext (carrier, traceKey, spanKey, radix) {
150
183
  if (carrier[traceKey] && carrier[spanKey]) {
151
184
  return new DatadogSpanContext({
@@ -141,6 +141,10 @@ class Tracer extends BaseTracer {
141
141
  getRumData () {
142
142
  return this._tracer.getRumData.apply(this._tracer, arguments)
143
143
  }
144
+
145
+ setUser () {
146
+ return this._tracer.setUser.apply(this.tracer, arguments)
147
+ }
144
148
  }
145
149
 
146
150
  module.exports = Tracer
@@ -122,6 +122,22 @@ class DatadogTracer extends Tracer {
122
122
  <meta name="dd-trace-id" content="${traceId}" />\
123
123
  <meta name="dd-trace-time" content="${traceTime}" />`
124
124
  }
125
+
126
+ setUser (user) {
127
+ if (!user || !user.id) return this
128
+
129
+ const span = this.scope().active()
130
+ if (!span) return this
131
+
132
+ const rootSpan = span._spanContext._trace.started[0]
133
+ if (!rootSpan) return this
134
+
135
+ for (const k of Object.keys(user)) {
136
+ rootSpan.setTag(`usr.${k}`, '' + user[k])
137
+ }
138
+
139
+ return this
140
+ }
125
141
  }
126
142
 
127
143
  function addError (span, error) {
@@ -1,59 +0,0 @@
1
- 'use strict'
2
-
3
- const { instrument } = require('./util')
4
-
5
- function createWrapCommand (tracer, config, name) {
6
- return function wrapCommand (command) {
7
- return function commandWithTrace (ns, ops) {
8
- return instrument(command, this, arguments, this, ns, ops, tracer, config, { name })
9
- }
10
- }
11
- }
12
-
13
- function createWrapQuery (tracer, config) {
14
- return function wrapQuery (query) {
15
- return function queryWithTrace () {
16
- const pool = this.server.s.pool
17
- const ns = this.ns
18
- const ops = this.cmd
19
-
20
- return instrument(query, this, arguments, pool, ns, ops, tracer, config)
21
- }
22
- }
23
- }
24
-
25
- function createWrapCursor (tracer, config, name) {
26
- return function wrapCursor (cursor) {
27
- return function cursorWithTrace () {
28
- const pool = this.server.s.pool
29
- const ns = this.ns
30
-
31
- return instrument(cursor, this, arguments, pool, ns, {}, tracer, config, { name })
32
- }
33
- }
34
- }
35
-
36
- module.exports = [
37
- {
38
- name: 'mongodb-core',
39
- versions: ['2 - 3.1.9'],
40
- patch ({ Cursor, Server }, tracer, config) {
41
- this.wrap(Server.prototype, 'command', createWrapCommand(tracer, config))
42
- this.wrap(Server.prototype, 'insert', createWrapCommand(tracer, config, 'insert'))
43
- this.wrap(Server.prototype, 'update', createWrapCommand(tracer, config, 'update'))
44
- this.wrap(Server.prototype, 'remove', createWrapCommand(tracer, config, 'remove'))
45
- this.wrap(Cursor.prototype, '_getmore', createWrapCursor(tracer, config, 'getMore'))
46
- this.wrap(Cursor.prototype, '_find', createWrapQuery(tracer, config))
47
- this.wrap(Cursor.prototype, 'kill', createWrapCursor(tracer, config, 'killCursors'))
48
- },
49
- unpatch ({ Cursor, Server }) {
50
- this.unwrap(Server.prototype, 'command')
51
- this.unwrap(Server.prototype, 'insert')
52
- this.unwrap(Server.prototype, 'update')
53
- this.unwrap(Server.prototype, 'remove')
54
- this.unwrap(Cursor.prototype, '_getmore')
55
- this.unwrap(Cursor.prototype, '_find')
56
- this.unwrap(Cursor.prototype, 'kill')
57
- }
58
- }
59
- ]
@@ -1,138 +0,0 @@
1
- 'use strict'
2
-
3
- const { instrument } = require('./util')
4
-
5
- function createWrapConnectionCommand (tracer, config, name) {
6
- return function wrapCommand (command) {
7
- return function commandWithTrace (ns, ops) {
8
- const hostParts = typeof this.address === 'string' ? this.address.split(':') : ''
9
- const options = hostParts.length === 2
10
- ? { host: hostParts[0], port: hostParts[1] }
11
- : {} // no port means the address is a random UUID so no host either
12
- const topology = { s: { options } }
13
-
14
- ns = `${ns.db}.${ns.collection}`
15
-
16
- return instrument(command, this, arguments, topology, ns, ops, tracer, config, { name })
17
- }
18
- }
19
- }
20
-
21
- function createWrapCommand (tracer, config, name) {
22
- return function wrapCommand (command) {
23
- return function commandWithTrace (server, ns, ops) {
24
- return instrument(command, this, arguments, server, ns, ops, tracer, config, { name })
25
- }
26
- }
27
- }
28
-
29
- function createWrapMaybePromise (tracer, config) {
30
- return function wrapMaybePromise (maybePromise) {
31
- return function maybePromiseWithTrace (parent, callback, fn) {
32
- const callbackIndex = arguments.length - 2
33
-
34
- callback = arguments[callbackIndex]
35
-
36
- if (typeof callback === 'function') {
37
- arguments[callbackIndex] = tracer.scope().bind(callback)
38
- }
39
-
40
- return maybePromise.apply(this, arguments)
41
- }
42
- }
43
- }
44
-
45
- function patch (wp, tracer, config) {
46
- this.wrap(wp, 'command', createWrapCommand(tracer, config))
47
- this.wrap(wp, 'insert', createWrapCommand(tracer, config, 'insert'))
48
- this.wrap(wp, 'update', createWrapCommand(tracer, config, 'update'))
49
- this.wrap(wp, 'remove', createWrapCommand(tracer, config, 'remove'))
50
- this.wrap(wp, 'query', createWrapCommand(tracer, config))
51
- this.wrap(wp, 'getMore', createWrapCommand(tracer, config, 'getMore'))
52
- this.wrap(wp, 'killCursors', createWrapCommand(tracer, config, 'killCursors'))
53
- }
54
-
55
- function unpatch (wp) {
56
- this.unwrap(wp, 'command')
57
- this.unwrap(wp, 'insert')
58
- this.unwrap(wp, 'update')
59
- this.unwrap(wp, 'remove')
60
- this.unwrap(wp, 'query')
61
- this.unwrap(wp, 'getMore')
62
- this.unwrap(wp, 'killCursors')
63
- }
64
-
65
- function patchConnection ({ Connection }, tracer, config) {
66
- const proto = Connection.prototype
67
-
68
- this.wrap(proto, 'command', createWrapConnectionCommand(tracer, config))
69
- this.wrap(proto, 'query', createWrapConnectionCommand(tracer, config))
70
- this.wrap(proto, 'getMore', createWrapConnectionCommand(tracer, config, 'getMore'))
71
- this.wrap(proto, 'killCursors', createWrapConnectionCommand(tracer, config, 'killCursors'))
72
- }
73
-
74
- function unpatchConnection ({ Connection }) {
75
- const proto = Connection.prototype
76
-
77
- this.unwrap(proto, 'command')
78
- this.unwrap(proto, 'query')
79
- this.unwrap(proto, 'getMore')
80
- this.unwrap(proto, 'killCursors')
81
- }
82
-
83
- function patchClass (WireProtocol, tracer, config) {
84
- this.wrap(WireProtocol.prototype, 'command', createWrapCommand(tracer, config))
85
- }
86
-
87
- function unpatchClass (WireProtocol) {
88
- this.unwrap(WireProtocol.prototype, 'command')
89
- }
90
-
91
- module.exports = [
92
- {
93
- name: 'mongodb',
94
- versions: ['>=4'],
95
- file: 'lib/cmap/connection.js',
96
- patch: patchConnection,
97
- unpatch: unpatchConnection
98
- },
99
- {
100
- name: 'mongodb',
101
- versions: ['>=3.5.4'],
102
- file: 'lib/utils.js',
103
- patch (util, tracer, config) {
104
- this.wrap(util, 'maybePromise', createWrapMaybePromise(tracer, config))
105
- },
106
- unpatch (util) {
107
- this.unwrap(util, 'maybePromise')
108
- }
109
- },
110
- {
111
- name: 'mongodb',
112
- versions: ['>=3.3 <4'],
113
- file: 'lib/core/wireprotocol/index.js',
114
- patch,
115
- unpatch
116
- },
117
- {
118
- name: 'mongodb-core',
119
- versions: ['>=3.2'],
120
- file: 'lib/wireprotocol/index.js',
121
- patch,
122
- unpatch
123
- },
124
- {
125
- name: 'mongodb-core',
126
- versions: ['~3.1.10'],
127
- file: 'lib/wireprotocol/3_2_support.js',
128
- patch: patchClass,
129
- unpatch: unpatchClass
130
- },
131
- {
132
- name: 'mongodb-core',
133
- versions: ['~3.1.10'],
134
- file: 'lib/wireprotocol/2_6_support.js',
135
- patch: patchClass,
136
- unpatch: unpatchClass
137
- }
138
- ]