newrelic 7.5.2 → 8.3.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/NEWS.md +4989 -4886
- package/THIRD_PARTY_NOTICES.md +625 -216
- package/api.js +105 -174
- package/bin/test-naming-rules.js +38 -32
- package/bin/tracetractor +0 -1
- package/index.js +12 -18
- package/lib/agent.js +108 -111
- package/lib/aggregators/base-aggregator.js +1 -1
- package/lib/aggregators/event-aggregator.js +6 -6
- package/lib/attributes.js +12 -13
- package/lib/collector/api.js +32 -42
- package/lib/collector/facts.js +67 -65
- package/lib/collector/http-agents.js +30 -27
- package/lib/collector/parse-response.js +1 -2
- package/lib/collector/remote-method.js +43 -36
- package/lib/collector/serverless.js +13 -18
- package/lib/collector/ssl/certificates.js +1056 -1056
- package/lib/config/attribute-filter.js +90 -82
- package/lib/config/default.js +30 -18
- package/lib/config/env.js +17 -12
- package/lib/config/harvest-config-validator.js +1 -1
- package/lib/config/index.js +160 -177
- package/lib/config/merge-server-config.js +7 -5
- package/lib/custom-events/custom-event-aggregator.js +1 -1
- package/lib/db/parse-sql.js +6 -9
- package/lib/db/parsed-statement.js +6 -13
- package/lib/db/query-parsers/sql.js +6 -9
- package/lib/db/query-sample.js +7 -3
- package/lib/db/query-trace-aggregator.js +12 -12
- package/lib/db/utils.js +1 -1
- package/lib/environment.js +173 -138
- package/lib/errors/error-collector.js +18 -31
- package/lib/errors/error-event-aggregator.js +1 -1
- package/lib/errors/error-trace-aggregator.js +2 -3
- package/lib/errors/helper.js +21 -30
- package/lib/errors/index.js +16 -28
- package/lib/feature_flags.js +5 -8
- package/lib/grpc/connection/states.js +6 -6
- package/lib/grpc/connection.js +35 -46
- package/lib/header-attributes.js +49 -53
- package/lib/instrumentation/amqplib.js +8 -17
- package/lib/instrumentation/bluebird.js +61 -20
- package/lib/instrumentation/cassandra-driver.js +2 -2
- package/lib/instrumentation/connect.js +4 -3
- package/lib/instrumentation/core/async_hooks.js +11 -4
- package/lib/instrumentation/core/child_process.js +20 -28
- package/lib/instrumentation/core/crypto.js +1 -7
- package/lib/instrumentation/core/dns.js +3 -7
- package/lib/instrumentation/core/domain.js +2 -8
- package/lib/instrumentation/core/fs.js +22 -37
- package/lib/instrumentation/core/globals.js +3 -7
- package/lib/instrumentation/core/http-outbound.js +15 -40
- package/lib/instrumentation/core/http.js +29 -63
- package/lib/instrumentation/core/inspector.js +6 -10
- package/lib/instrumentation/core/net.js +3 -1
- package/lib/instrumentation/core/timers.js +17 -24
- package/lib/instrumentation/core/zlib.js +2 -10
- package/lib/instrumentation/express.js +4 -2
- package/lib/instrumentation/fastify/spec-builders.js +5 -0
- package/lib/instrumentation/fastify.js +37 -10
- package/lib/instrumentation/hapi/hapi-17.js +9 -10
- package/lib/instrumentation/hapi.js +15 -15
- package/lib/instrumentation/ioredis.js +1 -2
- package/lib/instrumentation/memcached.js +39 -43
- package/lib/instrumentation/mongodb/common.js +218 -0
- package/lib/instrumentation/mongodb/constants.js +87 -0
- package/lib/instrumentation/mongodb/v2-mongo.js +110 -0
- package/lib/instrumentation/mongodb/v3-mongo.js +80 -0
- package/lib/instrumentation/mongodb/v4-mongo.js +90 -0
- package/lib/instrumentation/mongodb.js +20 -312
- package/lib/instrumentation/mysql.js +33 -26
- package/lib/instrumentation/oracle.js +10 -14
- package/lib/instrumentation/pg.js +30 -21
- package/lib/instrumentation/promise.js +20 -17
- package/lib/instrumentation/redis.js +30 -30
- package/lib/instrumentation/when.js +9 -1
- package/lib/instrumentations.js +24 -24
- package/lib/logger.js +1 -1
- package/lib/metrics/index.js +37 -17
- package/lib/metrics/mapper.js +9 -9
- package/lib/metrics/metric-aggregator.js +5 -10
- package/lib/metrics/names.js +8 -7
- package/lib/metrics/normalizer/rule.js +6 -7
- package/lib/metrics/normalizer/tx_segment.js +17 -13
- package/lib/metrics/normalizer.js +30 -33
- package/lib/metrics/recorders/custom.js +3 -1
- package/lib/metrics/recorders/distributed-trace.js +3 -18
- package/lib/metrics/recorders/generic.js +3 -2
- package/lib/metrics/recorders/http.js +4 -6
- package/lib/metrics/recorders/http_external.js +1 -3
- package/lib/metrics/recorders/message-transaction.js +2 -12
- package/lib/metrics/recorders/other.js +2 -12
- package/lib/parse-proc-cpuinfo.js +11 -16
- package/lib/parse-proc-meminfo.js +5 -3
- package/lib/prioritized-attributes.js +12 -17
- package/lib/priority-queue.js +1 -1
- package/lib/proxy/grpc.js +1 -1
- package/lib/reservoir.js +9 -3
- package/lib/sampler.js +12 -13
- package/lib/serverless/api-gateway.js +3 -3
- package/lib/serverless/aws-lambda.js +28 -37
- package/lib/shim/conglomerate-shim.js +4 -4
- package/lib/shim/datastore-shim.js +29 -38
- package/lib/shim/index.js +8 -9
- package/lib/shim/message-shim.js +111 -113
- package/lib/shim/promise-shim.js +18 -13
- package/lib/shim/shim.js +72 -66
- package/lib/shim/specs/index.js +18 -19
- package/lib/shim/transaction-shim.js +26 -36
- package/lib/shim/webframework-shim.js +25 -35
- package/lib/shimmer.js +184 -166
- package/lib/spans/create-span-event-aggregator.js +24 -44
- package/lib/spans/span-context.js +4 -10
- package/lib/spans/span-event-aggregator.js +68 -13
- package/lib/spans/span-event.js +5 -7
- package/lib/spans/span-streamer.js +10 -18
- package/lib/spans/streaming-span-event-aggregator.js +1 -1
- package/lib/spans/streaming-span-event.js +4 -4
- package/lib/stats/apdex.js +5 -11
- package/lib/stats/index.js +12 -17
- package/lib/system-info.js +7 -3
- package/lib/timer.js +30 -16
- package/lib/transaction/dt-payload.js +1 -1
- package/lib/transaction/handle.js +19 -19
- package/lib/transaction/index.js +94 -112
- package/lib/transaction/name-state.js +5 -6
- package/lib/transaction/trace/aggregator.js +78 -73
- package/lib/transaction/trace/exclusive-time-calculator.js +5 -9
- package/lib/transaction/trace/index.js +26 -24
- package/lib/transaction/trace/segment.js +39 -56
- package/lib/transaction/tracecontext.js +37 -45
- package/lib/transaction/tracer/index.js +79 -44
- package/lib/transaction/transaction-event-aggregator.js +29 -31
- package/lib/uninstrumented.js +4 -5
- package/lib/util/attribute-types.js +1 -5
- package/lib/util/byte-limit.js +0 -1
- package/lib/util/cat.js +5 -13
- package/lib/util/codec.js +8 -4
- package/lib/util/deep-equal.js +48 -18
- package/lib/util/flatten.js +5 -2
- package/lib/util/hashes.js +2 -2
- package/lib/util/label-parser.js +7 -13
- package/lib/util/logger.js +31 -13
- package/lib/util/process-version.js +1 -1
- package/lib/util/properties.js +1 -1
- package/lib/util/sql/obfuscate.js +7 -17
- package/lib/util/stream-sink.js +2 -3
- package/lib/util/urltils.js +9 -13
- package/lib/utilization/aws-info.js +2 -3
- package/lib/utilization/azure-info.js +32 -30
- package/lib/utilization/common.js +5 -4
- package/lib/utilization/docker-info.js +4 -6
- package/lib/utilization/gcp-info.js +36 -35
- package/lib/utilization/index.js +1 -1
- package/lib/utilization/kubernetes-info.js +2 -2
- package/lib/utilization/pcf-info.js +4 -4
- package/package.json +32 -18
- package/stub_api.js +8 -6
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
8
|
const semver = require('semver')
|
|
9
|
+
const instrument = require('./mongodb/v2-mongo')
|
|
10
|
+
const instrumentV3 = require('./mongodb/v3-mongo')
|
|
11
|
+
const instrumentV4 = require('./mongodb/v4-mongo')
|
|
9
12
|
|
|
10
13
|
// XXX: When this instrumentation is modularized, update this thread
|
|
11
14
|
// with a cautionary note:
|
|
@@ -15,325 +18,30 @@ const semver = require('semver')
|
|
|
15
18
|
// snippet. The snippet will break once this file is moved from this
|
|
16
19
|
// location.
|
|
17
20
|
|
|
18
|
-
// legacy endpoint enumerations
|
|
19
|
-
const DB_OPS = [
|
|
20
|
-
'addUser',
|
|
21
|
-
'authenticate',
|
|
22
|
-
'collection',
|
|
23
|
-
'collectionNames',
|
|
24
|
-
'collections',
|
|
25
|
-
'command',
|
|
26
|
-
'createCollection',
|
|
27
|
-
'createIndex',
|
|
28
|
-
'cursorInfo',
|
|
29
|
-
'dereference',
|
|
30
|
-
'dropCollection',
|
|
31
|
-
'dropDatabase',
|
|
32
|
-
'dropIndex',
|
|
33
|
-
'ensureIndex',
|
|
34
|
-
'eval',
|
|
35
|
-
'executeDbAdminCommand',
|
|
36
|
-
'indexInformation',
|
|
37
|
-
'logout',
|
|
38
|
-
'open',
|
|
39
|
-
'reIndex',
|
|
40
|
-
'removeUser',
|
|
41
|
-
'renameCollection',
|
|
42
|
-
'stats',
|
|
43
|
-
'_executeInsertCommand',
|
|
44
|
-
'_executeQueryCommand'
|
|
45
|
-
]
|
|
46
|
-
|
|
47
|
-
const COLLECTION_OPS = [
|
|
48
|
-
'aggregate',
|
|
49
|
-
'bulkWrite',
|
|
50
|
-
'count',
|
|
51
|
-
'createIndex',
|
|
52
|
-
'deleteMany',
|
|
53
|
-
'deleteOne',
|
|
54
|
-
'distinct',
|
|
55
|
-
'drop',
|
|
56
|
-
'dropAllIndexes',
|
|
57
|
-
'dropIndex',
|
|
58
|
-
'ensureIndex',
|
|
59
|
-
'findAndModify',
|
|
60
|
-
'findAndRemove',
|
|
61
|
-
'findOne',
|
|
62
|
-
'findOneAndDelete',
|
|
63
|
-
'findOneAndReplace',
|
|
64
|
-
'findOneAndUpdate',
|
|
65
|
-
'geoHaystackSearch',
|
|
66
|
-
'geoNear',
|
|
67
|
-
'group',
|
|
68
|
-
'indexes',
|
|
69
|
-
'indexExists',
|
|
70
|
-
'indexInformation',
|
|
71
|
-
'insert',
|
|
72
|
-
'insertMany',
|
|
73
|
-
'insertOne',
|
|
74
|
-
'isCapped',
|
|
75
|
-
'mapReduce',
|
|
76
|
-
'options',
|
|
77
|
-
'parallelCollectionScan',
|
|
78
|
-
'reIndex',
|
|
79
|
-
'remove',
|
|
80
|
-
'rename',
|
|
81
|
-
'replaceOne',
|
|
82
|
-
'save',
|
|
83
|
-
'stats',
|
|
84
|
-
'update',
|
|
85
|
-
'updateMany',
|
|
86
|
-
'updateOne'
|
|
87
|
-
]
|
|
88
|
-
|
|
89
|
-
const GRID_OPS = [
|
|
90
|
-
'put',
|
|
91
|
-
'get',
|
|
92
|
-
'delete'
|
|
93
|
-
]
|
|
94
|
-
|
|
95
|
-
const CURSOR_OPS = [
|
|
96
|
-
'nextObject',
|
|
97
|
-
'next',
|
|
98
|
-
'toArray',
|
|
99
|
-
'count',
|
|
100
|
-
'explain'
|
|
101
|
-
]
|
|
102
|
-
|
|
103
21
|
module.exports = initialize
|
|
104
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Registers the query parser, and relevant instrumentation
|
|
25
|
+
* based on version of mongodb
|
|
26
|
+
*
|
|
27
|
+
* @param {Agent} agent
|
|
28
|
+
* @param {Object} mongodb resolved package
|
|
29
|
+
* @param {string} moduleName name of module
|
|
30
|
+
* @param {Shim} shim
|
|
31
|
+
*/
|
|
105
32
|
function initialize(agent, mongodb, moduleName, shim) {
|
|
106
|
-
if (!mongodb)
|
|
33
|
+
if (!mongodb) {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
107
36
|
|
|
108
37
|
shim.setDatastore(shim.MONGODB)
|
|
109
|
-
shim.setParser(function mongoQueryParser(operation) {
|
|
110
|
-
let collection = this.collectionName || 'unknown'
|
|
111
|
-
if (this.collection && this.collection.collectionName) {
|
|
112
|
-
collection = this.collection.collectionName
|
|
113
|
-
} else if (this.s && this.s.name) {
|
|
114
|
-
collection = this.s.name
|
|
115
|
-
} else if (this.ns) {
|
|
116
|
-
collection = this.ns.split(/\./)[1] || collection
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return {operation, collection}
|
|
120
|
-
})
|
|
121
38
|
|
|
122
39
|
const mongoVersion = shim.require('./package.json').version
|
|
123
|
-
if (semver.satisfies(mongoVersion, '>=
|
|
124
|
-
|
|
125
|
-
} else if (
|
|
126
|
-
|
|
40
|
+
if (semver.satisfies(mongoVersion, '>=4.0.0')) {
|
|
41
|
+
instrumentV4(shim, mongodb)
|
|
42
|
+
} else if (semver.satisfies(mongoVersion, '>=3.0.6')) {
|
|
43
|
+
instrumentV3(shim, mongodb)
|
|
127
44
|
} else {
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function instrument306(shim, mongodb) {
|
|
133
|
-
const instrumenter = mongodb.instrument(Object.create(null), () => {})
|
|
134
|
-
captureAttributesOnStarted(shim, instrumenter)
|
|
135
|
-
instrumentLegacy(shim, mongodb)
|
|
136
|
-
|
|
137
|
-
if (shim.isFunction(instrumenter.uninstrument)) {
|
|
138
|
-
shim.agent.once('unload', function uninstrumentMongo() {
|
|
139
|
-
instrumenter.uninstrument()
|
|
140
|
-
})
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function instrumentInstrument(shim, mongodb) {
|
|
145
|
-
const recordDesc = {
|
|
146
|
-
'Gridstore': {isQuery: false, makeDesc: function makeGridDesc(opName) {
|
|
147
|
-
return {name:'GridFS-' + opName, callback: shim.LAST}
|
|
148
|
-
}},
|
|
149
|
-
'OrderedBulkOperation': {isQuery: true, makeDesc: makeQueryDescFunc},
|
|
150
|
-
'UnorderedBulkOperation': {isQuery: true, makeDesc: makeQueryDescFunc},
|
|
151
|
-
'CommandCursor': {isQuery: true, makeDesc: makeQueryDescFunc},
|
|
152
|
-
'AggregationCursor': {isQuery: true, makeDesc: makeQueryDescFunc},
|
|
153
|
-
'Cursor': {isQuery: true, makeDesc: makeQueryDescFunc},
|
|
154
|
-
'Collection': {isQuery: true, makeDesc: makeQueryDescFunc},
|
|
155
|
-
'Db': {isQuery: false, makeDesc: function makeDbDesc() {
|
|
156
|
-
return {callback: shim.LAST}
|
|
157
|
-
}}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// instrument using the apm api
|
|
161
|
-
const instrumenter = mongodb.instrument(Object.create(null), instrumentModules)
|
|
162
|
-
captureAttributesOnStarted(shim, instrumenter)
|
|
163
|
-
|
|
164
|
-
function instrumentModules(err, instrumentations) {
|
|
165
|
-
if (err) {
|
|
166
|
-
shim.logger
|
|
167
|
-
.trace('Unable to instrument mongo using the apm api due to error: %s', err)
|
|
168
|
-
// fallback to legacy instrumentation?
|
|
169
|
-
return
|
|
170
|
-
}
|
|
171
|
-
instrumentations.forEach(instrumentModule)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
function instrumentModule(module) {
|
|
175
|
-
var object = module.obj
|
|
176
|
-
var instrumentations = module.instrumentations
|
|
177
|
-
for (var i = 0; i < instrumentations.length; i++) {
|
|
178
|
-
applyInstrumentation(module.name, object, instrumentations[i])
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function applyInstrumentation(objectName, object, instrumentation) {
|
|
183
|
-
var methods = instrumentation.methods
|
|
184
|
-
var methodOptions = instrumentation.options
|
|
185
|
-
if (methodOptions.callback) {
|
|
186
|
-
for (var j = 0; j < methods.length; j++) {
|
|
187
|
-
var method = methods[j]
|
|
188
|
-
|
|
189
|
-
var isQuery = recordDesc[objectName].isQuery
|
|
190
|
-
var makeDescFunc = recordDesc[objectName].makeDesc
|
|
191
|
-
var proto = object.prototype
|
|
192
|
-
if (isQuery) {
|
|
193
|
-
shim.recordQuery(proto, method, makeDescFunc(shim, method))
|
|
194
|
-
} else if (isQuery === false) { // could be unset
|
|
195
|
-
shim.recordOperation(proto, method, makeDescFunc(shim, method))
|
|
196
|
-
} else {
|
|
197
|
-
shim.logger.trace('No wrapping method found for %s', objectName)
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// the cursor object implements Readable stream and internally calls nextObject on
|
|
203
|
-
// each read, in which case we do not want to record each nextObject() call
|
|
204
|
-
if (/Cursor$/.test(objectName)) {
|
|
205
|
-
shim.recordOperation(object.prototype, 'pipe')
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
function captureAttributesOnStarted(shim, instrumenter) {
|
|
211
|
-
instrumenter.on('started', function onMongoEventStarted(evnt) {
|
|
212
|
-
// This assumes that this `started` event is fired _after_ our wrapper
|
|
213
|
-
// starts and creates the segment. We perform a check of the segment name
|
|
214
|
-
// out of an excess of caution.
|
|
215
|
-
const connId = evnt.connectionId
|
|
216
|
-
if (connId) {
|
|
217
|
-
// Mongo sticks the path to the domain socket in the "host" slot, but we
|
|
218
|
-
// want it in the "port", so if we have a domain socket we need to change
|
|
219
|
-
// the order of our parameters.
|
|
220
|
-
if (typeof connId === 'string') {
|
|
221
|
-
const parts = connId.split(':')
|
|
222
|
-
if (parts.length && parts[0][0] === '/') {
|
|
223
|
-
shim.captureInstanceAttributes('localhost', parts[0], evnt.databaseName)
|
|
224
|
-
} else {
|
|
225
|
-
shim.captureInstanceAttributes(parts[0], parts[1], evnt.databaseName)
|
|
226
|
-
}
|
|
227
|
-
} else if (connId.domainSocket) {
|
|
228
|
-
shim.captureInstanceAttributes('localhost', connId.host, evnt.databaseName)
|
|
229
|
-
} else {
|
|
230
|
-
shim.captureInstanceAttributes(connId.host, connId.port, evnt.databaseName)
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
})
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
function instrumentLegacy(shim, mongodb) {
|
|
237
|
-
instrumentCursor(mongodb.Cursor)
|
|
238
|
-
instrumentCursor(shim.require('./lib/aggregation_cursor'))
|
|
239
|
-
instrumentCursor(shim.require('./lib/command_cursor'))
|
|
240
|
-
|
|
241
|
-
if (mongodb.Collection && mongodb.Collection.prototype) {
|
|
242
|
-
const proto = mongodb.Collection.prototype
|
|
243
|
-
for (let i = 0; i < COLLECTION_OPS.length; i++) {
|
|
244
|
-
shim.recordQuery(
|
|
245
|
-
proto,
|
|
246
|
-
COLLECTION_OPS[i],
|
|
247
|
-
makeQueryDescFunc(shim, COLLECTION_OPS[i])
|
|
248
|
-
)
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if (mongodb.Grid && mongodb.Grid.prototype) {
|
|
253
|
-
const proto = mongodb.Grid.prototype
|
|
254
|
-
for (let i = 0; i < CURSOR_OPS.length; i++) {
|
|
255
|
-
shim.recordOperation(proto, GRID_OPS[i],
|
|
256
|
-
{name:'GridFS-' + GRID_OPS[i], callback: shim.LAST})
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (mongodb.Db && mongodb.Db.prototype) {
|
|
261
|
-
const proto = mongodb.Db.prototype
|
|
262
|
-
shim.recordOperation(proto, DB_OPS, {callback: shim.LAST})
|
|
263
|
-
shim.recordOperation(mongodb.Db, 'connect', {callback: shim.LAST})
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
function instrumentCursor(Cursor) {
|
|
267
|
-
if (Cursor && Cursor.prototype) {
|
|
268
|
-
const proto = Cursor.prototype
|
|
269
|
-
for (let i = 0; i < CURSOR_OPS.length; i++) {
|
|
270
|
-
shim.recordQuery(proto, CURSOR_OPS[i], makeQueryDescFunc(shim, CURSOR_OPS[i]))
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
shim.recordQuery(proto, 'each', makeQueryDescFunc(shim, 'each'))
|
|
274
|
-
shim.recordOperation(proto, 'pipe')
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
function makeQueryDescFunc(shim, methodName) {
|
|
280
|
-
if (methodName === 'each') {
|
|
281
|
-
return function eachDescFunc() {
|
|
282
|
-
const parameters = getInstanceAttributeParameters(shim, this)
|
|
283
|
-
return {query: methodName, parameters, rowCallback: shim.LAST}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
return function queryDescFunc() {
|
|
288
|
-
// segment name does not actually use query string
|
|
289
|
-
// method name is set as query so the query parser has access to the op name
|
|
290
|
-
const parameters = getInstanceAttributeParameters(shim, this)
|
|
291
|
-
return {query: methodName, parameters, promise: true, callback: shim.LAST}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
function getInstanceAttributeParameters(shim, obj) {
|
|
296
|
-
if (obj.db && obj.db.serverConfig) {
|
|
297
|
-
shim.logger.trace('Adding datastore instance attributes from obj.db.serverConfig')
|
|
298
|
-
const serverConfig = obj.db.serverConfig
|
|
299
|
-
const db = serverConfig.db || serverConfig.dbInstance
|
|
300
|
-
return doCapture(serverConfig, db && db.databaseName)
|
|
301
|
-
} else if (obj.s && obj.s.db && obj.s.topology) {
|
|
302
|
-
shim.logger.trace(
|
|
303
|
-
'Adding datastore instance attributes from obj.s.db + obj.s.topology'
|
|
304
|
-
)
|
|
305
|
-
const databaseName = obj.s.db.databaseName || null
|
|
306
|
-
const topology = obj.s.topology
|
|
307
|
-
if (topology.s && topology.s.options) {
|
|
308
|
-
return doCapture(topology.s.options, databaseName)
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
shim.logger.trace('Could not find datastore instance attributes.')
|
|
313
|
-
return {
|
|
314
|
-
host: null,
|
|
315
|
-
port_path_or_id: null,
|
|
316
|
-
database_name: null
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
function doCapture(conf, database) {
|
|
320
|
-
let host = conf.host
|
|
321
|
-
let port = conf.port
|
|
322
|
-
|
|
323
|
-
// If using a domain socket, mongo stores the path as the host name, but we
|
|
324
|
-
// pass it through the port value.
|
|
325
|
-
if (
|
|
326
|
-
(conf.socketOptions && conf.socketOptions.domainSocket) ||
|
|
327
|
-
/\.sock$/.test(host)
|
|
328
|
-
) {
|
|
329
|
-
port = host
|
|
330
|
-
host = 'localhost'
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
return {
|
|
334
|
-
host: host,
|
|
335
|
-
port_path_or_id: port,
|
|
336
|
-
database_name: database
|
|
337
|
-
}
|
|
45
|
+
instrument(shim, mongodb)
|
|
338
46
|
}
|
|
339
47
|
}
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
var dbutils = require('../db/utils')
|
|
9
9
|
var properties = require('../util/properties')
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
module.exports = function initialize(agent, mysql, moduleName, shim) {
|
|
13
12
|
shim.setDatastore(shim.MYSQL)
|
|
14
13
|
shim.__wrappedPoolConnection = false
|
|
@@ -50,16 +49,15 @@ module.exports = function initialize(agent, mysql, moduleName, shim) {
|
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
function wrapGetConnection(shim, connectable) {
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}, 'Not wrapping getConnection')
|
|
52
|
+
if (!connectable || !connectable.getConnection || shim.isWrapped(connectable.getConnection)) {
|
|
53
|
+
shim.logger.trace(
|
|
54
|
+
{
|
|
55
|
+
connectable: !!connectable,
|
|
56
|
+
getConnection: !!(connectable && connectable.getConnection),
|
|
57
|
+
isWrapped: !!(connectable && shim.isWrapped(connectable.getConnection))
|
|
58
|
+
},
|
|
59
|
+
'Not wrapping getConnection'
|
|
60
|
+
)
|
|
63
61
|
return false
|
|
64
62
|
}
|
|
65
63
|
|
|
@@ -70,9 +68,12 @@ function wrapGetConnection(shim, connectable) {
|
|
|
70
68
|
var cbIdx = args.length - 1
|
|
71
69
|
|
|
72
70
|
if (shim.isFunction(args[cbIdx]) && !shim.isWrapped(args[cbIdx])) {
|
|
73
|
-
shim.logger.trace(
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
shim.logger.trace(
|
|
72
|
+
{
|
|
73
|
+
hasSegment: !!shim.getSegment()
|
|
74
|
+
},
|
|
75
|
+
'Wrapping callback with segment'
|
|
76
|
+
)
|
|
76
77
|
var cb = args[cbIdx]
|
|
77
78
|
if (!shim.__wrappedPoolConnection) {
|
|
78
79
|
cb = shim.wrap(cb, wrapGetConnectionCallback)
|
|
@@ -97,7 +98,7 @@ function wrapGetConnectionCallback(shim, cb) {
|
|
|
97
98
|
}
|
|
98
99
|
} catch (_err) {
|
|
99
100
|
shim.logger.debug(
|
|
100
|
-
{error: _err},
|
|
101
|
+
{ error: _err },
|
|
101
102
|
'Attempt to wrap PoolConnection#query resulted in thrown error'
|
|
102
103
|
)
|
|
103
104
|
}
|
|
@@ -107,11 +108,14 @@ function wrapGetConnectionCallback(shim, cb) {
|
|
|
107
108
|
|
|
108
109
|
function wrapQueriable(shim, queriable, isPoolQuery) {
|
|
109
110
|
if (!queriable || !queriable.query || shim.isWrapped(queriable.query)) {
|
|
110
|
-
shim.logger.debug(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
shim.logger.debug(
|
|
112
|
+
{
|
|
113
|
+
queriable: !!queriable,
|
|
114
|
+
query: !!(queriable && queriable.query),
|
|
115
|
+
isWrapped: !!(queriable && shim.isWrapped(queriable.query))
|
|
116
|
+
},
|
|
117
|
+
'Not wrappying queriable'
|
|
118
|
+
)
|
|
115
119
|
return false
|
|
116
120
|
}
|
|
117
121
|
|
|
@@ -169,11 +173,14 @@ function describeQuery(shim, queryFn, fnName, args) {
|
|
|
169
173
|
// Pull out instance attributes.
|
|
170
174
|
var parameters = getInstanceParameters(shim, this, extractedArgs.query)
|
|
171
175
|
|
|
172
|
-
shim.logger.trace(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
176
|
+
shim.logger.trace(
|
|
177
|
+
{
|
|
178
|
+
query: !!extractedArgs.query,
|
|
179
|
+
callback: !!extractedArgs.callback,
|
|
180
|
+
parameters: !!parameters
|
|
181
|
+
},
|
|
182
|
+
'Query segment descriptor'
|
|
183
|
+
)
|
|
177
184
|
|
|
178
185
|
return {
|
|
179
186
|
stream: true,
|
|
@@ -197,7 +204,7 @@ function describePoolQuery(shim, queryFn, fnName, args) {
|
|
|
197
204
|
}
|
|
198
205
|
|
|
199
206
|
function getInstanceParameters(shim, queryable, query) {
|
|
200
|
-
var parameters = {host: null, port_path_or_id: null, database_name: null}
|
|
207
|
+
var parameters = { host: null, port_path_or_id: null, database_name: null }
|
|
201
208
|
var conf = queryable.config
|
|
202
209
|
conf = (conf && conf.connectionConfig) || conf
|
|
203
210
|
var databaseName = queryable.__NR_databaseName || null
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
-
var logger = require('../logger').child({component: 'oracle'})
|
|
8
|
+
var logger = require('../logger').child({ component: 'oracle' })
|
|
9
9
|
var shimmer = require('../shimmer')
|
|
10
10
|
var parseSql = require('../db/parse-sql')
|
|
11
11
|
var ORACLE = require('../metrics/names').ORACLE
|
|
@@ -16,16 +16,14 @@ module.exports = function initialize(agent, oracle) {
|
|
|
16
16
|
|
|
17
17
|
logger.trace('wrapping oracle.connect and oracle.connectSync')
|
|
18
18
|
|
|
19
|
-
shimmer.wrapMethod(oracle, 'Oracle', 'connect', function
|
|
19
|
+
shimmer.wrapMethod(oracle, 'Oracle', 'connect', function wrapMethod(connect) {
|
|
20
20
|
return function wrappedConnect(connectData, cb) {
|
|
21
|
-
return connect.call(
|
|
22
|
-
this,
|
|
23
|
-
connectData,
|
|
24
|
-
tracer.bindFunction(wrapConnection)
|
|
25
|
-
)
|
|
21
|
+
return connect.call(this, connectData, tracer.bindFunction(wrapConnection))
|
|
26
22
|
|
|
27
23
|
function wrapConnection(err, connection) {
|
|
28
|
-
if (!err)
|
|
24
|
+
if (!err) {
|
|
25
|
+
ensureConnectionWrapped(connection)
|
|
26
|
+
}
|
|
29
27
|
return cb(err, connection)
|
|
30
28
|
}
|
|
31
29
|
}
|
|
@@ -41,7 +39,9 @@ module.exports = function initialize(agent, oracle) {
|
|
|
41
39
|
|
|
42
40
|
function ensureConnectionWrapped(connection) {
|
|
43
41
|
// return early in case called from an async connect after wrapping
|
|
44
|
-
if (wrapped)
|
|
42
|
+
if (wrapped) {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
45
|
logger.trace('wrapping oracle connection prototype')
|
|
46
46
|
wrapped = true
|
|
47
47
|
|
|
@@ -78,11 +78,7 @@ function wrapConnectionExecute(connection, tracer) {
|
|
|
78
78
|
var operation = ps.operation
|
|
79
79
|
|
|
80
80
|
segment.name = ORACLE.STATEMENT + collection + '/Connection.execute/' + operation
|
|
81
|
-
logger.trace(
|
|
82
|
-
'capturing oracle query. collection: %s, Operation: %s',
|
|
83
|
-
collection,
|
|
84
|
-
operation
|
|
85
|
-
)
|
|
81
|
+
logger.trace('capturing oracle query. collection: %s, Operation: %s', collection, operation)
|
|
86
82
|
|
|
87
83
|
segment.transaction.addRecorder(ps.recordMetrics.bind(ps, segment))
|
|
88
84
|
args[2] = bind(args[2])
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict'
|
|
7
7
|
|
|
8
|
+
const semver = require('semver')
|
|
9
|
+
|
|
8
10
|
function getQuery(shim, original, name, args) {
|
|
9
11
|
var config = args[0]
|
|
10
12
|
var statement
|
|
@@ -20,6 +22,8 @@ function getQuery(shim, original, name, args) {
|
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
module.exports = function initialize(agent, pgsql, moduleName, shim) {
|
|
25
|
+
const pgVersion = shim.require('./package.json').version
|
|
26
|
+
|
|
23
27
|
shim.setDatastore(shim.POSTGRES)
|
|
24
28
|
// allows for native wrapping to not happen if not necessary
|
|
25
29
|
// when env var is true
|
|
@@ -28,6 +32,29 @@ module.exports = function initialize(agent, pgsql, moduleName, shim) {
|
|
|
28
32
|
return instrumentPGNative(pgsql)
|
|
29
33
|
}
|
|
30
34
|
|
|
35
|
+
function wrapJSClientQuery(shim, _, __, queryArgs) {
|
|
36
|
+
// As of pg v7.0.0, Client.query returns a Promise from an async call.
|
|
37
|
+
// pg supports event based Client.query when a Query object is passed in,
|
|
38
|
+
// and works similarly in pg version <7.0.0
|
|
39
|
+
if (semver.satisfies(pgVersion, '>=7.0.0') && typeof queryArgs[0] === 'string') {
|
|
40
|
+
return {
|
|
41
|
+
callback: shim.LAST,
|
|
42
|
+
query: getQuery,
|
|
43
|
+
promise: true,
|
|
44
|
+
parameters: getInstanceParameters(shim, this),
|
|
45
|
+
internal: false
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
callback: shim.LAST,
|
|
51
|
+
query: getQuery,
|
|
52
|
+
stream: 'row',
|
|
53
|
+
parameters: getInstanceParameters(shim, this),
|
|
54
|
+
internal: false
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
31
58
|
// wrapping for native
|
|
32
59
|
function instrumentPGNative(pg) {
|
|
33
60
|
shim.wrapReturn(pg, 'Client', clientFactoryWrapper)
|
|
@@ -41,7 +68,7 @@ module.exports = function initialize(agent, pgsql, moduleName, shim) {
|
|
|
41
68
|
// constructor and pg.pools so we can check against pg.pools to only
|
|
42
69
|
// instrument pg.Pool on v6 and later.
|
|
43
70
|
if (!pg.pools) {
|
|
44
|
-
shim.wrapClass(pg, 'Pool', {post: poolPostConstructor, es6: true})
|
|
71
|
+
shim.wrapClass(pg, 'Pool', { post: poolPostConstructor, es6: true })
|
|
45
72
|
}
|
|
46
73
|
}
|
|
47
74
|
|
|
@@ -56,13 +83,7 @@ module.exports = function initialize(agent, pgsql, moduleName, shim) {
|
|
|
56
83
|
}
|
|
57
84
|
|
|
58
85
|
function clientPostConstructor(shim) {
|
|
59
|
-
shim.recordQuery(this, 'query',
|
|
60
|
-
callback: shim.LAST,
|
|
61
|
-
query: getQuery,
|
|
62
|
-
stream: 'row',
|
|
63
|
-
parameters: getInstanceParameters(shim, this),
|
|
64
|
-
internal: false
|
|
65
|
-
})
|
|
86
|
+
shim.recordQuery(this, 'query', wrapJSClientQuery)
|
|
66
87
|
|
|
67
88
|
shim.record(this, 'connect', function pgConnectNamer() {
|
|
68
89
|
return {
|
|
@@ -90,19 +111,7 @@ module.exports = function initialize(agent, pgsql, moduleName, shim) {
|
|
|
90
111
|
}
|
|
91
112
|
|
|
92
113
|
// wrapping for JS
|
|
93
|
-
shim.recordQuery(
|
|
94
|
-
pgsql && pgsql.Client && pgsql.Client.prototype,
|
|
95
|
-
'query',
|
|
96
|
-
function wrapJSClientQuery(shim) {
|
|
97
|
-
return {
|
|
98
|
-
callback: shim.LAST,
|
|
99
|
-
query: getQuery,
|
|
100
|
-
stream: 'row',
|
|
101
|
-
parameters: getInstanceParameters(shim, this),
|
|
102
|
-
internal: false
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
)
|
|
114
|
+
shim.recordQuery(pgsql && pgsql.Client && pgsql.Client.prototype, 'query', wrapJSClientQuery)
|
|
106
115
|
}
|
|
107
116
|
|
|
108
117
|
function getInstanceParameters(shim, client) {
|