@depup/elastic-apm-node 4.15.0-depup.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 (154) hide show
  1. package/LICENSE +26 -0
  2. package/NOTICE.md +442 -0
  3. package/README.md +48 -0
  4. package/changes.json +78 -0
  5. package/index.d.ts +398 -0
  6. package/index.js +11 -0
  7. package/lib/InflightEventSet.js +53 -0
  8. package/lib/activation-method.js +119 -0
  9. package/lib/agent.js +941 -0
  10. package/lib/apm-client/apm-client.js +313 -0
  11. package/lib/apm-client/http-apm-client/CHANGELOG.md +271 -0
  12. package/lib/apm-client/http-apm-client/README.md +485 -0
  13. package/lib/apm-client/http-apm-client/central-config.js +41 -0
  14. package/lib/apm-client/http-apm-client/container-info.js +111 -0
  15. package/lib/apm-client/http-apm-client/detect-hostname.js +96 -0
  16. package/lib/apm-client/http-apm-client/index.js +1975 -0
  17. package/lib/apm-client/http-apm-client/logging.js +31 -0
  18. package/lib/apm-client/http-apm-client/ndjson.js +20 -0
  19. package/lib/apm-client/http-apm-client/truncate.js +434 -0
  20. package/lib/apm-client/noop-apm-client.js +73 -0
  21. package/lib/async-hooks-polyfill.js +58 -0
  22. package/lib/cloud-metadata/aws.js +175 -0
  23. package/lib/cloud-metadata/azure.js +123 -0
  24. package/lib/cloud-metadata/callback-coordination.js +159 -0
  25. package/lib/cloud-metadata/gcp.js +133 -0
  26. package/lib/cloud-metadata/index.js +175 -0
  27. package/lib/config/config.js +458 -0
  28. package/lib/config/normalizers.js +701 -0
  29. package/lib/config/schema.js +1007 -0
  30. package/lib/constants.js +35 -0
  31. package/lib/errors.js +303 -0
  32. package/lib/filters/sanitize-field-names.js +69 -0
  33. package/lib/http-request.js +249 -0
  34. package/lib/instrumentation/azure-functions.js +519 -0
  35. package/lib/instrumentation/context.js +56 -0
  36. package/lib/instrumentation/dropped-spans-stats.js +112 -0
  37. package/lib/instrumentation/elasticsearch-shared.js +63 -0
  38. package/lib/instrumentation/express-utils.js +91 -0
  39. package/lib/instrumentation/generic-span.js +322 -0
  40. package/lib/instrumentation/http-shared.js +424 -0
  41. package/lib/instrumentation/ids.js +39 -0
  42. package/lib/instrumentation/index.js +1127 -0
  43. package/lib/instrumentation/modules/@apollo/server.js +30 -0
  44. package/lib/instrumentation/modules/@aws-sdk/client-dynamodb.js +143 -0
  45. package/lib/instrumentation/modules/@aws-sdk/client-s3.js +230 -0
  46. package/lib/instrumentation/modules/@aws-sdk/client-sns.js +197 -0
  47. package/lib/instrumentation/modules/@aws-sdk/client-sqs.js +336 -0
  48. package/lib/instrumentation/modules/@elastic/elasticsearch.js +343 -0
  49. package/lib/instrumentation/modules/@hapi/hapi.js +221 -0
  50. package/lib/instrumentation/modules/@opentelemetry/api.js +86 -0
  51. package/lib/instrumentation/modules/@opentelemetry/sdk-metrics.js +79 -0
  52. package/lib/instrumentation/modules/@redis/client/dist/lib/client/commands-queue.js +178 -0
  53. package/lib/instrumentation/modules/@redis/client/dist/lib/client/index.js +49 -0
  54. package/lib/instrumentation/modules/@smithy/smithy-client.js +198 -0
  55. package/lib/instrumentation/modules/_lambda-handler.js +40 -0
  56. package/lib/instrumentation/modules/apollo-server-core.js +49 -0
  57. package/lib/instrumentation/modules/aws-sdk/dynamodb.js +155 -0
  58. package/lib/instrumentation/modules/aws-sdk/s3.js +184 -0
  59. package/lib/instrumentation/modules/aws-sdk/sns.js +232 -0
  60. package/lib/instrumentation/modules/aws-sdk/sqs.js +361 -0
  61. package/lib/instrumentation/modules/aws-sdk.js +76 -0
  62. package/lib/instrumentation/modules/bluebird.js +93 -0
  63. package/lib/instrumentation/modules/cassandra-driver.js +280 -0
  64. package/lib/instrumentation/modules/elasticsearch.js +191 -0
  65. package/lib/instrumentation/modules/express-graphql.js +66 -0
  66. package/lib/instrumentation/modules/express-queue.js +28 -0
  67. package/lib/instrumentation/modules/express.js +162 -0
  68. package/lib/instrumentation/modules/fastify.js +172 -0
  69. package/lib/instrumentation/modules/finalhandler.js +41 -0
  70. package/lib/instrumentation/modules/generic-pool.js +85 -0
  71. package/lib/instrumentation/modules/graphql.js +256 -0
  72. package/lib/instrumentation/modules/handlebars.js +22 -0
  73. package/lib/instrumentation/modules/http.js +112 -0
  74. package/lib/instrumentation/modules/http2.js +320 -0
  75. package/lib/instrumentation/modules/https.js +68 -0
  76. package/lib/instrumentation/modules/ioredis.js +94 -0
  77. package/lib/instrumentation/modules/jade.js +18 -0
  78. package/lib/instrumentation/modules/kafkajs.js +476 -0
  79. package/lib/instrumentation/modules/knex.js +91 -0
  80. package/lib/instrumentation/modules/koa-router.js +74 -0
  81. package/lib/instrumentation/modules/koa.js +15 -0
  82. package/lib/instrumentation/modules/memcached.js +99 -0
  83. package/lib/instrumentation/modules/mimic-response.js +45 -0
  84. package/lib/instrumentation/modules/mongodb/lib/cmap/connection_pool.js +40 -0
  85. package/lib/instrumentation/modules/mongodb-core.js +206 -0
  86. package/lib/instrumentation/modules/mongodb.js +259 -0
  87. package/lib/instrumentation/modules/mysql.js +200 -0
  88. package/lib/instrumentation/modules/mysql2.js +140 -0
  89. package/lib/instrumentation/modules/pg.js +148 -0
  90. package/lib/instrumentation/modules/pug.js +18 -0
  91. package/lib/instrumentation/modules/redis.js +176 -0
  92. package/lib/instrumentation/modules/restify.js +52 -0
  93. package/lib/instrumentation/modules/tedious.js +159 -0
  94. package/lib/instrumentation/modules/undici.js +270 -0
  95. package/lib/instrumentation/modules/ws.js +59 -0
  96. package/lib/instrumentation/noop-transaction.js +81 -0
  97. package/lib/instrumentation/run-context/AbstractRunContextManager.js +215 -0
  98. package/lib/instrumentation/run-context/AsyncHooksRunContextManager.js +106 -0
  99. package/lib/instrumentation/run-context/AsyncLocalStorageRunContextManager.js +73 -0
  100. package/lib/instrumentation/run-context/BasicRunContextManager.js +82 -0
  101. package/lib/instrumentation/run-context/RunContext.js +151 -0
  102. package/lib/instrumentation/run-context/index.js +23 -0
  103. package/lib/instrumentation/shimmer.js +123 -0
  104. package/lib/instrumentation/span-compression.js +239 -0
  105. package/lib/instrumentation/span.js +621 -0
  106. package/lib/instrumentation/template-shared.js +43 -0
  107. package/lib/instrumentation/timer.js +84 -0
  108. package/lib/instrumentation/transaction.js +571 -0
  109. package/lib/lambda.js +992 -0
  110. package/lib/load-source-map.js +100 -0
  111. package/lib/logging.js +212 -0
  112. package/lib/metrics/index.js +92 -0
  113. package/lib/metrics/platforms/generic/index.js +40 -0
  114. package/lib/metrics/platforms/generic/process-cpu.js +22 -0
  115. package/lib/metrics/platforms/generic/process-top.js +157 -0
  116. package/lib/metrics/platforms/generic/stats.js +34 -0
  117. package/lib/metrics/platforms/generic/system-cpu.js +51 -0
  118. package/lib/metrics/platforms/linux/index.js +19 -0
  119. package/lib/metrics/platforms/linux/stats.js +213 -0
  120. package/lib/metrics/queue.js +90 -0
  121. package/lib/metrics/registry.js +52 -0
  122. package/lib/metrics/reporter.js +119 -0
  123. package/lib/metrics/runtime.js +77 -0
  124. package/lib/middleware/connect.js +16 -0
  125. package/lib/opentelemetry-bridge/OTelBridgeNonRecordingSpan.js +150 -0
  126. package/lib/opentelemetry-bridge/OTelBridgeRunContext.js +124 -0
  127. package/lib/opentelemetry-bridge/OTelContextManager.js +82 -0
  128. package/lib/opentelemetry-bridge/OTelSpan.js +344 -0
  129. package/lib/opentelemetry-bridge/OTelTracer.js +201 -0
  130. package/lib/opentelemetry-bridge/OTelTracerProvider.js +25 -0
  131. package/lib/opentelemetry-bridge/README.md +244 -0
  132. package/lib/opentelemetry-bridge/index.js +15 -0
  133. package/lib/opentelemetry-bridge/oblog.js +23 -0
  134. package/lib/opentelemetry-bridge/opentelemetry-core-mini/README.md +3 -0
  135. package/lib/opentelemetry-bridge/opentelemetry-core-mini/internal/validators.js +52 -0
  136. package/lib/opentelemetry-bridge/opentelemetry-core-mini/trace/TraceState.js +109 -0
  137. package/lib/opentelemetry-bridge/otelutils.js +99 -0
  138. package/lib/opentelemetry-bridge/setup.js +76 -0
  139. package/lib/opentelemetry-metrics/ElasticApmMetricExporter.js +285 -0
  140. package/lib/opentelemetry-metrics/index.js +50 -0
  141. package/lib/parsers.js +225 -0
  142. package/lib/propwrap.js +147 -0
  143. package/lib/stacktraces.js +537 -0
  144. package/lib/symbols.js +15 -0
  145. package/lib/tracecontext/index.js +118 -0
  146. package/lib/tracecontext/traceparent.js +185 -0
  147. package/lib/tracecontext/tracestate.js +388 -0
  148. package/lib/wildcard-matcher.js +52 -0
  149. package/loader.mjs +7 -0
  150. package/package.json +299 -0
  151. package/start.d.ts +8 -0
  152. package/start.js +29 -0
  153. package/types/aws-lambda.d.ts +98 -0
  154. package/types/connect.d.ts +23 -0
@@ -0,0 +1,91 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and other contributors where applicable.
3
+ * Licensed under the BSD 2-Clause License; you may not use this file except in
4
+ * compliance with the BSD 2-Clause License.
5
+ */
6
+
7
+ // Knex instrumentation exists to capture a more useful span stacktrace at
8
+ // the start of a Knex query, and use that stacktrace on the 'pg' or 'mysql'
9
+ // span.
10
+
11
+ 'use strict';
12
+
13
+ var semver = require('semver');
14
+
15
+ var shimmer = require('../shimmer');
16
+ var symbols = require('../../symbols');
17
+
18
+ module.exports = function (Knex, agent, { version, enabled }) {
19
+ if (!enabled) {
20
+ return Knex;
21
+ }
22
+ if (!semver.satisfies(version, '>=0.10.0 <4.0.0')) {
23
+ agent.logger.debug(
24
+ `knex@${version} is not supported, skipping knex instrumentation`,
25
+ );
26
+ return Knex;
27
+ }
28
+
29
+ if (agent._conf.spanStackTraceMinDuration < 0) {
30
+ agent.logger.trace(
31
+ 'not instrumenting knex because not capturing span stack traces (spanStackTraceMinDuration=%s)',
32
+ agent._conf.spanStackTraceMinDuration,
33
+ );
34
+ return Knex;
35
+ }
36
+
37
+ function wrapQueryStartPoint(original) {
38
+ return function wrappedQueryStartPoint() {
39
+ var builder = original.apply(this, arguments);
40
+
41
+ agent.logger.debug('capturing custom stack trace for knex');
42
+ var obj = {};
43
+ Error.captureStackTrace(obj);
44
+ builder[symbols.knexStackObj] = obj;
45
+
46
+ return builder;
47
+ };
48
+ }
49
+
50
+ function wrapRunner(original) {
51
+ return function wrappedRunner() {
52
+ var runner = original.apply(this, arguments);
53
+
54
+ agent.logger.debug('shimming knex runner.query');
55
+ shimmer.wrap(runner, 'query', wrapQuery);
56
+
57
+ return runner;
58
+ };
59
+ }
60
+
61
+ function wrapQuery(original) {
62
+ return function wrappedQuery() {
63
+ agent.logger.debug('intercepted call to knex runner.query');
64
+ if (this.connection) {
65
+ this.connection[symbols.knexStackObj] = this.builder
66
+ ? this.builder[symbols.knexStackObj]
67
+ : null;
68
+ }
69
+ return original.apply(this, arguments);
70
+ };
71
+ }
72
+
73
+ return function wrappedKnex() {
74
+ const knexInstance = Knex.apply(null, arguments);
75
+
76
+ if (knexInstance && knexInstance.client) {
77
+ const QUERY_FNS = ['queryBuilder', 'raw'];
78
+ agent.logger.debug('shimming knexInstance.client.runner');
79
+ shimmer.wrap(knexInstance.client, 'runner', wrapRunner);
80
+ agent.logger.debug(
81
+ 'shimming Knex.Client.prototype functions: %j',
82
+ QUERY_FNS,
83
+ );
84
+ shimmer.massWrap(knexInstance.client, QUERY_FNS, wrapQueryStartPoint);
85
+ } else {
86
+ agent.logger.debug('could not shim Knex');
87
+ }
88
+
89
+ return knexInstance;
90
+ };
91
+ };
@@ -0,0 +1,74 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and other contributors where applicable.
3
+ * Licensed under the BSD 2-Clause License; you may not use this file except in
4
+ * compliance with the BSD 2-Clause License.
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ var semver = require('semver');
10
+
11
+ var shimmer = require('../shimmer');
12
+
13
+ module.exports = function (Router, agent, { version, enabled }) {
14
+ if (!enabled) return Router;
15
+ if (!semver.satisfies(version, '>=5.2.0 <14')) {
16
+ agent.logger.debug(
17
+ 'koa-router version %s not supported - aborting...',
18
+ version,
19
+ );
20
+ return Router;
21
+ }
22
+ if (
23
+ semver.satisfies(version, '>=13') &&
24
+ semver.satisfies(process.version, '<18')
25
+ ) {
26
+ agent.logger.debug(
27
+ 'koa-router version %s not supported for node %s - aborting...',
28
+ version,
29
+ process.version,
30
+ );
31
+ return Router;
32
+ }
33
+
34
+ agent.logger.debug('shimming koa-router prototype.match function');
35
+ shimmer.wrap(Router.prototype, 'match', function (orig) {
36
+ return function (_, method) {
37
+ var matched = orig.apply(this, arguments);
38
+
39
+ if (typeof method !== 'string') {
40
+ agent.logger.debug(
41
+ 'unexpected method type in koa-router prototype.match: %s',
42
+ typeof method,
43
+ );
44
+ return matched;
45
+ }
46
+
47
+ if (Array.isArray(matched && matched.pathAndMethod)) {
48
+ const layer = matched.pathAndMethod.find(function (layer) {
49
+ return layer && layer.opts && layer.opts.end === true;
50
+ });
51
+
52
+ var path = layer && layer.path;
53
+ if (typeof path === 'string') {
54
+ var name = method + ' ' + path;
55
+ agent._instrumentation.setDefaultTransactionName(name);
56
+ } else {
57
+ agent.logger.debug(
58
+ 'unexpected path type in koa-router prototype.match: %s',
59
+ typeof path,
60
+ );
61
+ }
62
+ } else {
63
+ agent.logger.debug(
64
+ 'unexpected match result in koa-router prototype.match: %s',
65
+ typeof matched,
66
+ );
67
+ }
68
+
69
+ return matched;
70
+ };
71
+ });
72
+
73
+ return Router;
74
+ };
@@ -0,0 +1,15 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and other contributors where applicable.
3
+ * Licensed under the BSD 2-Clause License; you may not use this file except in
4
+ * compliance with the BSD 2-Clause License.
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ module.exports = function (koa, agent, { version, enabled }) {
10
+ if (!enabled) return koa;
11
+
12
+ agent.setFramework({ name: 'koa', version, overwrite: false });
13
+
14
+ return koa;
15
+ };
@@ -0,0 +1,99 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and other contributors where applicable.
3
+ * Licensed under the BSD 2-Clause License; you may not use this file except in
4
+ * compliance with the BSD 2-Clause License.
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ var semver = require('semver');
10
+
11
+ var shimmer = require('../shimmer');
12
+ var { getDBDestination } = require('../context');
13
+
14
+ module.exports = function (memcached, agent, { version, enabled }) {
15
+ if (!enabled) {
16
+ return memcached;
17
+ }
18
+ if (!semver.satisfies(version, '>=2.2.0')) {
19
+ agent.logger.debug(
20
+ 'Memcached version %s not supported - aborting...',
21
+ version,
22
+ );
23
+ return memcached;
24
+ }
25
+
26
+ const ins = agent._instrumentation;
27
+
28
+ agent.logger.debug('shimming memcached.prototype.command');
29
+ shimmer.wrap(memcached.prototype, 'command', wrapCommand);
30
+ shimmer.wrap(memcached.prototype, 'connect', wrapConnect);
31
+ return memcached;
32
+
33
+ function wrapConnect(original) {
34
+ return function wrappedConnect() {
35
+ const currentSpan = ins.currSpan();
36
+ const server = arguments[0];
37
+ agent.logger.debug('intercepted call to memcached.prototype.connect %o', {
38
+ server,
39
+ });
40
+
41
+ if (currentSpan) {
42
+ const [host, port = 11211] = server.split(':');
43
+ currentSpan._setDestinationContext(getDBDestination(host, port));
44
+ }
45
+ return original.apply(this, arguments);
46
+ };
47
+ }
48
+
49
+ // Wrap the generic command that is used to build touch, get, gets etc
50
+ function wrapCommand(original) {
51
+ return function wrappedCommand(queryCompiler, _server) {
52
+ if (typeof queryCompiler !== 'function') {
53
+ return original.apply(this, arguments);
54
+ }
55
+
56
+ var query = queryCompiler();
57
+ // Replace the queryCompiler function so it isn't called a second time.
58
+ arguments[0] = function prerunQueryCompiler() {
59
+ return query;
60
+ };
61
+
62
+ // If the callback is not a function the user doesn't care about result.
63
+ if (!query && typeof query.callback !== 'function') {
64
+ return original.apply(this, arguments);
65
+ }
66
+
67
+ const span = ins.createSpan(
68
+ `memcached.${query.type}`,
69
+ 'db',
70
+ 'memcached',
71
+ query.type,
72
+ { exitSpan: true },
73
+ );
74
+ if (!span) {
75
+ return original.apply(this, arguments);
76
+ }
77
+
78
+ agent.logger.debug('intercepted call to memcached.prototype.command %o', {
79
+ id: span.id,
80
+ type: query.type,
81
+ });
82
+ span.setDbContext({
83
+ statement: `${query.type} ${query.key}`,
84
+ type: 'memcached',
85
+ });
86
+
87
+ const spanRunContext = ins.currRunContext().enterSpan(span);
88
+ const origCallback = query.callback;
89
+ query.callback = ins.bindFunctionToRunContext(
90
+ spanRunContext,
91
+ function tracedCallback() {
92
+ span.end();
93
+ return origCallback.apply(this, arguments);
94
+ },
95
+ );
96
+ return ins.withRunContext(spanRunContext, original, this, ...arguments);
97
+ };
98
+ }
99
+ };
@@ -0,0 +1,45 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and other contributors where applicable.
3
+ * Licensed under the BSD 2-Clause License; you may not use this file except in
4
+ * compliance with the BSD 2-Clause License.
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ /*
10
+ * This instrumentation exists to work around an issue in mimic-response@1.0.0
11
+ * that was fixed in mimic-response@1.0.1.
12
+ * See https://github.com/elastic/apm-agent-nodejs/issues/423.
13
+ */
14
+
15
+ var semver = require('semver');
16
+
17
+ module.exports = function (mimicResponse, agent, { version, enabled }) {
18
+ if (!enabled) return mimicResponse;
19
+
20
+ if (semver.gte(version, '1.0.1')) {
21
+ agent.logger.debug(
22
+ "mimic-response version %s doesn't need to be patched - ignoring...",
23
+ version,
24
+ );
25
+ return mimicResponse;
26
+ }
27
+
28
+ var ins = agent._instrumentation;
29
+
30
+ return function wrappedMimicResponse(fromStream, toStream) {
31
+ // If we bound the `fromStream` emitter, but not the `toStream` emitter, we
32
+ // need to do so as else the `on`, `addListener`, and `prependListener`
33
+ // functions of the `fromStream` will be copied over to the `toStream` but
34
+ // run in the context of the `fromStream`.
35
+ if (
36
+ fromStream &&
37
+ toStream &&
38
+ ins.isEventEmitterBound(fromStream) &&
39
+ !ins.isEventEmitterBound(toStream)
40
+ ) {
41
+ ins.bindEmitter(toStream);
42
+ }
43
+ return mimicResponse.apply(null, arguments);
44
+ };
45
+ };
@@ -0,0 +1,40 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and other contributors where applicable.
3
+ * Licensed under the BSD 2-Clause License; you may not use this file except in
4
+ * compliance with the BSD 2-Clause License.
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { AsyncResource } = require('../../../../../async-hooks-polyfill');
10
+
11
+ const semver = require('semver');
12
+
13
+ module.exports = (mod, agent, { version, enabled }) => {
14
+ if (!enabled) return mod;
15
+ if (!semver.satisfies(version, '>=3.3 <6.4.0')) {
16
+ // - mongodb <3.3 is instrumented via mongodb-core
17
+ // - mongodb >=6.4.0 now longer requires ConnectionPool#checkOut to be
18
+ // patched to fix async context tracking. See discussion at
19
+ // https://github.com/elastic/apm-agent-nodejs/pull/3897
20
+ return mod;
21
+ }
22
+ agent.logger.debug('instrumenting mongodb ConnectionPool#checkOut');
23
+
24
+ if (mod.ConnectionPool) {
25
+ class ConnectionPoolTraced extends mod.ConnectionPool {
26
+ checkOut(callback) {
27
+ return super.checkOut(AsyncResource.bind(callback));
28
+ }
29
+ }
30
+
31
+ Object.defineProperty(mod, 'ConnectionPool', {
32
+ enumerable: true,
33
+ get: function () {
34
+ return ConnectionPoolTraced;
35
+ },
36
+ });
37
+
38
+ return mod;
39
+ }
40
+ };
@@ -0,0 +1,206 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and other contributors where applicable.
3
+ * Licensed under the BSD 2-Clause License; you may not use this file except in
4
+ * compliance with the BSD 2-Clause License.
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ var semver = require('semver');
10
+
11
+ const { getDBDestination } = require('../context');
12
+ var shimmer = require('../shimmer');
13
+
14
+ var SERVER_FNS = ['insert', 'update', 'remove', 'auth'];
15
+ var CURSOR_FNS_FIRST = ['next', '_getmore'];
16
+
17
+ const firstSpan = Symbol('first-span');
18
+
19
+ module.exports = function (mongodb, agent, { version, enabled }) {
20
+ if (!enabled) return mongodb;
21
+ if (!semver.satisfies(version, '>=1.2.19 <4')) {
22
+ agent.logger.debug(
23
+ 'mongodb-core version %s not supported - aborting...',
24
+ version,
25
+ );
26
+ return mongodb;
27
+ }
28
+
29
+ const ins = agent._instrumentation;
30
+
31
+ if (mongodb.Server) {
32
+ agent.logger.debug('shimming mongodb-core.Server.prototype.command');
33
+ shimmer.wrap(mongodb.Server.prototype, 'command', wrapCommand);
34
+ agent.logger.debug(
35
+ 'shimming mongodb-core.Server.prototype functions: %j',
36
+ SERVER_FNS,
37
+ );
38
+ shimmer.massWrap(mongodb.Server.prototype, SERVER_FNS, wrapQuery);
39
+ }
40
+
41
+ if (mongodb.Cursor) {
42
+ agent.logger.debug(
43
+ 'shimming mongodb-core.Cursor.prototype functions: %j',
44
+ CURSOR_FNS_FIRST,
45
+ );
46
+ shimmer.massWrap(mongodb.Cursor.prototype, CURSOR_FNS_FIRST, wrapCursor);
47
+ }
48
+
49
+ return mongodb;
50
+
51
+ function wrapCommand(orig) {
52
+ return function wrappedFunction(ns, cmd) {
53
+ var trans = agent._instrumentation.currTransaction();
54
+ var id = trans && trans.id;
55
+ var span;
56
+
57
+ agent.logger.debug(
58
+ 'intercepted call to mongodb-core.Server.prototype.command %o',
59
+ { id, ns },
60
+ );
61
+
62
+ if (trans && arguments.length > 0) {
63
+ var index = arguments.length - 1;
64
+ var cb = arguments[index];
65
+ if (typeof cb === 'function') {
66
+ var type;
67
+ if (cmd.findAndModify) type = 'findAndModify';
68
+ else if (cmd.createIndexes) type = 'createIndexes';
69
+ else if (cmd.ismaster) type = 'ismaster';
70
+ else if (cmd.count) type = 'count';
71
+ else type = 'command';
72
+
73
+ span = ins.createSpan(ns + '.' + type, 'db', 'mongodb', 'query', {
74
+ exitSpan: true,
75
+ });
76
+ if (span) {
77
+ span.setDbContext({ type: 'mongodb', instance: ns });
78
+ arguments[index] = ins.bindFunctionToRunContext(
79
+ ins.currRunContext(),
80
+ wrappedCallback,
81
+ );
82
+ }
83
+ }
84
+ }
85
+
86
+ return orig.apply(this, arguments);
87
+
88
+ function wrappedCallback(_err, commandResult) {
89
+ agent.logger.debug(
90
+ 'intercepted mongodb-core.Server.prototype.command callback %o',
91
+ { id },
92
+ );
93
+ if (commandResult && commandResult.connection) {
94
+ span._setDestinationContext(
95
+ getDBDestination(
96
+ commandResult.connection.host,
97
+ commandResult.connection.port,
98
+ ),
99
+ );
100
+ }
101
+ span.end();
102
+ return cb.apply(this, arguments);
103
+ }
104
+ };
105
+ }
106
+
107
+ function wrapQuery(orig, name) {
108
+ return function wrappedFunction(ns) {
109
+ var trans = agent._instrumentation.currTransaction();
110
+ var id = trans && trans.id;
111
+ var span;
112
+
113
+ agent.logger.debug(
114
+ 'intercepted call to mongodb-core.Server.prototype.%s %o',
115
+ name,
116
+ { id, ns },
117
+ );
118
+
119
+ if (trans && arguments.length > 0) {
120
+ var index = arguments.length - 1;
121
+ var cb = arguments[index];
122
+ if (typeof cb === 'function') {
123
+ span = ins.createSpan(ns + '.' + name, 'db', 'mongodb', 'query', {
124
+ exitSpan: true,
125
+ });
126
+ if (span) {
127
+ span.setDbContext({ type: 'mongodb', instance: ns });
128
+ arguments[index] = ins.bindFunctionToRunContext(
129
+ ins.currRunContext(),
130
+ wrappedCallback,
131
+ );
132
+ }
133
+ }
134
+ }
135
+
136
+ return orig.apply(this, arguments);
137
+
138
+ function wrappedCallback(_err, commandResult) {
139
+ agent.logger.debug(
140
+ 'intercepted mongodb-core.Server.prototype.%s callback %o',
141
+ name,
142
+ { id },
143
+ );
144
+ if (commandResult && commandResult.connection) {
145
+ span._setDestinationContext(
146
+ getDBDestination(
147
+ commandResult.connection.host,
148
+ commandResult.connection.port,
149
+ ),
150
+ );
151
+ }
152
+ span.end();
153
+ return cb.apply(this, arguments);
154
+ }
155
+ };
156
+ }
157
+ function wrapCursor(orig, name) {
158
+ return function wrappedFunction() {
159
+ var trans = agent._instrumentation.currTransaction();
160
+ var id = trans && trans.id;
161
+ var span;
162
+
163
+ agent.logger.debug(
164
+ 'intercepted call to mongodb-core.Cursor.prototype.%s %o',
165
+ name,
166
+ { id },
167
+ );
168
+
169
+ if (trans && arguments.length > 0) {
170
+ var cb = arguments[0];
171
+ if (typeof cb === 'function') {
172
+ if (name !== 'next' || !this[firstSpan]) {
173
+ var spanName = `${this.ns}.${this.cmd.find ? 'find' : name}`;
174
+ span = ins.createSpan(spanName, 'db', 'mongodb', 'query', {
175
+ exitSpan: true,
176
+ });
177
+ }
178
+ if (span) {
179
+ span.setDbContext({ type: 'mongodb', instance: this.ns });
180
+ // Limitation: Currently not getting destination address/port for
181
+ // cursor calls.
182
+ arguments[0] = ins.bindFunctionToRunContext(
183
+ ins.currRunContext(),
184
+ wrappedCallback,
185
+ );
186
+ if (name === 'next') {
187
+ this[firstSpan] = true;
188
+ }
189
+ }
190
+ }
191
+ }
192
+
193
+ return orig.apply(this, arguments);
194
+
195
+ function wrappedCallback() {
196
+ agent.logger.debug(
197
+ 'intercepted mongodb-core.Cursor.prototype.%s callback %o',
198
+ name,
199
+ { id },
200
+ );
201
+ span.end();
202
+ return cb.apply(this, arguments);
203
+ }
204
+ };
205
+ }
206
+ };