@kangc/skywalking-backend-js
Version:
The NodeJS agent for Apache SkyWalking
137 lines • 6.57 kB
JavaScript
"use strict";
/*!
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var SwPlugin_1 = require("../core/SwPlugin");
var ContextManager_1 = tslib_1.__importDefault(require("../trace/context/ContextManager"));
var Component_1 = require("../trace/Component");
var Tag_1 = tslib_1.__importDefault(require("../Tag"));
var Tracing_pb_1 = require("../proto/language-agent/Tracing_pb");
var MongoosePlugin = /** @class */ (function () {
function MongoosePlugin() {
this.module = 'mongoose';
this.versions = '*';
}
MongoosePlugin.prototype.install = function (installer) {
var Model = installer.require('mongoose').Model;
this.interceptOperation(Model, 'aggregate');
this.interceptOperation(Model, 'bulkWrite');
this.interceptOperation(Model, 'cleanIndexes');
this.interceptOperation(Model, 'count');
this.interceptOperation(Model, 'countDocuments');
this.interceptOperation(Model, 'create');
this.interceptOperation(Model, 'createCollection');
this.interceptOperation(Model, 'createIndexes');
this.interceptOperation(Model, 'deleteMany');
this.interceptOperation(Model, 'deleteOne');
this.interceptOperation(Model, 'distinct');
this.interceptOperation(Model, 'ensureIndexes');
this.interceptOperation(Model, 'estimatedDocumentCount');
this.interceptOperation(Model, 'exists');
this.interceptOperation(Model, 'find');
this.interceptOperation(Model, 'findById');
this.interceptOperation(Model, 'findByIdAndDelete');
this.interceptOperation(Model, 'findByIdAndRemove');
this.interceptOperation(Model, 'findByIdAndUpdate');
this.interceptOperation(Model, 'findOne');
this.interceptOperation(Model, 'findOneAndDelete');
this.interceptOperation(Model, 'findOneAndRemove');
this.interceptOperation(Model, 'findOneAndReplace');
this.interceptOperation(Model, 'findOneAndUpdate');
this.interceptOperation(Model, 'geoSearch');
this.interceptOperation(Model, 'insertMany');
this.interceptOperation(Model, 'listIndexes');
this.interceptOperation(Model, 'mapReduce');
this.interceptOperation(Model, 'populate');
this.interceptOperation(Model, 'remove');
this.interceptOperation(Model, 'replaceOne');
this.interceptOperation(Model, 'syncIndexes');
this.interceptOperation(Model, 'update');
this.interceptOperation(Model, 'updateMany');
this.interceptOperation(Model, 'updateOne');
this.interceptOperation(Model, 'validate');
this.interceptOperation(Model.prototype, 'delete');
this.interceptOperation(Model.prototype, 'deleteOne');
this.interceptOperation(Model.prototype, 'remove');
this.interceptOperation(Model.prototype, 'save');
// TODO:
// discriminator?
// startSession?
// where?
// NODO:
// hydrate
};
MongoosePlugin.prototype.interceptOperation = function (Container, operation) {
var _original = Container[operation];
if (!_original)
return;
Container[operation] = function () {
var _a;
var span = ContextManager_1.default.currentSpan;
if ((_a = span) === null || _a === void 0 ? void 0 : _a.mongooseInCall)
// mongoose has called into itself internally
return _original.apply(this, arguments);
var host = this.db.host + ":" + this.db.port;
span = ContextManager_1.default.current.newExitSpan('Mongoose/' + operation, Component_1.Component.MONGOOSE, Component_1.Component.MONGODB);
span.start();
try {
span.component = Component_1.Component.MONGOOSE;
span.layer = Tracing_pb_1.SpanLayer.DATABASE; // mongodb may not actually be called so we set these here in case
span.peer = host;
span.tag(Tag_1.default.dbType('MongoDB'));
span.tag(Tag_1.default.dbInstance(this.db.name));
var hasCB = typeof arguments[arguments.length - 1] === 'function';
if (hasCB) {
var wrappedCallback_1 = SwPlugin_1.wrapCallback(span, arguments[arguments.length - 1], 0);
arguments[arguments.length - 1] = function () {
// in case of immediate synchronous callback from mongoose
span.mongooseInCall = false;
wrappedCallback_1.apply(this, arguments);
};
}
span.mongooseInCall = true; // if mongoose calls into itself while executing this operation then ignore it
var ret = _original.apply(this, arguments);
span.mongooseInCall = false;
if (!hasCB) {
if (ret && typeof ret.then === 'function') {
// generic Promise check
ret = SwPlugin_1.wrapPromise(span, ret);
}
else {
// no callback passed in and no Promise or Cursor returned, play it safe
span.stop();
return ret;
}
}
span.async();
return ret;
}
catch (err) {
span.error(err);
span.stop();
throw err;
}
};
};
return MongoosePlugin;
}());
// noinspection JSUnusedGlobalSymbols
exports.default = new MongoosePlugin();
//# sourceMappingURL=MongoosePlugin.js.map