Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@instana/core

Package Overview
Dependencies
Maintainers
3
Versions
261
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@instana/core - npm Package Compare versions

Comparing version 1.106.5 to 1.106.6

4

package.json
{
"name": "@instana/core",
"version": "1.106.5",
"version": "1.106.6",
"description": "Core library for Instana's Node.js packages",

@@ -136,3 +136,3 @@ "main": "src/index.js",

},
"gitHead": "cc05d8aa93e154b98d7befa9557789064c66aa58"
"gitHead": "a13253b1e65d4c66d32495e092d8990073a0240f"
}
'use strict';
const url = require('url');
const shimmer = require('shimmer');
const requireHook = require('../../../util/requireHook');

@@ -8,2 +11,10 @@ const tracingUtil = require('../../tracingUtil');

let logger;
logger = require('../../../logger').getLogger('tracing/elasticsearch', newLogger => {
logger = newLogger;
});
const methodToActionRegex = /^(\w+?)(?:Api)?\.(?:.+) \[as (\w+)\]$/;
const endpointToIdRegex = /^\/[^/]+\/_doc\/([^/]+)$/;
let isActive = false;

@@ -16,2 +27,11 @@

function instrument(es) {
const ESAPI = require('@elastic/elasticsearch/api');
if (isConstructor(ESAPI)) {
instrumentTransport(es);
} else {
instrumentApiLayer(es, ESAPI);
}
}
function instrumentApiLayer(es, ESAPI) {
const OriginalClient = es.Client;

@@ -23,3 +43,3 @@ if (!OriginalClient || typeof OriginalClient !== 'function') {

const actionPaths = [];
forEachApiAction(actionPath => {
forEachApiAction(ESAPI, actionPath => {
actionPaths.push(actionPath);

@@ -106,17 +126,3 @@ });

if (action === 'mget' && params.body && params.body.docs && Array.isArray(params.body.docs)) {
getSpanDataFromMget1(span, params.body.docs);
} else if (action === 'mget' && params.body && params.body.ids && Array.isArray(params.body.ids)) {
getSpanDataFromMget2(span, params);
} else if (action === 'msearch' && Array.isArray(params.body)) {
getSpanDataFromMsearch(span, params.body);
} else {
span.data.elasticsearch.index = toStringEsMultiParameter(params.index);
span.data.elasticsearch.type = toStringEsMultiParameter(params.type);
span.data.elasticsearch.stats = toStringEsMultiParameter(params.stats);
span.data.elasticsearch.id = params.id;
if (action.indexOf('search') === 0) {
span.data.elasticsearch.query = tracingUtil.shortenDatabaseStatement(JSON.stringify(params));
}
}
processParams(span, params);

@@ -168,2 +174,4 @@ if (callbackIndex >= 0) {

}
parseConnectionFromResult(span, result);
span.d = Date.now() - span.ts;

@@ -180,5 +188,38 @@ span.transmit();

}
if (error.meta && error.meta.meta) {
parseConnectionFromResult(span, error.meta);
}
span.transmit();
}
function parseConnectionFromResult(span, result) {
// Result can also be a part of the error object, both have the meta.connection attribute.
// For the error object it is in error.meta.meta.connection (see onError).
if (!span.data.elasticsearch.cluster && !span.data.elasticsearch.address && result.meta && result.meta.connection) {
const connectionUrl = result.meta.connection.url;
if (connectionUrl && connectionUrl instanceof url.URL) {
span.data.elasticsearch.address = connectionUrl.hostname;
span.data.elasticsearch.port = connectionUrl.port;
}
}
}
function processParams(span, params) {
const action = span.data.elasticsearch.action;
const body = (params && params.body) || (params && params.bulkBody);
if (action === 'mget' && body && body.docs && Array.isArray(body.docs)) {
getSpanDataFromMget1(span, body.docs);
} else if (action === 'mget' && body && body.ids && Array.isArray(body.ids)) {
getSpanDataFromMget2(span, params);
} else if (action === 'msearch' && Array.isArray(body)) {
getSpanDataFromMsearch(span, body);
} else {
span.data.elasticsearch.index = toStringEsMultiParameter(params.index);
span.data.elasticsearch.type = toStringEsMultiParameter(params.type);
span.data.elasticsearch.id = params.id;
if (action.indexOf('search') === 0) {
span.data.elasticsearch.query = tracingUtil.shortenDatabaseStatement(JSON.stringify(params));
}
}
}
function toStringEsMultiParameter(param) {

@@ -204,3 +245,2 @@ if (param == null) {

const types = [];
const stats = [];
const ids = [];

@@ -210,3 +250,2 @@ for (let i = 0; i < docs.length; i++) {

collectParamFrom(docs[i], '_type', types);
collectParamFrom(docs[i], '_stats', stats);
collectParamFrom(docs[i], '_id', ids);

@@ -216,3 +255,2 @@ }

span.data.elasticsearch.type = types.length > 0 ? types.join(',') : undefined;
span.data.elasticsearch.stats = stats.length > 0 ? stats.join(',') : undefined;
span.data.elasticsearch.id = ids.length > 0 ? ids.join(',') : undefined;

@@ -222,6 +260,9 @@ }

function getSpanDataFromMget2(span, params) {
if (!params) {
return;
}
const body = (params && params.body) || (params && params.bulkBody);
span.data.elasticsearch.index = params.index ? toStringEsMultiParameter(params.index) : undefined;
span.data.elasticsearch.type = params.index ? toStringEsMultiParameter(params.type) : undefined;
span.data.elasticsearch.stats = params.index ? toStringEsMultiParameter(params.stats) : undefined;
span.data.elasticsearch.id = params.body.ids.length > 0 ? params.body.ids.join(',') : undefined;
span.data.elasticsearch.id = body && body.ids.length > 0 ? body.ids.join(',') : undefined;
}

@@ -232,3 +273,2 @@

const types = [];
const stats = [];
const query = [];

@@ -238,3 +278,2 @@ for (let i = 0; i < body.length; i++) {

collectParamFrom(body[i], 'type', types);
collectParamFrom(body[i], 'stats', stats);
collectParamFrom(body[i], 'query', query);

@@ -244,3 +283,2 @@ }

span.data.elasticsearch.type = types.length > 0 ? types.join(',') : undefined;
span.data.elasticsearch.stats = stats.length > 0 ? stats.join(',') : undefined;
span.data.elasticsearch.query = query.length > 0 ? tracingUtil.shortenDatabaseStatement(query.join(',')) : undefined;

@@ -258,4 +296,141 @@ }

function forEachApiAction(fn) {
const esApi = require('@elastic/elasticsearch/api')({
function instrumentTransport(es) {
// Starting with 7.9.1, the export of @elastic/elasticsearch/api expects to be called as a constructor. In fact,
// @elastic/elasticsearch#Client now inherits from @elastic/elasticsearch/api. See
// https://github.com/elastic/elasticsearch-js/commit/a064f0f357ea5797cb8a784671b85a6b0c88626d and
// https://github.com/elastic/elasticsearch-js/pull/1314 for details. Also, starting with that version, some API
// methods are added via Object.defineProperties with the default settings and only a getter, making it impossible
// to override/wrap them. For those versions we fall back to instrumenting the transport layer instead of the API.
if (es.Transport && es.Transport.prototype) {
shimmer.wrap(es.Transport.prototype, 'request', shimRequest);
} else {
logger.error(
'Cannot instrument @elastic/elasticsearch. Either es.Transport or es.Transport.prototype does not exist.'
);
}
}
function shimRequest(esReq) {
return function() {
if (!isActive || !cls.isTracing()) {
return esReq.apply(this, arguments);
}
const originalArgs = new Array(arguments.length);
for (let i = 0; i < arguments.length; i++) {
originalArgs[i] = arguments[i];
}
return instrumentedRequest(this, esReq, originalArgs);
};
}
function instrumentedRequest(ctx, origEsReq, originalArgs) {
const parentSpan = cls.getCurrentSpan();
if (constants.isExitSpan(parentSpan)) {
return origEsReq.apply(ctx, originalArgs);
}
// normalize arguments
let params = originalArgs[0] || {};
let options = originalArgs[1];
let callbackIndex = 2;
let originalCallback = originalArgs[callbackIndex];
if (typeof originalCallback !== 'function') {
if (typeof options === 'function') {
callbackIndex = 1;
originalCallback = originalArgs[callbackIndex];
} else if (typeof params === 'function') {
callbackIndex = 0;
originalCallback = originalArgs[callbackIndex];
params = {};
} else {
callbackIndex = -1;
originalCallback = null;
}
}
const httpPath = params.path;
return cls.ns.runAndReturn(() => {
const span = cls.startSpan('elasticsearch', constants.EXIT);
span.stack = tracingUtil.getStackTrace(instrumentedRequest, 1);
span.data.elasticsearch = {
endpoint: httpPath
};
findActionInStack(span);
processParams(span, params);
parseIdFromPath(span, httpPath);
const q = params.querystring;
if (q) {
if (typeof q === 'string') {
span.data.elasticsearch.query = tracingUtil.shortenDatabaseStatement(q);
} else if (typeof q === 'object' && Object.keys(q).length > 0) {
span.data.elasticsearch.query = tracingUtil.shortenDatabaseStatement(JSON.stringify(q));
}
}
if (callbackIndex >= 0) {
originalArgs[callbackIndex] = cls.ns.bind(function(error, result) {
if (error) {
onError(span, error);
} else {
onSuccess(span, result);
}
return originalCallback.apply(this, arguments);
});
return origEsReq.apply(ctx, originalArgs);
} else {
try {
return origEsReq.apply(ctx, originalArgs).then(onSuccess.bind(null, span), error => {
onError(span, error);
throw error;
});
} catch (e) {
// Immediately cleanup on synchronous errors.
throw e;
}
}
});
}
function findActionInStack(span) {
if (!span.stack) {
return;
}
const esApiFrames = span.stack.filter(frame => frame.c && frame.c.includes('@elastic/elasticsearch/api'));
if (esApiFrames.length === 0) {
return;
}
let esApiMethod = esApiFrames[esApiFrames.length - 1].m;
if (!esApiMethod) {
return;
}
const matchResult = methodToActionRegex.exec(esApiMethod);
if (matchResult) {
if (matchResult[1] === 'Client') {
// Top level API methods directly on Client, like `Client.indexApi [as index]`:
span.data.elasticsearch.action = `${matchResult[2].toLowerCase()}`;
} else {
// Nested API, like `IndicesApi.indicesRefreshApi [as refresh]`:
span.data.elasticsearch.action = `${matchResult[1].toLowerCase()}.${matchResult[2].toLowerCase()}`;
}
} else {
// fall back: use the full method name
span.data.elasticsearch.action = esApiMethod;
}
}
function parseIdFromPath(span, httpPath) {
if (httpPath) {
const matchResult = endpointToIdRegex.exec(httpPath);
if (matchResult) {
span.data.elasticsearch.id = matchResult[1];
}
}
}
function forEachApiAction(ESAPI, fn) {
const esApiFromBuildApi = ESAPI({
makeRequest: function dummyMakeRequest() {},

@@ -265,3 +440,3 @@ ConfigurationError: function DummyConfigurationError() {},

});
forEachKeyRecursive(esApi, [], fn);
forEachKeyRecursive(esApiFromBuildApi, [], fn);
}

@@ -298,2 +473,6 @@

function isConstructor(ESAPI) {
return ESAPI && typeof ESAPI.toString === 'function' && ESAPI.toString().includes('this[');
}
exports.activate = function activate() {

@@ -300,0 +479,0 @@ isActive = true;

@@ -58,3 +58,13 @@ 'use strict';

if (typeof transformerFn === 'function') {
cacheEntry.moduleExports = transformerFn(cacheEntry.moduleExports) || cacheEntry.moduleExports;
try {
cacheEntry.moduleExports = transformerFn(cacheEntry.moduleExports) || cacheEntry.moduleExports;
} catch (e) {
logger.error(`Cannot instrument ${moduleName} due to an error in instrumentation: ${e}`);
if (e.message) {
logger.error(e.message);
}
if (e.stack) {
logger.error(e.stack);
}
}
} else {

@@ -61,0 +71,0 @@ logger.error(

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc