Skip to content
This repository was archived by the owner on Jan 21, 2026. It is now read-only.

Commit fe7e925

Browse files
authored
fix: fix tracing not working in mongoose 3.3+ (#1134)
1 parent 259e9f8 commit fe7e925

4 files changed

Lines changed: 137 additions & 2 deletions

File tree

src/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ export const defaultConfig = {
338338
http: path.join(pluginDirectory, 'plugin-http.js'),
339339
http2: path.join(pluginDirectory, 'plugin-http2.js'),
340340
koa: path.join(pluginDirectory, 'plugin-koa.js'),
341+
mongodb: path.join(pluginDirectory, 'plugin-mongodb.js'),
341342
'mongodb-core': path.join(pluginDirectory, 'plugin-mongodb-core.js'),
342343
mongoose: path.join(pluginDirectory, 'plugin-mongoose.js'),
343344
mysql: path.join(pluginDirectory, 'plugin-mysql.js'),

src/plugins/plugin-mongodb.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/**
2+
* Copyright 2019 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
'use strict';
17+
18+
/**
19+
* NOTE: This file is almost completely cloned from the mongodb-core plugin, as
20+
* mongodb-core was absorbed into mongodb in 3.3+. Note that we only support
21+
* the mongodb npm module as a backend for mongoose; standalone usage is not
22+
* guaranteed to be traced correctly.
23+
* Any changes here might need to go in there as well.
24+
*/
25+
26+
var shimmer = require('shimmer');
27+
28+
var SUPPORTED_VERSIONS = '>=3.3';
29+
30+
function createNextWrap(api) {
31+
return function nextWrap(next) {
32+
return function next_trace(cb) {
33+
var span = api.createChildSpan({ name: 'mongo-cursor' });
34+
if (!api.isRealSpan(span)) {
35+
return next.apply(this, arguments);
36+
}
37+
span.addLabel('db', this.ns);
38+
if (api.enhancedDatabaseReportingEnabled()) {
39+
span.addLabel('cmd', JSON.stringify(this.cmd));
40+
}
41+
return next.call(this, wrapCallback(api, span, cb));
42+
};
43+
};
44+
}
45+
46+
function wrapWithLabel(api, label) {
47+
return function(original) {
48+
return function mongo_operation_trace(ns, ops, options, callback) {
49+
var span = api.createChildSpan({ name: label });
50+
if (!api.isRealSpan(span)) {
51+
return original.apply(this, arguments);
52+
}
53+
span.addLabel('db', ns);
54+
if (api.enhancedDatabaseReportingEnabled()) {
55+
span.addLabel('operations', JSON.stringify(ops));
56+
}
57+
if (typeof options === 'function') {
58+
return original.call(this, ns, ops,
59+
wrapCallback(api, span, options));
60+
} else {
61+
return original.call(this, ns, ops, options,
62+
wrapCallback(api, span, callback));
63+
}
64+
};
65+
};
66+
}
67+
68+
/**
69+
* Wraps the provided callback so that the provided span will
70+
* be closed immediately after the callback is invoked.
71+
*
72+
* @param {Span} span The span to be closed.
73+
* @param {Function} done The callback to be wrapped.
74+
* @return {Function} The wrapped function.
75+
*/
76+
function wrapCallback(api, span, done) {
77+
var fn = function(err, res) {
78+
if (api.enhancedDatabaseReportingEnabled()) {
79+
if (err) {
80+
// Errors may contain sensitive query parameters.
81+
span.addLabel('mongoError', err);
82+
}
83+
if (res) {
84+
var result = res.result ? res.result : res;
85+
span.addLabel('result', result);
86+
}
87+
}
88+
span.endSpan();
89+
if (done) {
90+
done(err, res);
91+
}
92+
};
93+
return api.wrap(fn);
94+
}
95+
96+
function createOnceWrap(api) {
97+
return function onceWrap(once) {
98+
return function once_trace(event, cb) {
99+
return once.call(this, event, api.wrap(cb));
100+
};
101+
};
102+
}
103+
104+
module.exports = [
105+
{
106+
file: 'lib/core/connection/pool.js',
107+
versions: SUPPORTED_VERSIONS,
108+
patch: function(pool, api) {
109+
shimmer.wrap(pool.prototype, 'once', createOnceWrap(api));
110+
},
111+
unpatch: function(pool) {
112+
shimmer.unwrap(pool.prototype, 'once');
113+
}
114+
},
115+
{
116+
file: 'lib/core/index.js',
117+
versions: SUPPORTED_VERSIONS,
118+
patch: function(mongo, api) {
119+
shimmer.wrap(mongo.Server.prototype, 'command', wrapWithLabel(api, 'mongo-command'));
120+
shimmer.wrap(mongo.Server.prototype, 'insert', wrapWithLabel(api, 'mongo-insert'));
121+
shimmer.wrap(mongo.Server.prototype, 'update', wrapWithLabel(api, 'mongo-update'));
122+
shimmer.wrap(mongo.Server.prototype, 'remove', wrapWithLabel(api, 'mongo-remove'));
123+
shimmer.wrap(mongo.Cursor.prototype, '_next', createNextWrap(api));
124+
},
125+
unpatch: function(mongo) {
126+
shimmer.unwrap(mongo.Server.prototype, 'command');
127+
shimmer.unwrap(mongo.Server.prototype, 'insert');
128+
shimmer.unwrap(mongo.Server.prototype, 'update');
129+
shimmer.unwrap(mongo.Server.prototype, 'remove');
130+
shimmer.unwrap(mongo.Cursor.prototype, '_next');
131+
}
132+
}
133+
];
134+
135+
export default {};

test/fixtures/plugin-fixtures.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143
},
144144
"mongoose5": {
145145
"dependencies": {
146-
"mongoose": "~5.6.0"
146+
"mongoose": "^5.7.0"
147147
}
148148
},
149149
"mysql-2": {

test/plugins/test-trace-mongoose.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ describe('mongoose integration tests', function() {
3636
});
3737
});
3838

39-
// TODO(kjin): In plugin-fixtures.json, unpin mongoose 5
4039
const versions = [4, 5];
4140
for (const version of versions) {
4241
describe(`mongoose@${version}`, () => {

0 commit comments

Comments
 (0)