newrelic 8.2.0 → 8.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NEWS.md +5061 -4963
- package/README.md +7 -6
- package/THIRD_PARTY_NOTICES.md +95 -68
- package/api.js +74 -68
- package/bin/test-naming-rules.js +22 -22
- package/lib/agent.js +4 -4
- package/lib/attributes.js +2 -2
- package/lib/collector/api.js +12 -12
- package/lib/collector/facts.js +2 -3
- package/lib/collector/http-agents.js +12 -11
- package/lib/collector/key-parser.js +1 -1
- package/lib/collector/remote-method.js +27 -26
- package/lib/config/attribute-filter.js +23 -23
- package/lib/config/default.js +26 -9
- package/lib/config/env.js +14 -4
- package/lib/config/hsm.js +1 -1
- package/lib/config/index.js +90 -69
- package/lib/config/lasp.js +3 -3
- package/lib/config/merge-server-config.js +1 -1
- package/lib/db/parse-sql.js +8 -8
- package/lib/db/parsed-statement.js +9 -8
- package/lib/db/query-parsers/sql.js +7 -7
- package/lib/db/query-sample.js +9 -9
- package/lib/db/query-trace-aggregator.js +4 -4
- package/lib/db/statement-matcher.js +5 -5
- package/lib/db/utils.js +1 -1
- package/lib/environment.js +43 -43
- package/lib/errors/error-collector.js +2 -2
- package/lib/errors/error-trace-aggregator.js +1 -1
- package/lib/errors/helper.js +3 -3
- package/lib/errors/index.js +17 -17
- package/lib/feature_flags.js +7 -5
- package/lib/header-attributes.js +6 -6
- package/lib/header-processing.js +1 -1
- package/lib/instrumentation/amqplib.js +26 -26
- package/lib/instrumentation/bluebird.js +3 -3
- package/lib/instrumentation/cassandra-driver.js +7 -3
- package/lib/instrumentation/connect.js +4 -4
- package/lib/instrumentation/core/async_hooks.js +6 -6
- package/lib/instrumentation/core/domain.js +2 -2
- package/lib/instrumentation/core/globals.js +1 -1
- package/lib/instrumentation/core/http-outbound.js +15 -84
- package/lib/instrumentation/core/http.js +34 -67
- package/lib/instrumentation/core/inspector.js +2 -2
- package/lib/instrumentation/core/timers.js +7 -7
- package/lib/instrumentation/core/zlib.js +2 -2
- package/lib/instrumentation/director.js +4 -4
- package/lib/instrumentation/express.js +8 -8
- package/lib/instrumentation/fastify/spec-builders.js +57 -47
- package/lib/instrumentation/fastify.js +111 -28
- package/lib/instrumentation/generic-pool.js +1 -1
- package/lib/instrumentation/hapi/hapi-17.js +11 -11
- package/lib/instrumentation/hapi/shared.js +1 -1
- package/lib/instrumentation/hapi.js +22 -22
- package/lib/instrumentation/ioredis.js +7 -7
- package/lib/instrumentation/memcached.js +7 -7
- package/lib/instrumentation/mongodb/common.js +73 -23
- package/lib/instrumentation/mongodb/v3-mongo.js +20 -1
- package/lib/instrumentation/mongodb/v4-mongo.js +6 -7
- package/lib/instrumentation/mysql.js +19 -19
- package/lib/instrumentation/oracle.js +15 -15
- package/lib/instrumentation/pg.js +4 -4
- package/lib/instrumentation/promise.js +46 -46
- package/lib/instrumentation/q.js +2 -2
- package/lib/instrumentation/redis.js +11 -11
- package/lib/instrumentation/restify.js +1 -1
- package/lib/instrumentation/undici.js +242 -0
- package/lib/instrumentation/vision.js +4 -4
- package/lib/instrumentation/when.js +3 -3
- package/lib/instrumentations.js +2 -1
- package/lib/logger.js +5 -5
- package/lib/metrics/index.js +15 -15
- package/lib/metrics/mapper.js +7 -7
- package/lib/metrics/names.js +6 -3
- package/lib/metrics/normalizer/rule.js +9 -9
- package/lib/metrics/normalizer/tx_segment.js +17 -17
- package/lib/metrics/normalizer.js +22 -22
- package/lib/metrics/recorders/custom.js +5 -5
- package/lib/metrics/recorders/generic.js +3 -3
- package/lib/metrics/recorders/http.js +7 -7
- package/lib/metrics/recorders/http_external.js +7 -7
- package/lib/metrics/recorders/message-transaction.js +5 -6
- package/lib/metrics/recorders/other.js +5 -5
- package/lib/parse-proc-cpuinfo.js +25 -19
- package/lib/parse-proc-meminfo.js +8 -2
- package/lib/prioritized-attributes.js +2 -2
- package/lib/priority-queue.js +10 -10
- package/lib/reservoir.js +3 -3
- package/lib/sampler.js +26 -26
- package/lib/shim/datastore-shim.js +35 -32
- package/lib/shim/index.js +2 -2
- package/lib/shim/message-shim.js +47 -47
- package/lib/shim/promise-shim.js +1 -1
- package/lib/shim/shim.js +61 -61
- package/lib/shim/specs/index.js +3 -3
- package/lib/shim/transaction-shim.js +44 -192
- package/lib/shim/webframework-shim.js +52 -52
- package/lib/spans/span-event-aggregator.js +62 -10
- package/lib/spans/span-event.js +1 -1
- package/lib/spans/streaming-span-attributes.js +1 -1
- package/lib/stats/apdex.js +2 -2
- package/lib/stats/index.js +2 -2
- package/lib/system-info.js +23 -23
- package/lib/timer.js +5 -5
- package/lib/transaction/dt-payload.js +1 -1
- package/lib/transaction/index.js +40 -40
- package/lib/transaction/name-state.js +14 -14
- package/lib/transaction/trace/exclusive-time-calculator.js +6 -6
- package/lib/transaction/trace/index.js +14 -14
- package/lib/transaction/trace/segment.js +18 -18
- package/lib/transaction/tracecontext.js +1 -1
- package/lib/transaction/tracer/index.js +53 -49
- package/lib/uninstrumented.js +7 -7
- package/lib/util/arity.js +2 -2
- package/lib/util/byte-limit.js +4 -4
- package/lib/util/cat.js +269 -24
- package/lib/util/codec.js +2 -2
- package/lib/util/copy.js +2 -2
- package/lib/util/deep-equal.js +10 -10
- package/lib/util/flatten.js +4 -4
- package/lib/util/hashes.js +14 -14
- package/lib/util/label-parser.js +17 -17
- package/lib/util/logger.js +24 -24
- package/lib/util/process-version.js +2 -2
- package/lib/util/properties.js +4 -4
- package/lib/util/sql/obfuscate.js +15 -15
- package/lib/util/stream-sink.js +3 -3
- package/lib/util/unwrapped-core.js +2 -2
- package/lib/util/urltils.js +16 -16
- package/lib/utilization/aws-info.js +7 -7
- package/lib/utilization/azure-info.js +6 -6
- package/lib/utilization/common.js +13 -13
- package/lib/utilization/docker-info.js +11 -11
- package/lib/utilization/gcp-info.js +4 -4
- package/lib/utilization/index.js +5 -5
- package/lib/utilization/pcf-info.js +9 -9
- package/package.json +13 -7
- package/stub_api.js +8 -8
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
const { CURSOR_OPS, COLLECTION_OPS, DB_OPS } = require('./constants')
|
|
8
|
-
const { URL } = require('url')
|
|
9
|
-
|
|
10
8
|
const common = module.exports
|
|
9
|
+
common.NR_ATTRS = Symbol('NR_ATTRS')
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* Instruments all methods from constants.CURSOR_OPS on a given
|
|
@@ -24,7 +23,7 @@ common.instrumentCursor = function instrumentCursor(shim, Cursor) {
|
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
shim.recordQuery(proto, 'each', common.makeQueryDescFunc(shim, 'each'))
|
|
27
|
-
shim.recordOperation(proto, 'pipe')
|
|
26
|
+
shim.recordOperation(proto, 'pipe', { opaque: true })
|
|
28
27
|
}
|
|
29
28
|
}
|
|
30
29
|
|
|
@@ -48,9 +47,11 @@ common.instrumentCollection = function instrumentCollection(shim, Collection) {
|
|
|
48
47
|
* Instruments all methods from constants.DB_OPS on
|
|
49
48
|
* the Db class.
|
|
50
49
|
*
|
|
51
|
-
* @param {
|
|
50
|
+
* @param {object} params
|
|
52
51
|
* @param {Shim} params.shim
|
|
53
52
|
* @param {Db} params.Db
|
|
53
|
+
* @param shim
|
|
54
|
+
* @param Db
|
|
54
55
|
*/
|
|
55
56
|
common.instrumentDb = function instrumentDb(shim, Db) {
|
|
56
57
|
if (Db && Db.prototype) {
|
|
@@ -63,6 +64,7 @@ common.instrumentDb = function instrumentDb(shim, Db) {
|
|
|
63
64
|
|
|
64
65
|
/**
|
|
65
66
|
* Sets up the desc for all instrumented query methods
|
|
67
|
+
*
|
|
66
68
|
* @param {Shim} shim
|
|
67
69
|
* @param {string} methodName
|
|
68
70
|
*/
|
|
@@ -97,18 +99,16 @@ common.captureAttributesOnStarted = function captureAttributesOnStarted(shim, in
|
|
|
97
99
|
// out of an excess of caution.
|
|
98
100
|
const connId = evnt.connectionId
|
|
99
101
|
if (connId) {
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
} else {
|
|
108
|
-
shim.captureInstanceAttributes(parts[0], parts[1], evnt.databaseName)
|
|
109
|
-
}
|
|
102
|
+
// used in v3 when connection is a cluster pool
|
|
103
|
+
if (typeof connId === 'number') {
|
|
104
|
+
setHostPort(shim, evnt.address, evnt.databaseName, this.$MongoClient)
|
|
105
|
+
// used in v3 when connection is to 1 host
|
|
106
|
+
} else if (typeof connId === 'string') {
|
|
107
|
+
setHostPort(shim, connId, evnt.databaseName)
|
|
108
|
+
// v2 contains `domainSocket`, get socket connection from `host`
|
|
110
109
|
} else if (connId.domainSocket) {
|
|
111
110
|
shim.captureInstanceAttributes('localhost', connId.host, evnt.databaseName)
|
|
111
|
+
// v2 remote connection get `host` `port` from respective properties
|
|
112
112
|
} else {
|
|
113
113
|
shim.captureInstanceAttributes(connId.host, connId.port, evnt.databaseName)
|
|
114
114
|
}
|
|
@@ -116,11 +116,49 @@ common.captureAttributesOnStarted = function captureAttributesOnStarted(shim, in
|
|
|
116
116
|
})
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Extracts the host and port from a connection string
|
|
121
|
+
* This also handles if connection string is a domain socket
|
|
122
|
+
* Mongo sticks the path to the domain socket in the "host" slot, but we
|
|
123
|
+
* want it in the "port", so if we have a domain socket we need to change
|
|
124
|
+
* the order of our parameters.
|
|
125
|
+
*
|
|
126
|
+
* @param {Shim} shim
|
|
127
|
+
* @param {string} connStr
|
|
128
|
+
* @param {string} db database name
|
|
129
|
+
* @param {object} client mongo client instance
|
|
130
|
+
*/
|
|
131
|
+
function setHostPort(shim, connStr, db, client) {
|
|
132
|
+
const parts = connStr.split(':')
|
|
133
|
+
// in v3 when running with a cluster of socket connections
|
|
134
|
+
// the address is `undefined:undefined`. we will instead attempt
|
|
135
|
+
// to get connection details from the client symbol NR_ATTRS
|
|
136
|
+
// added in `lib/instrumentation/mongodb/v3-mongo` when a client connects
|
|
137
|
+
// with a URL string
|
|
138
|
+
if (parts.includes('undefined')) {
|
|
139
|
+
try {
|
|
140
|
+
const attrs = client[common.NR_ATTRS]
|
|
141
|
+
const socket = decodeURIComponent(attrs.split(',')[0].split('mongodb://')[1])
|
|
142
|
+
shim.captureInstanceAttributes('localhost', socket, db)
|
|
143
|
+
} catch (err) {
|
|
144
|
+
shim.logger.debug(err, 'Could not extract host/port from mongo command')
|
|
145
|
+
}
|
|
146
|
+
// connected using domain socket but the "host"(e.g: /path/to/mongo-socket-port.sock)
|
|
147
|
+
} else if (parts.length && parts[0][0] === '/') {
|
|
148
|
+
shim.captureInstanceAttributes('localhost', parts[0], db)
|
|
149
|
+
} else {
|
|
150
|
+
shim.captureInstanceAttributes(parts[0], parts[1], db)
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
119
154
|
/**
|
|
120
155
|
* Get the database_name, host, port_path_or_id
|
|
121
156
|
* for the query segment. v4 refactored where the toplogy is stored.
|
|
122
157
|
* You can now get the details via the client obj that's deeply nested
|
|
123
158
|
* See: https://github.com/mongodb/node-mongodb-native/pull/2594/files#diff-1d214e57ddda9095d296e5700ebce701333bfefcf417e234c584d14091b2f50dR168
|
|
159
|
+
*
|
|
160
|
+
* @param shim
|
|
161
|
+
* @param obj
|
|
124
162
|
*/
|
|
125
163
|
function getInstanceAttributeParameters(shim, obj) {
|
|
126
164
|
if (obj.s && obj.s.db && obj.s.topology) {
|
|
@@ -136,13 +174,18 @@ function getInstanceAttributeParameters(shim, obj) {
|
|
|
136
174
|
obj.s.db.s &&
|
|
137
175
|
obj.s.db.s.client &&
|
|
138
176
|
obj.s.db.s.client.s &&
|
|
139
|
-
obj.s.db.s.client.s.
|
|
177
|
+
obj.s.db.s.client.s.options &&
|
|
178
|
+
obj.s.db.s.client.s.options.hosts &&
|
|
179
|
+
obj.s.db.s.client.s.options.hosts.length
|
|
140
180
|
) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
181
|
+
// hosts is an array but we will always pull the first for consistency
|
|
182
|
+
const hosts = obj.s.db.s.client.s.options.hosts
|
|
183
|
+
let host = hosts[0].host
|
|
184
|
+
let port = hosts[0].port
|
|
185
|
+
const socketPath = hosts[0].socketPath
|
|
186
|
+
|
|
187
|
+
if (socketPath) {
|
|
188
|
+
port = socketPath
|
|
146
189
|
host = 'localhost'
|
|
147
190
|
}
|
|
148
191
|
return {
|
|
@@ -160,12 +203,19 @@ function getInstanceAttributeParameters(shim, obj) {
|
|
|
160
203
|
}
|
|
161
204
|
|
|
162
205
|
function doCapture(conf, database) {
|
|
206
|
+
// in older versions of 3.x the host/port
|
|
207
|
+
// lived directly on the topology.s.options
|
|
163
208
|
let host = conf.host
|
|
164
209
|
let port = conf.port
|
|
165
210
|
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
211
|
+
// servers is an array but we will always pull the first for consistency
|
|
212
|
+
if (conf.servers && conf.servers.length) {
|
|
213
|
+
;[{ host, port }] = conf.servers
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// host is a domain socket. set host as localhost and use the domain
|
|
217
|
+
// socket host as the port
|
|
218
|
+
if (host && host.endsWith('.sock')) {
|
|
169
219
|
port = host
|
|
170
220
|
host = 'localhost'
|
|
171
221
|
}
|
|
@@ -9,7 +9,8 @@ const {
|
|
|
9
9
|
captureAttributesOnStarted,
|
|
10
10
|
instrumentCollection,
|
|
11
11
|
instrumentCursor,
|
|
12
|
-
instrumentDb
|
|
12
|
+
instrumentDb,
|
|
13
|
+
NR_ATTRS
|
|
13
14
|
} = require('./common')
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -30,6 +31,23 @@ function queryParser(operation) {
|
|
|
30
31
|
return { operation, collection }
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Records the `mongo.MongoClient.connect` operations. It also adds the first arg of connect(url)
|
|
36
|
+
* to a Symbol on the MongoClient to be used later to extract the host/port in cases where the topology
|
|
37
|
+
* is a cluster of domain sockets
|
|
38
|
+
*
|
|
39
|
+
* @param {Shim} shim
|
|
40
|
+
* @param {Object} mongodb resolved package
|
|
41
|
+
*/
|
|
42
|
+
function instrumentClient(shim, mongodb) {
|
|
43
|
+
shim.recordOperation(mongodb.MongoClient, 'connect', function wrappedConnect(shim, _, __, args) {
|
|
44
|
+
// Add the connection url to the MongoClient to retrieve later in the `lib/instrumentation/mongo/common`
|
|
45
|
+
// captureAttributesOnStarted listener
|
|
46
|
+
this[NR_ATTRS] = args[0]
|
|
47
|
+
return { callback: shim.LAST }
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
|
|
33
51
|
/**
|
|
34
52
|
* Registers relevant instrumentation for mongo >= 3.0.6
|
|
35
53
|
* In 3.0.6 they refactored their "APM" module which removed
|
|
@@ -44,6 +62,7 @@ function queryParser(operation) {
|
|
|
44
62
|
*/
|
|
45
63
|
module.exports = function instrument(shim, mongodb) {
|
|
46
64
|
shim.setParser(queryParser)
|
|
65
|
+
instrumentClient(shim, mongodb)
|
|
47
66
|
const instrumenter = mongodb.instrument(Object.create(null), () => {})
|
|
48
67
|
captureAttributesOnStarted(shim, instrumenter)
|
|
49
68
|
instrumentCursor(shim, mongodb.Cursor)
|
|
@@ -36,15 +36,14 @@ function cmdStartedHandler(shim, evnt) {
|
|
|
36
36
|
if (evnt.connectionId) {
|
|
37
37
|
let [host, port] = evnt.address.split(':')
|
|
38
38
|
|
|
39
|
-
// connection via socket get port from
|
|
40
|
-
//
|
|
39
|
+
// connection via socket get port from 1st host
|
|
40
|
+
// socketPath property
|
|
41
|
+
// which looks like mongodb:///tmp/mongodb-27017.sock"
|
|
41
42
|
if (['undefined'].includes(host, port)) {
|
|
42
43
|
host = 'localhost'
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (socketPath.length && socketPath[1].startsWith('//')) {
|
|
47
|
-
port = decodeURIComponent(socketPath[1].substr(2))
|
|
44
|
+
const hosts = this.s.options.hosts
|
|
45
|
+
if (hosts && hosts.length && hosts[0].socketPath) {
|
|
46
|
+
port = hosts[0].socketPath
|
|
48
47
|
}
|
|
49
48
|
} else if (host === '127.0.0.1') {
|
|
50
49
|
host = 'localhost'
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
const dbutils = require('../db/utils')
|
|
9
|
+
const properties = require('../util/properties')
|
|
10
10
|
|
|
11
11
|
module.exports = function initialize(agent, mysql, moduleName, shim) {
|
|
12
12
|
shim.setDatastore(shim.MYSQL)
|
|
@@ -16,7 +16,7 @@ module.exports = function initialize(agent, mysql, moduleName, shim) {
|
|
|
16
16
|
function wrapCreateConnection(shim, fn, fnName, connection) {
|
|
17
17
|
shim.logger.debug('Wrapping Connection#query')
|
|
18
18
|
if (wrapQueriable(shim, connection, false)) {
|
|
19
|
-
|
|
19
|
+
const connProto = Object.getPrototypeOf(connection)
|
|
20
20
|
shim.setInternalProperty(connProto, '__NR_storeDatabase', true)
|
|
21
21
|
shim.unwrap(mysql, 'createConnection')
|
|
22
22
|
}
|
|
@@ -33,7 +33,7 @@ module.exports = function initialize(agent, mysql, moduleName, shim) {
|
|
|
33
33
|
shim.wrapReturn(mysql, 'createPoolCluster', wrapCreatePoolCluster)
|
|
34
34
|
function wrapCreatePoolCluster(shim, fn, fnName, poolCluster) {
|
|
35
35
|
shim.logger.debug('Wrapping PoolCluster#of')
|
|
36
|
-
|
|
36
|
+
const proto = Object.getPrototypeOf(poolCluster)
|
|
37
37
|
shim.wrapReturn(proto, 'of', wrapPoolClusterOf)
|
|
38
38
|
function wrapPoolClusterOf(shim, of, _n, poolNamespace) {
|
|
39
39
|
if (wrapGetConnection(shim, poolNamespace)) {
|
|
@@ -61,11 +61,11 @@ function wrapGetConnection(shim, connectable) {
|
|
|
61
61
|
return false
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
const proto = Object.getPrototypeOf(connectable)
|
|
65
65
|
shim.wrap(proto, 'getConnection', function doWrapGetConnection(shim, fn) {
|
|
66
66
|
return function wrappedGetConnection() {
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
const args = shim.toArray(arguments)
|
|
68
|
+
const cbIdx = args.length - 1
|
|
69
69
|
|
|
70
70
|
if (shim.isFunction(args[cbIdx]) && !shim.isWrapped(args[cbIdx])) {
|
|
71
71
|
shim.logger.trace(
|
|
@@ -74,7 +74,7 @@ function wrapGetConnection(shim, connectable) {
|
|
|
74
74
|
},
|
|
75
75
|
'Wrapping callback with segment'
|
|
76
76
|
)
|
|
77
|
-
|
|
77
|
+
let cb = args[cbIdx]
|
|
78
78
|
if (!shim.__wrappedPoolConnection) {
|
|
79
79
|
cb = shim.wrap(cb, wrapGetConnectionCallback)
|
|
80
80
|
}
|
|
@@ -119,9 +119,9 @@ function wrapQueriable(shim, queriable, isPoolQuery) {
|
|
|
119
119
|
return false
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
|
|
122
|
+
const proto = Object.getPrototypeOf(queriable)
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
let describe
|
|
125
125
|
if (isPoolQuery) {
|
|
126
126
|
describe = describePoolQuery
|
|
127
127
|
} else {
|
|
@@ -139,8 +139,8 @@ function wrapQueriable(shim, queriable, isPoolQuery) {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
function extractQueryArgs(shim, args) {
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
let query = ''
|
|
143
|
+
let callback = null
|
|
144
144
|
|
|
145
145
|
// Figure out the query parameter.
|
|
146
146
|
if (shim.isString(args[0])) {
|
|
@@ -168,10 +168,10 @@ function extractQueryArgs(shim, args) {
|
|
|
168
168
|
|
|
169
169
|
function describeQuery(shim, queryFn, fnName, args) {
|
|
170
170
|
shim.logger.trace('Recording query')
|
|
171
|
-
|
|
171
|
+
const extractedArgs = extractQueryArgs(shim, args)
|
|
172
172
|
|
|
173
173
|
// Pull out instance attributes.
|
|
174
|
-
|
|
174
|
+
const parameters = getInstanceParameters(shim, this, extractedArgs.query)
|
|
175
175
|
|
|
176
176
|
shim.logger.trace(
|
|
177
177
|
{
|
|
@@ -193,7 +193,7 @@ function describeQuery(shim, queryFn, fnName, args) {
|
|
|
193
193
|
|
|
194
194
|
function describePoolQuery(shim, queryFn, fnName, args) {
|
|
195
195
|
shim.logger.trace('Recording pool query')
|
|
196
|
-
|
|
196
|
+
const extractedArgs = extractQueryArgs(shim, args)
|
|
197
197
|
return {
|
|
198
198
|
stream: true,
|
|
199
199
|
query: null,
|
|
@@ -204,10 +204,10 @@ function describePoolQuery(shim, queryFn, fnName, args) {
|
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
function getInstanceParameters(shim, queryable, query) {
|
|
207
|
-
|
|
208
|
-
|
|
207
|
+
const parameters = { host: null, port_path_or_id: null, database_name: null }
|
|
208
|
+
let conf = queryable.config
|
|
209
209
|
conf = (conf && conf.connectionConfig) || conf
|
|
210
|
-
|
|
210
|
+
let databaseName = queryable.__NR_databaseName || null
|
|
211
211
|
if (conf) {
|
|
212
212
|
parameters.database_name = databaseName = databaseName || conf.database
|
|
213
213
|
|
|
@@ -229,7 +229,7 @@ function getInstanceParameters(shim, queryable, query) {
|
|
|
229
229
|
|
|
230
230
|
function storeDatabaseName(shim, queryable, query) {
|
|
231
231
|
if (queryable.__NR_storeDatabase) {
|
|
232
|
-
|
|
232
|
+
const databaseName = dbutils.extractDatabaseChangeFromUse(query)
|
|
233
233
|
if (databaseName) {
|
|
234
234
|
shim.setInternalProperty(queryable, '__NR_databaseName', databaseName)
|
|
235
235
|
}
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const logger = require('../logger').child({ component: 'oracle' })
|
|
9
|
+
const shimmer = require('../shimmer')
|
|
10
|
+
const parseSql = require('../db/parse-sql')
|
|
11
|
+
const ORACLE = require('../metrics/names').ORACLE
|
|
12
12
|
|
|
13
13
|
module.exports = function initialize(agent, oracle) {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const tracer = agent.tracer
|
|
15
|
+
let wrapped = false
|
|
16
16
|
|
|
17
17
|
logger.trace('wrapping oracle.connect and oracle.connectSync')
|
|
18
18
|
|
|
@@ -31,7 +31,7 @@ module.exports = function initialize(agent, oracle) {
|
|
|
31
31
|
|
|
32
32
|
shimmer.wrapMethod(oracle, 'Oracle', 'connectSync', function wrapSyncConnect(connect) {
|
|
33
33
|
return function wrappedSyncConnect() {
|
|
34
|
-
|
|
34
|
+
const connection = connect.apply(this, arguments)
|
|
35
35
|
ensureConnectionWrapped(connection)
|
|
36
36
|
return connection
|
|
37
37
|
}
|
|
@@ -51,13 +51,13 @@ module.exports = function initialize(agent, oracle) {
|
|
|
51
51
|
return tracer.wrapFunctionNoSegment(connect, 'connect')
|
|
52
52
|
})
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
const proto = Object.getPrototypeOf(connection)
|
|
55
55
|
wrapConnectionExecute(proto, tracer)
|
|
56
56
|
wrapConnectionPrepare(proto, tracer)
|
|
57
57
|
|
|
58
58
|
shimmer.wrapMethod(proto, 'Oracle', 'reader', function wrapMethod(createReader) {
|
|
59
59
|
return function wrappedConnect(sql) {
|
|
60
|
-
|
|
60
|
+
const reader = createReader.apply(this, arguments)
|
|
61
61
|
wrapReader(reader, tracer, sql)
|
|
62
62
|
return reader
|
|
63
63
|
}
|
|
@@ -73,9 +73,9 @@ function wrapConnectionExecute(connection, tracer) {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
function wrappedExecute(segment, args, bind) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
const ps = parseSql(ORACLE.PREFIX, args[0])
|
|
77
|
+
const collection = ps.collection
|
|
78
|
+
const operation = ps.operation
|
|
79
79
|
|
|
80
80
|
segment.name = ORACLE.STATEMENT + collection + '/Connection.execute/' + operation
|
|
81
81
|
logger.trace('capturing oracle query. collection: %s, Operation: %s', collection, operation)
|
|
@@ -87,7 +87,7 @@ function wrapConnectionExecute(connection, tracer) {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
function wrapReader(reader, tracer, sql) {
|
|
90
|
-
|
|
90
|
+
const ps = parseSql(ORACLE.PREFIX, sql)
|
|
91
91
|
shimmer.wrapMethod(reader, 'Oracle.Reader', 'nextRow', wrapNextRow)
|
|
92
92
|
shimmer.wrapMethod(reader, 'Oracle.Reader', 'nextRows', wrapNextRows)
|
|
93
93
|
|
|
@@ -113,8 +113,8 @@ function wrapConnectionPrepare(connection, tracer) {
|
|
|
113
113
|
|
|
114
114
|
function wrapPrepare(prepare) {
|
|
115
115
|
return function wrappedPrepare(sql) {
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
const ps = parseSql(ORACLE.PREFIX, sql)
|
|
117
|
+
const prepared = prepare.apply(this, arguments)
|
|
118
118
|
shimmer.wrapMethod(prepared, 'Oracle', 'execute', wrapExecute)
|
|
119
119
|
return prepared
|
|
120
120
|
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
const semver = require('semver')
|
|
9
9
|
|
|
10
10
|
function getQuery(shim, original, name, args) {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const config = args[0]
|
|
12
|
+
let statement
|
|
13
13
|
if (config && (typeof config === 'string' || config instanceof String)) {
|
|
14
14
|
statement = config
|
|
15
15
|
} else if (config && config.text) {
|
|
@@ -98,11 +98,11 @@ module.exports = function initialize(agent, pgsql, moduleName, shim) {
|
|
|
98
98
|
// client. The original getter replaces itself with the instance of the native
|
|
99
99
|
// client, so only instrument if the getter exists (otherwise assume already
|
|
100
100
|
// instrumented).
|
|
101
|
-
|
|
101
|
+
const origGetter = pgsql.__lookupGetter__('native')
|
|
102
102
|
if (origGetter) {
|
|
103
103
|
delete pgsql.native
|
|
104
104
|
pgsql.__defineGetter__('native', function getNative() {
|
|
105
|
-
|
|
105
|
+
const temp = origGetter()
|
|
106
106
|
if (temp != null) {
|
|
107
107
|
instrumentPGNative(temp)
|
|
108
108
|
}
|