skywalking-backend-js
Version:
The NodeJS agent for Apache SkyWalking
209 lines • 8.32 kB
JavaScript
;
/*!
*
* 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 });
exports.execute = exports.getAWS = void 0;
var tslib_1 = require("tslib");
var Tag_1 = tslib_1.__importDefault(require("../Tag"));
var _AWS = null;
var _runTo, _send, _promise;
// XXX: Special versions of wrapCallback() and wrapPromise() which allows wrapping successful callback. This is used
// when an Exit span is converted to an Entry span on success of getting SQS messages. It does some extra stuff which is
// harmless in this context because it comes from a specialized fork of agent.
var wrapCallback = function (span, callback, idxError, state) {
if (idxError === void 0) { idxError = false; }
return function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (state) {
if (state.stopped)
// don't proc span stuff if span already stopped
return callback.apply(this, args);
if (!state.noStop) {
state.stopped = true;
if (state.timeouts) {
for (var _b = 0, _c = state.timeouts; _b < _c.length; _b++) {
var timeout = _c[_b];
clearTimeout(timeout);
}
}
}
}
span.resync();
var ret;
var isErrorOrPostCall = idxError !== false && args[idxError];
try {
if (isErrorOrPostCall)
span.error(args[idxError]);
else if (state === null || state === void 0 ? void 0 : state.beforeCB) {
isErrorOrPostCall = true;
span = (_a = state.beforeCB).call.apply(_a, tslib_1.__spreadArrays([this, span], args));
isErrorOrPostCall = false;
return callback.apply(this, args);
}
else
isErrorOrPostCall = true;
}
catch (err) {
span.error(err);
throw err;
}
finally {
if (!(state === null || state === void 0 ? void 0 : state.noStop))
span.stop();
else
span.async();
if (isErrorOrPostCall)
ret = callback.apply(this, args);
}
return ret;
};
};
var wrapPromise = function (span, promise, state, initialized) {
if (!initialized) {
state = tslib_1.__assign(tslib_1.__assign({}, (state || {})), { stopped: 0, thend: 0, catched: 0, timeouts: [] });
promise = promise.then(
// make sure span ends even if there is no user .then(), .catch() or .finally()
function (res) {
state.timeouts.push(setTimeout(function () {
if (!state.stopped++) {
span.stop();
}
}));
return res;
}, function (err) {
state.timeouts.push(setTimeout(function () {
if (!state.stopped++) {
span.error(err);
span.stop();
}
}));
return Promise.reject(err);
});
}
var _then = promise.then;
var _catch = promise.catch;
Object.defineProperty(promise, 'then', {
configurable: true,
writable: true,
value: function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (args[0] && !state.thend++)
args[0] = wrapCallback(span, args[0], false, state);
if (args[1] && !state.catched++)
args[1] = wrapCallback(span, args[1], 0, state);
var _promise = _then.apply(this, args);
if (state.thend && state.catched)
return _promise;
else
return wrapPromise(span, _promise, state, true);
},
});
Object.defineProperty(promise, 'catch', {
configurable: true,
writable: true,
value: function (err) {
if (!state.catched++)
err = wrapCallback(span, err, 0, state);
var _promise = _catch.call(this, err);
if (state.thend && state.catched)
return _promise;
else
return wrapPromise(span, _promise, state, true);
},
});
return promise;
};
function getAWS(installer) {
var _a, _b;
if (!_AWS) {
_AWS = (_b = (_a = installer.require) === null || _a === void 0 ? void 0 : _a.call(installer, 'aws-sdk')) !== null && _b !== void 0 ? _b : require('aws-sdk');
_runTo = _AWS.Request.prototype.runTo;
_send = _AWS.Request.prototype.send;
_promise = _AWS.Request.prototype.promise;
}
return _AWS;
}
exports.getAWS = getAWS;
exports.execute = function (span, _this, func, params, callback, hostTag, beforeCB) {
var _a, _b, _c, _d;
span.start();
var state = beforeCB ? { beforeCB: beforeCB } : null;
try {
if (callback)
callback = wrapCallback(span, callback, 0, state);
var req = func.call(_this, params, callback);
if (hostTag)
span.tag(Tag_1.default[hostTag]((_b = (_a = req.httpRequest) === null || _a === void 0 ? void 0 : _a.endpoint) === null || _b === void 0 ? void 0 : _b.href));
else if (!span.peer && hostTag !== null)
span.peer = (_d = (_c = req.httpRequest) === null || _c === void 0 ? void 0 : _c.endpoint) === null || _d === void 0 ? void 0 : _d.href;
// span.peer = `${req.httpRequest?.endpoint?.hostname ?? '???'}:${req.httpRequest?.endpoint?.port ?? '???'}`;
if (!callback) {
req.send = function (send_callback) {
if (send_callback)
send_callback = callback = wrapCallback(span, send_callback, 0, state);
_send.call(this, send_callback);
};
req.promise = function () {
var ret = _promise.apply(this, arguments);
if (!callback) {
// we check just in case a .send() was done, which shouldn't be done but users...
callback = true;
ret = wrapPromise(span, ret,
// convert from Promise.then(res) success args to aws-sdk2 callback(err, res) success args
beforeCB ? { beforeCB: function (span, res) { return beforeCB(span, null, res); } } : null);
}
return ret;
};
req.on('complete', function (res) {
if (!callback) {
// we check again because .send() might have introduced a callback
var block = span.resync();
if (res.error)
span.error(res.error);
span.stop();
}
});
}
req.runTo = function () {
// we need to resync for this so that the http client picks up our exit span and sees that it inherits from it and doesn't do a whole new span
span.resync();
try {
_runTo.apply(this, arguments);
}
finally {
span.async();
}
};
span.async();
return req;
}
catch (e) {
span.error(e);
span.stop();
throw e;
}
};
//# sourceMappingURL=SDK2.js.map