@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.
- package/LICENSE +26 -0
- package/NOTICE.md +442 -0
- package/README.md +48 -0
- package/changes.json +78 -0
- package/index.d.ts +398 -0
- package/index.js +11 -0
- package/lib/InflightEventSet.js +53 -0
- package/lib/activation-method.js +119 -0
- package/lib/agent.js +941 -0
- package/lib/apm-client/apm-client.js +313 -0
- package/lib/apm-client/http-apm-client/CHANGELOG.md +271 -0
- package/lib/apm-client/http-apm-client/README.md +485 -0
- package/lib/apm-client/http-apm-client/central-config.js +41 -0
- package/lib/apm-client/http-apm-client/container-info.js +111 -0
- package/lib/apm-client/http-apm-client/detect-hostname.js +96 -0
- package/lib/apm-client/http-apm-client/index.js +1975 -0
- package/lib/apm-client/http-apm-client/logging.js +31 -0
- package/lib/apm-client/http-apm-client/ndjson.js +20 -0
- package/lib/apm-client/http-apm-client/truncate.js +434 -0
- package/lib/apm-client/noop-apm-client.js +73 -0
- package/lib/async-hooks-polyfill.js +58 -0
- package/lib/cloud-metadata/aws.js +175 -0
- package/lib/cloud-metadata/azure.js +123 -0
- package/lib/cloud-metadata/callback-coordination.js +159 -0
- package/lib/cloud-metadata/gcp.js +133 -0
- package/lib/cloud-metadata/index.js +175 -0
- package/lib/config/config.js +458 -0
- package/lib/config/normalizers.js +701 -0
- package/lib/config/schema.js +1007 -0
- package/lib/constants.js +35 -0
- package/lib/errors.js +303 -0
- package/lib/filters/sanitize-field-names.js +69 -0
- package/lib/http-request.js +249 -0
- package/lib/instrumentation/azure-functions.js +519 -0
- package/lib/instrumentation/context.js +56 -0
- package/lib/instrumentation/dropped-spans-stats.js +112 -0
- package/lib/instrumentation/elasticsearch-shared.js +63 -0
- package/lib/instrumentation/express-utils.js +91 -0
- package/lib/instrumentation/generic-span.js +322 -0
- package/lib/instrumentation/http-shared.js +424 -0
- package/lib/instrumentation/ids.js +39 -0
- package/lib/instrumentation/index.js +1127 -0
- package/lib/instrumentation/modules/@apollo/server.js +30 -0
- package/lib/instrumentation/modules/@aws-sdk/client-dynamodb.js +143 -0
- package/lib/instrumentation/modules/@aws-sdk/client-s3.js +230 -0
- package/lib/instrumentation/modules/@aws-sdk/client-sns.js +197 -0
- package/lib/instrumentation/modules/@aws-sdk/client-sqs.js +336 -0
- package/lib/instrumentation/modules/@elastic/elasticsearch.js +343 -0
- package/lib/instrumentation/modules/@hapi/hapi.js +221 -0
- package/lib/instrumentation/modules/@opentelemetry/api.js +86 -0
- package/lib/instrumentation/modules/@opentelemetry/sdk-metrics.js +79 -0
- package/lib/instrumentation/modules/@redis/client/dist/lib/client/commands-queue.js +178 -0
- package/lib/instrumentation/modules/@redis/client/dist/lib/client/index.js +49 -0
- package/lib/instrumentation/modules/@smithy/smithy-client.js +198 -0
- package/lib/instrumentation/modules/_lambda-handler.js +40 -0
- package/lib/instrumentation/modules/apollo-server-core.js +49 -0
- package/lib/instrumentation/modules/aws-sdk/dynamodb.js +155 -0
- package/lib/instrumentation/modules/aws-sdk/s3.js +184 -0
- package/lib/instrumentation/modules/aws-sdk/sns.js +232 -0
- package/lib/instrumentation/modules/aws-sdk/sqs.js +361 -0
- package/lib/instrumentation/modules/aws-sdk.js +76 -0
- package/lib/instrumentation/modules/bluebird.js +93 -0
- package/lib/instrumentation/modules/cassandra-driver.js +280 -0
- package/lib/instrumentation/modules/elasticsearch.js +191 -0
- package/lib/instrumentation/modules/express-graphql.js +66 -0
- package/lib/instrumentation/modules/express-queue.js +28 -0
- package/lib/instrumentation/modules/express.js +162 -0
- package/lib/instrumentation/modules/fastify.js +172 -0
- package/lib/instrumentation/modules/finalhandler.js +41 -0
- package/lib/instrumentation/modules/generic-pool.js +85 -0
- package/lib/instrumentation/modules/graphql.js +256 -0
- package/lib/instrumentation/modules/handlebars.js +22 -0
- package/lib/instrumentation/modules/http.js +112 -0
- package/lib/instrumentation/modules/http2.js +320 -0
- package/lib/instrumentation/modules/https.js +68 -0
- package/lib/instrumentation/modules/ioredis.js +94 -0
- package/lib/instrumentation/modules/jade.js +18 -0
- package/lib/instrumentation/modules/kafkajs.js +476 -0
- package/lib/instrumentation/modules/knex.js +91 -0
- package/lib/instrumentation/modules/koa-router.js +74 -0
- package/lib/instrumentation/modules/koa.js +15 -0
- package/lib/instrumentation/modules/memcached.js +99 -0
- package/lib/instrumentation/modules/mimic-response.js +45 -0
- package/lib/instrumentation/modules/mongodb/lib/cmap/connection_pool.js +40 -0
- package/lib/instrumentation/modules/mongodb-core.js +206 -0
- package/lib/instrumentation/modules/mongodb.js +259 -0
- package/lib/instrumentation/modules/mysql.js +200 -0
- package/lib/instrumentation/modules/mysql2.js +140 -0
- package/lib/instrumentation/modules/pg.js +148 -0
- package/lib/instrumentation/modules/pug.js +18 -0
- package/lib/instrumentation/modules/redis.js +176 -0
- package/lib/instrumentation/modules/restify.js +52 -0
- package/lib/instrumentation/modules/tedious.js +159 -0
- package/lib/instrumentation/modules/undici.js +270 -0
- package/lib/instrumentation/modules/ws.js +59 -0
- package/lib/instrumentation/noop-transaction.js +81 -0
- package/lib/instrumentation/run-context/AbstractRunContextManager.js +215 -0
- package/lib/instrumentation/run-context/AsyncHooksRunContextManager.js +106 -0
- package/lib/instrumentation/run-context/AsyncLocalStorageRunContextManager.js +73 -0
- package/lib/instrumentation/run-context/BasicRunContextManager.js +82 -0
- package/lib/instrumentation/run-context/RunContext.js +151 -0
- package/lib/instrumentation/run-context/index.js +23 -0
- package/lib/instrumentation/shimmer.js +123 -0
- package/lib/instrumentation/span-compression.js +239 -0
- package/lib/instrumentation/span.js +621 -0
- package/lib/instrumentation/template-shared.js +43 -0
- package/lib/instrumentation/timer.js +84 -0
- package/lib/instrumentation/transaction.js +571 -0
- package/lib/lambda.js +992 -0
- package/lib/load-source-map.js +100 -0
- package/lib/logging.js +212 -0
- package/lib/metrics/index.js +92 -0
- package/lib/metrics/platforms/generic/index.js +40 -0
- package/lib/metrics/platforms/generic/process-cpu.js +22 -0
- package/lib/metrics/platforms/generic/process-top.js +157 -0
- package/lib/metrics/platforms/generic/stats.js +34 -0
- package/lib/metrics/platforms/generic/system-cpu.js +51 -0
- package/lib/metrics/platforms/linux/index.js +19 -0
- package/lib/metrics/platforms/linux/stats.js +213 -0
- package/lib/metrics/queue.js +90 -0
- package/lib/metrics/registry.js +52 -0
- package/lib/metrics/reporter.js +119 -0
- package/lib/metrics/runtime.js +77 -0
- package/lib/middleware/connect.js +16 -0
- package/lib/opentelemetry-bridge/OTelBridgeNonRecordingSpan.js +150 -0
- package/lib/opentelemetry-bridge/OTelBridgeRunContext.js +124 -0
- package/lib/opentelemetry-bridge/OTelContextManager.js +82 -0
- package/lib/opentelemetry-bridge/OTelSpan.js +344 -0
- package/lib/opentelemetry-bridge/OTelTracer.js +201 -0
- package/lib/opentelemetry-bridge/OTelTracerProvider.js +25 -0
- package/lib/opentelemetry-bridge/README.md +244 -0
- package/lib/opentelemetry-bridge/index.js +15 -0
- package/lib/opentelemetry-bridge/oblog.js +23 -0
- package/lib/opentelemetry-bridge/opentelemetry-core-mini/README.md +3 -0
- package/lib/opentelemetry-bridge/opentelemetry-core-mini/internal/validators.js +52 -0
- package/lib/opentelemetry-bridge/opentelemetry-core-mini/trace/TraceState.js +109 -0
- package/lib/opentelemetry-bridge/otelutils.js +99 -0
- package/lib/opentelemetry-bridge/setup.js +76 -0
- package/lib/opentelemetry-metrics/ElasticApmMetricExporter.js +285 -0
- package/lib/opentelemetry-metrics/index.js +50 -0
- package/lib/parsers.js +225 -0
- package/lib/propwrap.js +147 -0
- package/lib/stacktraces.js +537 -0
- package/lib/symbols.js +15 -0
- package/lib/tracecontext/index.js +118 -0
- package/lib/tracecontext/traceparent.js +185 -0
- package/lib/tracecontext/tracestate.js +388 -0
- package/lib/wildcard-matcher.js +52 -0
- package/loader.mjs +7 -0
- package/package.json +299 -0
- package/start.d.ts +8 -0
- package/start.js +29 -0
- package/types/aws-lambda.d.ts +98 -0
- 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
|
+
};
|