@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,148 @@
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 EventEmitter = require('events');
10
+
11
+ var semver = require('semver');
12
+ var sqlSummary = require('sql-summary');
13
+
14
+ var shimmer = require('../shimmer');
15
+ var symbols = require('../../symbols');
16
+ var { getDBDestination } = require('../context');
17
+
18
+ module.exports = function (pg, agent, { version, enabled }) {
19
+ if (!enabled) {
20
+ return pg;
21
+ }
22
+ if (!semver.satisfies(version, '>=4.0.0 <9.0.0')) {
23
+ agent.logger.debug('pg version %s not supported - aborting...', version);
24
+ return pg;
25
+ }
26
+
27
+ patchClient(pg.Client, 'pg.Client', agent);
28
+
29
+ // Trying to access the pg.native getter will trigger and log the warning
30
+ // "Cannot find module 'pg-native'" to STDERR if the module isn't installed.
31
+ // Overwriting the getter we can lazily patch the native client only if the
32
+ // user is acually requesting it.
33
+ var getter = pg.__lookupGetter__('native');
34
+ if (getter) {
35
+ delete pg.native;
36
+ // To be as true to the original pg module as possible, we use
37
+ // __defineGetter__ instead of Object.defineProperty.
38
+ pg.__defineGetter__('native', function () {
39
+ var native = getter();
40
+ if (native && native.Client) {
41
+ patchClient(native.Client, 'pg.native.Client', agent);
42
+ }
43
+ return native;
44
+ });
45
+ }
46
+
47
+ return pg;
48
+ };
49
+
50
+ function patchClient(Client, klass, agent) {
51
+ agent.logger.debug('shimming %s.prototype.query', klass);
52
+ shimmer.wrap(Client.prototype, 'query', wrapQuery);
53
+
54
+ function wrapQuery(orig, name) {
55
+ return function wrappedFunction(sql) {
56
+ agent.logger.debug('intercepted call to %s.prototype.%s', klass, name);
57
+ const ins = agent._instrumentation;
58
+ const span = ins.createSpan('SQL', 'db', 'postgresql', 'query', {
59
+ exitSpan: true,
60
+ });
61
+ if (!span) {
62
+ return orig.apply(this, arguments);
63
+ }
64
+
65
+ // Get connection parameters from Client.
66
+ let host, port, database, user;
67
+ if (typeof this.connectionParameters === 'object') {
68
+ ({ host, port, database, user } = this.connectionParameters);
69
+ }
70
+ span._setDestinationContext(getDBDestination(host, port));
71
+
72
+ const dbContext = { type: 'sql' };
73
+ let sqlText = sql;
74
+ if (sql && typeof sql.text === 'string') {
75
+ sqlText = sql.text;
76
+ }
77
+ if (typeof sqlText === 'string') {
78
+ span.name = sqlSummary(sqlText);
79
+ dbContext.statement = sqlText;
80
+ } else {
81
+ agent.logger.debug(
82
+ 'unable to parse sql form pg module (type: %s)',
83
+ typeof sqlText,
84
+ );
85
+ }
86
+ if (database) {
87
+ dbContext.instance = database;
88
+ }
89
+ if (user) {
90
+ dbContext.user = user;
91
+ }
92
+ span.setDbContext(dbContext);
93
+
94
+ if (this[symbols.knexStackObj]) {
95
+ span.customStackTrace(this[symbols.knexStackObj]);
96
+ this[symbols.knexStackObj] = null;
97
+ }
98
+
99
+ let index = arguments.length - 1;
100
+ let cb = arguments[index];
101
+ if (Array.isArray(cb)) {
102
+ index = cb.length - 1;
103
+ cb = cb[index];
104
+ }
105
+
106
+ const spanRunContext = ins.currRunContext().enterSpan(span);
107
+ const onQueryEnd = ins.bindFunctionToRunContext(
108
+ spanRunContext,
109
+ (_err) => {
110
+ agent.logger.debug('intercepted end of %s.prototype.%s', klass, name);
111
+ span.end();
112
+ },
113
+ );
114
+
115
+ if (typeof cb === 'function') {
116
+ arguments[index] = ins.bindFunction((err, res) => {
117
+ onQueryEnd(err);
118
+ return cb(err, res);
119
+ });
120
+ return orig.apply(this, arguments);
121
+ } else {
122
+ var queryOrPromise = orig.apply(this, arguments);
123
+
124
+ // It is important to prefer `.on` to `.then` for pg <7 >=6.3.0, because
125
+ // `query.then` is broken in those versions. See
126
+ // https://github.com/brianc/node-postgres/commit/b5b49eb895727e01290e90d08292c0d61ab86322#r23267714
127
+ if (typeof queryOrPromise.on === 'function') {
128
+ queryOrPromise.on('end', onQueryEnd);
129
+ queryOrPromise.on('error', onQueryEnd);
130
+ if (queryOrPromise instanceof EventEmitter) {
131
+ ins.bindEmitter(queryOrPromise);
132
+ }
133
+ } else if (typeof queryOrPromise.then === 'function') {
134
+ queryOrPromise.then(() => {
135
+ onQueryEnd();
136
+ }, onQueryEnd);
137
+ } else {
138
+ agent.logger.debug(
139
+ 'ERROR: unknown pg query type: %s',
140
+ typeof queryOrPromise,
141
+ );
142
+ }
143
+
144
+ return queryOrPromise;
145
+ }
146
+ };
147
+ }
148
+ }
@@ -0,0 +1,18 @@
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 shimmer = require('../shimmer');
10
+ var templateShared = require('../template-shared');
11
+
12
+ module.exports = function (pug, agent, { enabled }) {
13
+ if (!enabled) return pug;
14
+ agent.logger.debug('shimming pug.compile');
15
+ shimmer.wrap(pug, 'compile', templateShared.wrapCompile(agent, 'pug'));
16
+
17
+ return pug;
18
+ };
@@ -0,0 +1,176 @@
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 constants = require('../../constants');
12
+ var shimmer = require('../shimmer');
13
+ var { getDBDestination } = require('../context');
14
+
15
+ const isWrappedRedisCbSym = Symbol('ElasticAPMIsWrappedRedisCb');
16
+
17
+ const TYPE = 'db';
18
+ const SUBTYPE = 'redis';
19
+ const ACTION = 'query';
20
+
21
+ module.exports = function (redis, agent, { version, enabled }) {
22
+ if (!enabled) {
23
+ return redis;
24
+ }
25
+ if (!semver.satisfies(version, '>=2.0.0 <4.0.0')) {
26
+ // Explicitly do not log.debug here, because the message is misleading for
27
+ // redis@4 and later that is being handled by @redis/client instrumentation.
28
+ return redis;
29
+ }
30
+
31
+ const ins = agent._instrumentation;
32
+
33
+ // The undocumented field on a RedisClient instance on which connection
34
+ // options are stored has changed a few times.
35
+ //
36
+ // - >=2.4.0: `client.connection_options.{host,port}`, commit eae5596a
37
+ // - >=2.3.0, <2.4.0: `client.connection_option.{host,port}`, commit d454e402
38
+ // - >=0.12.0, <2.3.0: `client.connectionOption.{host,port}`, commit 064260d1
39
+ // - <0.12.0: *maybe* `client.{host,port}`
40
+ const connOptsFromRedisClient = (rc) =>
41
+ rc.connection_options || rc.connection_option || rc.connectionOption || {};
42
+
43
+ var proto = redis.RedisClient && redis.RedisClient.prototype;
44
+ if (semver.satisfies(version, '>2.5.3')) {
45
+ agent.logger.debug(
46
+ 'shimming redis.RedisClient.prototype.internal_send_command',
47
+ );
48
+ shimmer.wrap(proto, 'internal_send_command', wrapInternalSendCommand);
49
+ } else {
50
+ agent.logger.debug('shimming redis.RedisClient.prototype.send_command');
51
+ shimmer.wrap(proto, 'send_command', wrapSendCommand);
52
+ }
53
+
54
+ return redis;
55
+
56
+ function makeWrappedCallback(spanRunContext, span, origCb) {
57
+ const wrappedCallback = ins.bindFunctionToRunContext(
58
+ spanRunContext,
59
+ function (err, _reply) {
60
+ if (err) {
61
+ span._setOutcomeFromErrorCapture(constants.OUTCOME_FAILURE);
62
+ agent.captureError(err, { skipOutcome: true });
63
+ }
64
+ span.end();
65
+ if (origCb) {
66
+ return origCb.apply(this, arguments);
67
+ }
68
+ },
69
+ );
70
+ wrappedCallback[isWrappedRedisCbSym] = true;
71
+ return wrappedCallback;
72
+ }
73
+
74
+ function wrapInternalSendCommand(original) {
75
+ return function wrappedInternalSendCommand(commandObj) {
76
+ if (!commandObj || typeof commandObj.command !== 'string') {
77
+ // Unexpected usage. Skip instrumenting this call.
78
+ return original.apply(this, arguments);
79
+ }
80
+
81
+ if (commandObj.callback && commandObj.callback[isWrappedRedisCbSym]) {
82
+ // Avoid re-wrapping internal_send_command called *again* for commands
83
+ // queued before the client was "ready".
84
+ return original.apply(this, arguments);
85
+ }
86
+
87
+ const command = commandObj.command;
88
+ agent.logger.debug(
89
+ { command },
90
+ 'intercepted call to RedisClient.prototype.internal_send_command',
91
+ );
92
+ const span = ins.createSpan(
93
+ command.toUpperCase(),
94
+ TYPE,
95
+ SUBTYPE,
96
+ ACTION,
97
+ { exitSpan: true },
98
+ );
99
+ if (!span) {
100
+ return original.apply(this, arguments);
101
+ }
102
+
103
+ const connOpts = connOptsFromRedisClient(this);
104
+ span._setDestinationContext(
105
+ getDBDestination(connOpts.host, connOpts.port),
106
+ );
107
+ span.setDbContext({ type: 'redis' });
108
+
109
+ const spanRunContext = ins.currRunContext().enterSpan(span);
110
+ commandObj.callback = makeWrappedCallback(
111
+ spanRunContext,
112
+ span,
113
+ commandObj.callback,
114
+ );
115
+ return ins.withRunContext(spanRunContext, original, this, ...arguments);
116
+ };
117
+ }
118
+
119
+ function wrapSendCommand(original) {
120
+ return function wrappedSendCommand(command, args, cb) {
121
+ if (typeof command !== 'string') {
122
+ // Unexpected usage. Skip instrumenting this call.
123
+ return original.apply(this, arguments);
124
+ }
125
+
126
+ let origCb = cb;
127
+ if (
128
+ !origCb &&
129
+ Array.isArray(args) &&
130
+ typeof args[args.length - 1] === 'function'
131
+ ) {
132
+ origCb = args[args.length - 1];
133
+ }
134
+ if (origCb && origCb[isWrappedRedisCbSym]) {
135
+ // Avoid re-wrapping send_command called *again* for commands queued
136
+ // before the client was "ready".
137
+ return original.apply(this, arguments);
138
+ }
139
+
140
+ agent.logger.debug(
141
+ { command },
142
+ 'intercepted call to RedisClient.prototype.send_command',
143
+ );
144
+ var span = ins.createSpan(command.toUpperCase(), TYPE, SUBTYPE, ACTION, {
145
+ exitSpan: true,
146
+ });
147
+ if (!span) {
148
+ return original.apply(this, arguments);
149
+ }
150
+
151
+ const connOpts = connOptsFromRedisClient(this);
152
+ span._setDestinationContext(
153
+ getDBDestination(connOpts.host, connOpts.port),
154
+ );
155
+ span.setDbContext({ type: 'redis' });
156
+
157
+ const spanRunContext = ins.currRunContext().enterSpan(span);
158
+ const wrappedCb = makeWrappedCallback(spanRunContext, span, origCb);
159
+ if (cb) {
160
+ cb = wrappedCb;
161
+ } else if (origCb) {
162
+ args[args.length - 1] = wrappedCb;
163
+ } else {
164
+ cb = wrappedCb;
165
+ }
166
+ return ins.withRunContext(
167
+ spanRunContext,
168
+ original,
169
+ this,
170
+ command,
171
+ args,
172
+ cb,
173
+ );
174
+ };
175
+ }
176
+ };
@@ -0,0 +1,52 @@
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 semver = require('semver');
10
+
11
+ const shimmer = require('../shimmer');
12
+
13
+ module.exports = function (restify, agent, { version, enabled }) {
14
+ if (!enabled) {
15
+ return restify;
16
+ }
17
+ if (!semver.satisfies(version, '>=5.2.0 <12.0.0')) {
18
+ agent.logger.debug('restify version %s not supported, skipping', version);
19
+ return restify;
20
+ }
21
+
22
+ agent.setFramework({ name: 'restify', version, overwrite: false });
23
+
24
+ function patchServer(server) {
25
+ if (semver.gte(version, '7.0.0')) {
26
+ shimmer.wrap(server, '_onHandlerError', function (orig) {
27
+ return function _wrappedOnHandlerError(err, req, res, isUncaught) {
28
+ if (err)
29
+ agent.captureError(err, { request: req, handled: !isUncaught });
30
+ return orig.apply(this, arguments);
31
+ };
32
+ });
33
+ } else {
34
+ shimmer.wrap(server, '_emitErrorEvents', function (orig) {
35
+ return function _wrappedOnHandlerError(req, res, route, err, cb) {
36
+ if (err) agent.captureError(err, { request: req });
37
+ return orig.apply(this, arguments);
38
+ };
39
+ });
40
+ }
41
+ }
42
+
43
+ shimmer.wrap(restify, 'createServer', function (fn) {
44
+ return function wrappedCreateServer() {
45
+ const server = fn.apply(this, arguments);
46
+ patchServer(server);
47
+ return server;
48
+ };
49
+ });
50
+
51
+ return restify;
52
+ };
@@ -0,0 +1,159 @@
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
+ var clone = require('shallow-clone-shim');
11
+ var sqlSummary = require('sql-summary');
12
+
13
+ var { getDBDestination } = require('../context');
14
+
15
+ module.exports = function (tedious, agent, { version, enabled }) {
16
+ if (!enabled) return tedious;
17
+ if (
18
+ semver.satisfies(version, '>=19') &&
19
+ !semver.satisfies(process.version, '>=18.17')
20
+ ) {
21
+ agent.logger.debug(
22
+ 'tedious version %s not supported for node %s - aborting...',
23
+ version,
24
+ process.version,
25
+ );
26
+ return tedious;
27
+ }
28
+ if (version === '4.0.0' || !semver.satisfies(version, '>=1.9.0 <20')) {
29
+ agent.logger.debug(
30
+ 'tedious version %s not supported - aborting...',
31
+ version,
32
+ );
33
+ return tedious;
34
+ }
35
+
36
+ const ins = agent._instrumentation;
37
+
38
+ return clone({}, tedious, {
39
+ Connection(descriptor) {
40
+ const getter = descriptor.get;
41
+ if (getter) {
42
+ // tedious v6.5.0+
43
+ descriptor.get = function get() {
44
+ return wrapConnection(getter());
45
+ };
46
+ } else if (typeof descriptor.value === 'function') {
47
+ descriptor.value = wrapConnection(descriptor.value);
48
+ } else {
49
+ agent.logger.debug(
50
+ 'could not patch `tedious.Connection` property for tedious version %s - aborting...',
51
+ version,
52
+ );
53
+ }
54
+ return descriptor;
55
+ },
56
+ Request(descriptor) {
57
+ const getter = descriptor.get;
58
+ if (getter) {
59
+ // tedious v6.5.0+
60
+ descriptor.get = function get() {
61
+ return wrapRequest(getter());
62
+ };
63
+ } else if (typeof descriptor.value === 'function') {
64
+ descriptor.value = wrapRequest(descriptor.value);
65
+ } else {
66
+ agent.logger.debug(
67
+ 'could not patch `tedious.Request` property for tedious version %s - aborting...',
68
+ version,
69
+ );
70
+ }
71
+ return descriptor;
72
+ },
73
+ });
74
+
75
+ function wrapRequest(OriginalRequest) {
76
+ class Request extends OriginalRequest {
77
+ constructor() {
78
+ super(...arguments);
79
+ ins.bindEmitter(this);
80
+ }
81
+ }
82
+
83
+ return Request;
84
+ }
85
+
86
+ function wrapConnection(OriginalConnection) {
87
+ class Connection extends OriginalConnection {
88
+ constructor() {
89
+ super(...arguments);
90
+ ins.bindEmitter(this);
91
+ }
92
+
93
+ makeRequest(request, _packetType, payload) {
94
+ // if not a Request object (i.e. a BulkLoad), then bail
95
+ if (!request.parametersByName) {
96
+ return super.makeRequest(...arguments);
97
+ }
98
+ const span = ins.createSpan(null, 'db', 'mssql', 'query', {
99
+ exitSpan: true,
100
+ });
101
+ if (!span) {
102
+ return super.makeRequest(...arguments);
103
+ }
104
+
105
+ let host, port, instanceName;
106
+ if (typeof this.config === 'object') {
107
+ // http://tediousjs.github.io/tedious/api-connection.html#function_newConnection
108
+ host = this.config.server;
109
+ if (this.config.options) {
110
+ port = this.config.options.port;
111
+ instanceName = this.config.options.instanceName;
112
+ }
113
+ }
114
+ span._setDestinationContext(getDBDestination(host, port));
115
+
116
+ let sql;
117
+ let preparing;
118
+ if (payload.parameters !== undefined) {
119
+ // This looks for tedious instance with `RpcRequestPayload` started
120
+ // since version >=v11.0.10, when RPC parameter handling was refactored
121
+ // (https://github.com/tediousjs/tedious/pull/1275).
122
+ preparing =
123
+ typeof payload.procedure === 'number'
124
+ ? // tedious@16.2.0 starts using stored procedure *IDs*
125
+ // (https://github.com/tediousjs/tedious/pull/1327)
126
+ payload.procedure === 11
127
+ : payload.procedure === 'sp_prepare';
128
+ const stmtParam =
129
+ payload.parameters.find(({ name }) => name === 'statement') ||
130
+ payload.parameters.find(({ name }) => name === 'stmt');
131
+ sql = stmtParam ? stmtParam.value : request.sqlTextOrProcedure;
132
+ } else {
133
+ preparing = request.sqlTextOrProcedure === 'sp_prepare';
134
+ const params = request.parametersByName;
135
+ sql = (params.statement || params.stmt || {}).value;
136
+ }
137
+ span.name = sqlSummary(sql) + (preparing ? ' (prepare)' : '');
138
+ const dbContext = { type: 'sql', statement: sql };
139
+ if (instanceName) {
140
+ dbContext.instance = instanceName;
141
+ }
142
+ span.setDbContext(dbContext);
143
+
144
+ const origCallback = request.userCallback;
145
+ request.userCallback = ins.bindFunction(function tracedCallback() {
146
+ // TODO: captureError and setOutcome on err first arg here
147
+ span.end();
148
+ if (origCallback) {
149
+ return origCallback.apply(this, arguments);
150
+ }
151
+ });
152
+
153
+ return super.makeRequest(...arguments);
154
+ }
155
+ }
156
+
157
+ return Connection;
158
+ }
159
+ };