UNPKG

@instana/core

Version:
127 lines (105 loc) 4.11 kB
/* * (c) Copyright IBM Corp. 2021 * (c) Copyright Instana Inc. and contributors 2021 */ 'use strict'; const shimmer = require('../../../../shimmer'); const hook = require('../../../../../util/hook'); const { getFunctionArguments } = require('../../../../../util/function_arguments'); /** @type {Array.<import('./instana_aws_product').InstanaAWSProduct}> */ const awsProducts = [ // require('./dynamodb'), require('./s3'), require('./sqs'), require('./kinesis'), require('./sns'), require('./lambda') ]; const awsProductInstances = []; const sqsConsumer = require('./sqs-consumer'); /** @type {Object.<string, import('./instana_aws_product').InstanaAWSProduct} */ const operationMap = {}; let isActive = false; exports.init = function init(config) { awsProducts.forEach(AwsProductClass => { const awsProductInstance = new AwsProductClass(config); awsProductInstances.push(awsProductInstance); Object.assign(operationMap, awsProductInstance.getOperations()); // NOTE: each aws product can have it's own init fn to wrap or unwrap specific functions if (awsProductInstance.init) { awsProductInstance.init(hook, shimmer); } }); sqsConsumer.init(); /** * https://github.com/aws/aws-sdk-js-v3/releases/tag/v3.1046.0 */ hook.onModuleLoad('@smithy/core/client', instrumentGlobalSmithy); /** * @aws-sdk/smithly-client >= 3.36.0 changed how the dist structure gets delivered * https://github.com/aws/aws-sdk-js-v3/blob/main/packages/smithy-client/CHANGELOG.md#3360-2021-10-08 * @aws-sdk/smithly-client is a subdependency of any @aws-sdk/* package */ hook.onFileLoad(/@aws-sdk\/smithy-client\/dist-cjs\/client\.js/, instrumentGlobalSmithy); /** * @aws-sdk/smithly-client < 3.36.0 */ hook.onFileLoad(/@aws-sdk\/smithy-client\/dist\/cjs\/client\.js/, instrumentGlobalSmithy); /** * @aws-sdk/smithly-client > 3.36.0 */ hook.onModuleLoad('@smithy/smithy-client', instrumentGlobalSmithy); }; exports.isActive = function () { return isActive; }; // NOTE: you currently can only disable the whole AWS SDK v3 exports.activate = function activate() { isActive = true; }; exports.deactivate = function deactivate() { isActive = false; }; /** * The require hook can run once while `exports` is still `{}` (cyclic CJS load); `exports` is then the same object * Node fills in later. Defer wrapping until after the current synchronous load completes. */ function instrumentGlobalSmithy(exports) { const tryWrap = () => { if (typeof exports.Client === 'function' && exports.Client.prototype) { shimmer.wrap(exports.Client.prototype, 'send', shimSmithySend); return true; } return false; }; if (!tryWrap()) { setImmediate(() => { tryWrap(); }); } return exports; } function shimSmithySend(originalSend) { return function () { const self = this; const smithySendArgs = getFunctionArguments(arguments); const command = smithySendArgs[0]; const serviceId = self.config && self.config.serviceId; let awsProduct = serviceId && awsProductInstances.find(aws => aws.getServiceIdName() === serviceId.toLowerCase()); if (awsProduct && awsProduct.supportsOperation(command.constructor.name)) { return awsProduct.instrumentedSmithySend(self, isActive, originalSend, smithySendArgs); } else { // This logic should not be used in AWS SDK v4. All AWS SDK v4 instrumentations must use the new approach // introduced in https://github.com/instana/nodejs/pull/838 for Kinesis. That is: Do not use an explicit // operationsInfo/operationsMap that restricts the traced operations to a subset of possible operations. // Instead, allow all operations to be traced using the operation name from `command.constructor.name` // for span.data.$spanName.op. awsProduct = operationMap[smithySendArgs[0].constructor.name]; if (awsProduct) { return awsProduct.instrumentedSmithySend(self, isActive, originalSend, smithySendArgs); } return originalSend.apply(self, smithySendArgs); } }; }