Skip to content

Commit 808323f

Browse files
authoredApr 4, 2024··
refactor(mongodb): Removed instrumentation that handles connecting via unix domain socket. (#2129)
1 parent c32cb27 commit 808323f

File tree

7 files changed

+23
-213
lines changed

7 files changed

+23
-213
lines changed
 

‎lib/instrumentation/mongodb/common.js

+5-45
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const {
1111
} = require('../../shim/specs')
1212
const { CURSOR_OPS, COLLECTION_OPS, DB_OPS } = require('./constants')
1313
const common = module.exports
14-
common.NR_ATTRS = Symbol('NR_ATTRS')
1514

1615
/**
1716
* Instruments all methods from constants.CURSOR_OPS on a given
@@ -88,8 +87,7 @@ common.instrumentDb = function instrumentDb(shim, Db) {
8887
* Sets up the desc for all instrumented query methods
8988
*
9089
* @param {Shim} shim instance of shim
91-
* @param {Function} fn function getting instrumented
92-
* @param _fn
90+
* @param {Function} _fn function getting instrumented
9391
* @param {string} methodName name of function
9492
* @returns {QuerySpec} query spec
9593
*/
@@ -156,13 +154,10 @@ common.captureAttributesOnStarted = function captureAttributesOnStarted(
156154
if (connId) {
157155
// used in v3 when connection is a cluster pool
158156
if (typeof connId === 'number') {
159-
setHostPort(shim, evnt.address, evnt.databaseName, this.$MongoClient)
157+
setHostPort(shim, evnt.address, evnt.databaseName)
160158
// used in v3 when connection is to 1 host
161159
} else if (typeof connId === 'string') {
162160
setHostPort(shim, connId, evnt.databaseName)
163-
// v2 contains `domainSocket`, get socket connection from `host`
164-
} else if (connId.domainSocket) {
165-
shim.captureInstanceAttributes('localhost', connId.host, evnt.databaseName)
166161
// v2 remote connection get `host` `port` from respective properties
167162
} else {
168163
shim.captureInstanceAttributes(connId.host, connId.port, evnt.databaseName)
@@ -173,37 +168,14 @@ common.captureAttributesOnStarted = function captureAttributesOnStarted(
173168

174169
/**
175170
* Extracts the host and port from a connection string
176-
* This also handles if connection string is a domain socket
177-
* Mongo sticks the path to the domain socket in the "host" slot, but we
178-
* want it in the "port", so if we have a domain socket we need to change
179-
* the order of our parameters.
180171
*
181172
* @param {Shim} shim instance of shim
182173
* @param {string} connStr mongo connection string
183174
* @param {string} db database name
184-
* @param {object} client mongo client instance
185175
*/
186-
function setHostPort(shim, connStr, db, client) {
176+
function setHostPort(shim, connStr, db) {
187177
const parts = common.parseAddress(connStr)
188-
// in v3 when running with a cluster of socket connections
189-
// the address is `undefined:undefined`. we will instead attempt
190-
// to get connection details from the client symbol NR_ATTRS
191-
// added in `lib/instrumentation/mongodb/v3-mongo` when a client connects
192-
// with a URL string
193-
if (parts.includes('undefined')) {
194-
try {
195-
const attrs = client[common.NR_ATTRS]
196-
const socket = decodeURIComponent(attrs.split(',')[0].split('mongodb://')[1])
197-
shim.captureInstanceAttributes('localhost', socket, db)
198-
} catch (err) {
199-
shim.logger.debug(err, 'Could not extract host/port from mongo command')
200-
}
201-
// connected using domain socket but the "host"(e.g: /path/to/mongo-socket-port.sock)
202-
} else if (parts.length && parts[0][0] === '/') {
203-
shim.captureInstanceAttributes('localhost', parts[0], db)
204-
} else {
205-
shim.captureInstanceAttributes(parts[0], parts[1], db)
206-
}
178+
shim.captureInstanceAttributes(parts[0], parts[1], db)
207179
}
208180

209181
/**
@@ -247,13 +219,8 @@ function getInstanceAttributeParameters(shim, mongo) {
247219
* @returns {object} db params
248220
*/
249221
function getParametersFromHosts(hosts, database) {
250-
let [{ host, port }] = hosts
251-
const [{ socketPath }] = hosts
222+
const [{ host, port }] = hosts
252223

253-
if (socketPath) {
254-
port = socketPath
255-
host = 'localhost'
256-
}
257224
return new DatastoreParameters({
258225
host,
259226
port_path_or_id: port,
@@ -284,13 +251,6 @@ function getParametersFromTopology(conf, database) {
284251
;[{ host, port }] = conf.s.options.hosts
285252
}
286253

287-
// host is a domain socket. set host as localhost and use the domain
288-
// socket host as the port
289-
if (host && host.endsWith('.sock')) {
290-
port = host
291-
host = 'localhost'
292-
}
293-
294254
return new DatastoreParameters({
295255
host,
296256
port_path_or_id: port,

‎lib/instrumentation/mongodb/v3-mongo.js

+6-9
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ const {
1111
instrumentBulkOperation,
1212
instrumentCollection,
1313
instrumentCursor,
14-
instrumentDb,
15-
NR_ATTRS
14+
instrumentDb
1615
} = require('./common')
1716

1817
/**
1918
* parser used to grab the collection and operation
2019
* on every mongo operation
2120
*
22-
* @param {object} operation
21+
* @param {object} operation mongodb operation
22+
* @returns {object} { operation, collection } parsed operation and collection
2323
*/
2424
function queryParser(operation) {
2525
let collection = this.collectionName || 'unknown'
@@ -40,14 +40,11 @@ function queryParser(operation) {
4040
* to a Symbol on the MongoClient to be used later to extract the host/port in cases where the topology
4141
* is a cluster of domain sockets
4242
*
43-
* @param {Shim} shim
43+
* @param {Shim} shim instance of shim
4444
* @param {object} mongodb resolved package
4545
*/
4646
function instrumentClient(shim, mongodb) {
47-
shim.recordOperation(mongodb.MongoClient, 'connect', function wrappedConnect(shim, _, __, args) {
48-
// Add the connection url to the MongoClient to retrieve later in the `lib/instrumentation/mongo/common`
49-
// captureAttributesOnStarted listener
50-
this[NR_ATTRS] = args[0]
47+
shim.recordOperation(mongodb.MongoClient, 'connect', function wrappedConnect(shim) {
5148
return new RecorderSpec({ callback: shim.LAST, name: 'connect' })
5249
})
5350
}
@@ -61,7 +58,7 @@ function instrumentClient(shim, mongodb) {
6158
* as well as sets up a listener for when commands start to properly
6259
* add necessary attributes to segments
6360
*
64-
* @param {Shim} shim
61+
* @param {Shim} shim instance of shim
6562
* @param {object} mongodb resolved package
6663
*/
6764
module.exports = function instrument(shim, mongodb) {

‎lib/instrumentation/mongodb/v4-mongo.js

+11-17
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ const {
1818
* parser used to grab the collection and operation
1919
* from a running query
2020
*
21-
* @param {object} operation
21+
* @param {object} operation mongodb operation
22+
* @returns {object} { operation, collection } parsed operation and collection
2223
*/
2324
function queryParser(operation) {
2425
let collection = this.collectionName || 'unknown'
@@ -39,23 +40,15 @@ function queryParser(operation) {
3940
* update host, port and database_name
4041
* on segment attributes
4142
*
42-
* @param {Shim} shim
43-
* @param {CommandStartedEvent} evnt
43+
* @param {Shim} shim instance of shim
44+
* @param {CommandStartedEvent} evnt mongodb event
4445
*/
4546
function cmdStartedHandler(shim, evnt) {
4647
if (evnt.connectionId) {
47-
let [host, port] = parseAddress(evnt.address)
48-
49-
// connection via socket get port from 1st host
50-
// socketPath property
51-
// which looks like mongodb:///tmp/mongodb-27017.sock"
52-
if (['undefined'].includes(host, port)) {
53-
host = 'localhost'
54-
const hosts = this.s.options.hosts
55-
if (hosts && hosts.length && hosts[0].socketPath) {
56-
port = hosts[0].socketPath
57-
}
58-
} else if (['127.0.0.1', '::1', '[::1]'].includes(host)) {
48+
const address = parseAddress(evnt.address)
49+
let [host] = address
50+
const [, port] = address
51+
if (['127.0.0.1', '::1', '[::1]'].includes(host)) {
5952
host = 'localhost'
6053
}
6154

@@ -68,7 +61,8 @@ function cmdStartedHandler(shim, evnt) {
6861
* enable APM(monitorCommands) and add the
6962
* `commandStarted` listener
7063
*
71-
* @param {Shim} shim
64+
* @param {Shim} shim instance of shim
65+
* @returns {OperationSpec} spec to capture connect method
7266
*/
7367
function wrapConnect(shim) {
7468
this.monitorCommands = true
@@ -82,7 +76,7 @@ function wrapConnect(shim) {
8276
* so we can properly update the segment attributes with a more accurate
8377
* host/port/database name
8478
*
85-
* @param {Shim} shim
79+
* @param {Shim} shim instance of shim
8680
* @param {MongoClient} MongoClient reference
8781
*/
8882
function instrumentMongoClient(shim, MongoClient) {

‎test/versioned/mongodb/collection-common.js

-89
Original file line numberDiff line numberDiff line change
@@ -184,95 +184,6 @@ function collectionTest(name, run) {
184184
})
185185
})
186186

187-
// The domain socket tests should only be run if there is a domain socket
188-
// to connect to, which only happens if there is a Mongo instance running on
189-
// the same box as these tests.
190-
const domainPath = common.getDomainSocketPath()
191-
const shouldTestDomain = domainPath
192-
t.test('domain socket', { skip: !shouldTestDomain }, function (t) {
193-
t.autoend()
194-
t.beforeEach(async function () {
195-
agent = helper.instrumentMockedAgent()
196-
METRIC_HOST_NAME = agent.config.getHostnameSafe()
197-
METRIC_HOST_PORT = domainPath
198-
199-
const mongodb = require('mongodb')
200-
201-
await dropTestCollections(mongodb)
202-
const res = await common.connect(mongodb, domainPath)
203-
client = res.client
204-
db = res.db
205-
collection = db.collection(COLLECTIONS.collection1)
206-
await populate(collection)
207-
})
208-
209-
t.afterEach(async function () {
210-
await common.close(client, db)
211-
helper.unloadAgent(agent)
212-
agent = null
213-
})
214-
215-
t.test('should have domain socket in metrics', function (t) {
216-
t.notOk(agent.getTransaction(), 'should not have transaction')
217-
helper.runInTransaction(agent, function (transaction) {
218-
transaction.name = common.TRANSACTION_NAME
219-
run(t, collection, function (err, segments, metrics) {
220-
t.error(err)
221-
transaction.end()
222-
const re = new RegExp('^Datastore/instance/MongoDB/' + domainPath)
223-
const badMetrics = Object.keys(agent.metrics._metrics.unscoped).filter(function (m) {
224-
return re.test(m)
225-
})
226-
t.notOk(badMetrics.length, 'should not use domain path as host name')
227-
common.checkMetrics(t, agent, METRIC_HOST_NAME, METRIC_HOST_PORT, metrics || [])
228-
t.end()
229-
})
230-
})
231-
})
232-
})
233-
234-
t.test('domain socket replica set', { skip: !shouldTestDomain }, function (t) {
235-
t.autoend()
236-
t.beforeEach(async function () {
237-
agent = helper.instrumentMockedAgent()
238-
METRIC_HOST_NAME = agent.config.getHostnameSafe()
239-
METRIC_HOST_PORT = domainPath
240-
241-
const mongodb = require('mongodb')
242-
243-
await dropTestCollections(mongodb)
244-
const res = await common.connect(mongodb, domainPath)
245-
client = res.client
246-
db = res.db
247-
collection = db.collection(COLLECTIONS.collection1)
248-
await populate(collection)
249-
})
250-
251-
t.afterEach(async function () {
252-
await common.close(client, db)
253-
helper.unloadAgent(agent)
254-
agent = null
255-
})
256-
257-
t.test('should have domain socket in metrics', function (t) {
258-
t.notOk(agent.getTransaction(), 'should not have transaction')
259-
helper.runInTransaction(agent, function (transaction) {
260-
transaction.name = common.TRANSACTION_NAME
261-
run(t, collection, function (err, segments, metrics) {
262-
t.error(err)
263-
transaction.end()
264-
const re = new RegExp('^Datastore/instance/MongoDB/' + domainPath)
265-
const badMetrics = Object.keys(agent.metrics._metrics.unscoped).filter(function (m) {
266-
return re.test(m)
267-
})
268-
t.notOk(badMetrics.length, 'should not use domain path as host name')
269-
common.checkMetrics(t, agent, METRIC_HOST_NAME, METRIC_HOST_PORT, metrics || [])
270-
t.end()
271-
})
272-
})
273-
})
274-
})
275-
276187
// this seems to break in 3.x up to 3.6.0
277188
// I think it is because of this https://jira.mongodb.org/browse/NODE-2452
278189
if (semver.satisfies(pkgVersion, '>=3.6.0')) {

‎test/versioned/mongodb/common.js

-13
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
'use strict'
77

8-
const fs = require('fs')
98
const mongoPackage = require('mongodb/package.json')
109
const params = require('../../lib/params')
1110
const semver = require('semver')
@@ -44,7 +43,6 @@ exports.close = function close() {
4443
exports.checkMetrics = checkMetrics
4544
exports.getHostName = getHostName
4645
exports.getPort = getPort
47-
exports.getDomainSocketPath = getDomainSocketPath
4846

4947
function connectV2(mongodb, path) {
5048
return new Promise((resolve, reject) => {
@@ -223,17 +221,6 @@ function checkMetrics(t, agent, host, port, metrics) {
223221
})
224222
}
225223

226-
function getDomainSocketPath() {
227-
const files = fs.readdirSync('/tmp')
228-
for (let i = 0; i < files.length; ++i) {
229-
const file = '/tmp/' + files[i]
230-
if (/^\/tmp\/mongodb.*?\.sock$/.test(file)) {
231-
return file
232-
}
233-
}
234-
return null
235-
}
236-
237224
function getMetrics(agent) {
238225
return agent.metrics._metrics
239226
}

‎test/versioned/mongodb/db-common.js

-39
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ if (semver.satisfies(common.pkgVersion, '2.2.x')) {
1919

2020
function dbTest(name, run) {
2121
mongoTest(name, function init(t, agent) {
22-
const LOCALHOST = agent.config.getHostnameSafe()
23-
const domainPath = common.getDomainSocketPath()
2422
const mongodb = require('mongodb')
2523
let db = null
2624
let client = null
@@ -65,43 +63,6 @@ function dbTest(name, run) {
6563
})
6664
})
6765
})
68-
69-
// The domain socket tests should only be run if there is a domain socket
70-
// to connect to, which only happens if there is a Mongo instance running on
71-
// the same box as these tests.
72-
const shouldTestDomain = domainPath
73-
74-
t.test('domain socket', { skip: !shouldTestDomain }, function (t) {
75-
t.autoend()
76-
t.beforeEach(async function () {
77-
// mongo >= 3.6.9 fails if you try to create an existing collection
78-
// drop before executing tests
79-
if (name === 'createCollection') {
80-
await collectionCommon.dropTestCollections(mongodb)
81-
}
82-
MONGO_HOST = LOCALHOST
83-
MONGO_PORT = domainPath
84-
85-
const res = await common.connect(mongodb, domainPath)
86-
client = res.client
87-
db = res.db
88-
})
89-
90-
t.afterEach(function () {
91-
return common.close(client, db)
92-
})
93-
94-
t.test('with transaction', function (t) {
95-
t.notOk(agent.getTransaction(), 'should not have transaction')
96-
helper.runInTransaction(agent, function (transaction) {
97-
run(t, db, function (names, opts = {}) {
98-
verifyMongoSegments(t, agent, transaction, names, opts)
99-
transaction.end()
100-
t.end()
101-
})
102-
})
103-
})
104-
})
10566
})
10667
}
10768

‎test/versioned/mongodb/legacy/cursor.tap.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const { pkgVersion, STATEMENT_PREFIX, COLLECTIONS } = require('../common')
1515
common.test('count', function countTest(t, collection, verify) {
1616
collection.find({}).count(function onCount(err, data) {
1717
t.notOk(err, 'should not error')
18-
t.equal(data, 30, 'should have correct result')
18+
t.ok(data >= 30, 'should have correct result')
1919
verify(null, [`${STATEMENT_PREFIX}/count`, 'Callback: onCount'], ['count'])
2020
})
2121
})

0 commit comments

Comments
 (0)
Please sign in to comment.