Skip to content

Commit

Permalink
feat(collector): added node:fs, restify and socket.io support (OpenTe…
Browse files Browse the repository at this point in the history
…lemetry integration) (#715)

refs #109122
  • Loading branch information
kirrg001 committed Jun 12, 2023
1 parent 545b802 commit 60f3bb9
Show file tree
Hide file tree
Showing 52 changed files with 3,024 additions and 89 deletions.
1,346 changes: 1,338 additions & 8 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,13 @@
"request": "^2.88.0",
"request-promise": "^4.2.2",
"request-promise-native": "^1.0.5",
"restify": "^8.6.1",
"rimraf": "^3.0.2",
"sequelize": "^6.17.0",
"sinon": "^11.1.1",
"sinon-chai": "^3.7.0",
"socket.io": "^4.6.0",
"socket.io-client": "^4.6.0",
"sqs-consumer": "5.7.0",
"sqs-consumer-v6": "npm:sqs-consumer@^6.2.0",
"superagent": "^6.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/autoprofile/lib/samplers/async_sampler.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

'use strict';

const fs = require('fs');
const { uninstrumentedFs: fs } = require('@instana/core');
const util = require('util');
const CallSite = require('../profile').CallSite;
const Profile = require('../profile').Profile;
Expand Down
1 change: 1 addition & 0 deletions packages/autoprofile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
}
],
"dependencies": {
"@instana/core": "2.23.0",
"detect-libc": "^1.0.3",
"nan": "^2.14.2"
},
Expand Down
3 changes: 2 additions & 1 deletion packages/aws-lambda-auto-wrap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
"url": "https://github.com/instana/nodejs/issues"
},
"dependencies": {
"@instana/aws-lambda": "2.23.0"
"@instana/aws-lambda": "2.23.0",
"@instana/core": "2.23.0"
},
"devDependencies": {
"no-code2": "2.0.0"
Expand Down
3 changes: 2 additions & 1 deletion packages/aws-lambda-auto-wrap/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

'use strict';

const fs = require('fs');
const { uninstrumentedFs: fs } = require('@instana/core');
const path = require('path');

const SPLIT_AT_DOT_REGEX = /^([^.]*)\.(.*)$/;
const TWO_DOTS = '..';
const DEFAULT_HANDLER = 'index.handler';
Expand Down
2 changes: 1 addition & 1 deletion packages/collector/src/actions/source.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

'use strict';

const fs = require('fs');
const { uninstrumentedFs: fs } = require('@instana/core');

/** @type {import('@instana/core/src/logger').GenericLogger} */
let logger;
Expand Down
30 changes: 15 additions & 15 deletions packages/collector/src/agentConnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@

'use strict';

const { atMostOnce } = require('@instana/core').util;
const fs = require('fs');
const { http } = require('@instana/core').uninstrumentedHttp;
const { util, uninstrumentedHttp, uninstrumentedFs: fs } = require('@instana/core');
const http = uninstrumentedHttp.http;

const pathUtil = require('path');
const { propertySizes } = require('@instana/core').util;

/** @typedef {import('@instana/core/src/tracing/cls').InstanaBaseSpan} InstanaBaseSpan */

Expand Down Expand Up @@ -79,7 +78,7 @@ exports.AgentEventSeverity = {
* @param {(err: Error, rawResponse?: string) => void} cb
*/
exports.announceNodeCollector = function announceNodeCollector(cb) {
cb = atMostOnce('callback for announceNodeCollector', cb);
cb = util.atMostOnce('callback for announceNodeCollector', cb);

/** @type {AgentConnectionPayload} */
const payload = {
Expand Down Expand Up @@ -202,7 +201,7 @@ exports.checkWhetherAgentIsReadyToAcceptData = function checkWhetherAgentIsReady
* @param {(...args: *) => *} cb
*/
function checkWhetherResponseForPathIsOkay(path, cb) {
cb = atMostOnce('callback for checkWhetherResponseForPathIsOkay', cb);
cb = util.atMostOnce('callback for checkWhetherResponseForPathIsOkay', cb);

const req = http.request(
{
Expand Down Expand Up @@ -238,7 +237,7 @@ function checkWhetherResponseForPathIsOkay(path, cb) {
* @param {(...args: *) => *} cb
*/
exports.sendMetrics = function sendMetrics(data, cb) {
cb = atMostOnce('callback for sendMetrics', cb);
cb = util.atMostOnce('callback for sendMetrics', cb);

sendData(`/com.instana.plugin.nodejs.${pidStore.pid}`, data, (err, body) => {
if (err) {
Expand All @@ -264,7 +263,7 @@ exports.sendMetrics = function sendMetrics(data, cb) {
* @param {(...args: *) => *} cb
*/
exports.sendSpans = function sendSpans(spans, cb) {
const callback = atMostOnce('callback for sendSpans', err => {
const callback = util.atMostOnce('callback for sendSpans', err => {
if (err && !maxContentErrorHasBeenLogged && err instanceof PayloadTooLargeError) {
logLargeSpans(spans);
}
Expand All @@ -279,7 +278,7 @@ exports.sendSpans = function sendSpans(spans, cb) {
* @param {(...args: *) => *} cb
*/
exports.sendProfiles = function sendProfiles(profiles, cb) {
const callback = atMostOnce('callback for sendProfiles', err => {
const callback = util.atMostOnce('callback for sendProfiles', err => {
if (err && err instanceof PayloadTooLargeError) {
logger.warn('Profiles are too too large to be sent.');
} else if (err && err.statusCode === 404) {
Expand All @@ -299,7 +298,7 @@ exports.sendProfiles = function sendProfiles(profiles, cb) {
* @param {(...args: *) => *} cb
*/
exports.sendEvent = function sendEvent(eventData, cb) {
const callback = atMostOnce('callback for sendEvent', (err, responseBody) => {
const callback = util.atMostOnce('callback for sendEvent', (err, responseBody) => {
cb(err, responseBody);
});

Expand All @@ -321,7 +320,7 @@ exports.sendAgentMonitoringEvent = function sendAgentMonitoringEvent(code, categ
category
};

const callback = atMostOnce('callback for sendAgentMonitoringEvent', (err, responseBody) => {
const callback = util.atMostOnce('callback for sendAgentMonitoringEvent', (err, responseBody) => {
cb(err, responseBody);
});

Expand All @@ -334,7 +333,7 @@ exports.sendAgentMonitoringEvent = function sendAgentMonitoringEvent(code, categ
* @param {(...args: *) => *} cb
*/
exports.sendAgentResponseToAgent = function sendAgentResponseToAgent(messageId, response, cb) {
cb = atMostOnce('callback for sendAgentResponseToAgent', cb);
cb = util.atMostOnce('callback for sendAgentResponseToAgent', cb);

sendData(
`/com.instana.plugin.nodejs/response.${pidStore.pid}?messageId=${encodeURIComponent(messageId)}`,
Expand All @@ -348,7 +347,7 @@ exports.sendAgentResponseToAgent = function sendAgentResponseToAgent(messageId,
* @param {(...args: *) => *} cb
*/
exports.sendTracingMetricsToAgent = function sendTracingMetricsToAgent(tracingMetrics, cb) {
const callback = atMostOnce('callback for sendTracingMetricsToAgent', err => {
const callback = util.atMostOnce('callback for sendTracingMetricsToAgent', err => {
cb(err);
});

Expand All @@ -363,7 +362,7 @@ exports.sendTracingMetricsToAgent = function sendTracingMetricsToAgent(tracingMe
* @returns
*/
function sendData(path, data, cb, ignore404 = false) {
cb = atMostOnce(`callback for sendData: ${path}`, cb);
cb = util.atMostOnce(`callback for sendData: ${path}`, cb);

const payloadAsString = JSON.stringify(data, circularReferenceRemover());
if (typeof logger.trace === 'function') {
Expand Down Expand Up @@ -474,7 +473,8 @@ function logLargeSpans(spans) {
.slice(0, 4)
.map(
s =>
`span name: ${s.span.n}, largest attribute: ${propertySizes(s.span)
`span name: ${s.span.n}, largest attribute: ${util
.propertySizes(s.span)
.sort((p1, p2) => p2.length - p1.length)
.slice(0, 1)
.map(p => `${p.property} (${p.length} bytes)`)}`
Expand Down
2 changes: 1 addition & 1 deletion packages/collector/src/cmdline.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

'use strict';

const fs = require('fs');
const { uninstrumentedFs: fs } = require('@instana/core');

/** @type {import('@instana/core/src/logger').GenericLogger} */
let logger;
Expand Down
2 changes: 1 addition & 1 deletion packages/collector/src/pidStore/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

'use strict';

const fs = require('fs');
const EventEmitter = require('events').EventEmitter;

const { uninstrumentedFs: fs } = require('@instana/core');
const internalPidStore = require('./internalPidStore');
const agentOpts = require('../agent/opts');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

'use strict';

const fs = require('fs');
const { uninstrumentedFs: fs } = require('@instana/core');
const path = require('path');

/** @type {import('@instana/core/src/logger').GenericLogger} */
Expand Down
9 changes: 4 additions & 5 deletions packages/collector/test/bazel_inode_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ describe('agent connection/bazel', function () {
describe("Bazel's node-patches are present", () => {
before(() => {
agentConnection = proxyquire('../src/agentConnection', {
// Stub out the fs part part of the fd/inode lookup (the readlinkSync call), and act as if node-patches from
// Bazel were active, that is, return an absolute path from readlinkSync.
fs: mockFs(`/proc/${process.pid}/fd/socket:[12345]`),

// stub out the http communication part of the announce request
'@instana/core': mockInstanaCoreHttp(),

Expand Down Expand Up @@ -111,7 +107,10 @@ describe('agent connection/bazel', function () {
return req;
}
}
}
},
// Stub out the fs part part of the fd/inode lookup (the readlinkSync call), and act as if node-patches from
// Bazel were active, that is, return an absolute path from readlinkSync.
uninstrumentedFs: mockFs(`/proc/${process.pid}/fd/socket:[12345]`)
};
}
});
4 changes: 3 additions & 1 deletion packages/collector/test/cmdline_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ describe('cmdline', () => {

function req() {
result = proxyquire('../src/cmdline', {
fs,
'@instana/core': {
uninstrumentedFs: fs
},

// We need to proxyquire logger, too, to work around the duplicate module logger name check.
'./logger': proxyquire('../src/logger', {})
Expand Down
12 changes: 10 additions & 2 deletions packages/collector/test/opentelemetry/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,19 @@ const initOtel = () => {
};

if (process.env.INSTANA_LOAD_FIRST === 'true') {
require('../../src')();
require('../../src')({
tracing: {
useOpentelemetry: false
}
});
initOtel();
} else {
initOtel();
require('../../src')();
require('../../src')({
tracing: {
useOpentelemetry: false
}
});
}

require('mysql');
Expand Down
4 changes: 2 additions & 2 deletions packages/collector/test/pidStore/pidStore_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ describe('pidStore', () => {

function doRequire() {
pidStore = proxyquire('../../src/pidStore', {
fs: {
readFileSync
'@instana/core': {
uninstrumentedFs: { readFileSync }
},
'./internalPidStore': {
pid: process.pid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,17 @@

'use strict';

const instana = require('../../../../../..')();
const instana = require('../../../../../..')({
tracing: {
// We need to disable Otel here because on CI the AWS sdk loads the config file more often than locally
// and creates more spans than locally.
// Background: if you receive a message, aws verifies if you have a cached config file.
// AWS tries to load the file from disk ~/.aws/config and caches it.
// But if the file does not exist, it tries to load it again and again.
// https://github.com/aws/aws-sdk-js/blob/5bfd7c11067e1d52391deb06d165551218f7f19e/lib/shared-ini/ini-loader.js#L67
useOpentelemetry: false
}
});

const express = require('express');
const request = require('request-promise');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ AWS.HttpRequest.prototype.appendToUserAgent = function () {
};

AWS.config.update({ region: 'us-east-2' });

const sqs = new AWS.SQS();

exports.sqs = sqs;
Expand Down
10 changes: 5 additions & 5 deletions packages/collector/test/tracing/control_flow/q/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,28 +48,28 @@ mochaSuiteFn('tracing/q', function () {
runTest('/delay2');
runTest('/timeout', verifySingleEntryWithError);
runTest('/nodeify');
runTest('/make-node-resolver');
runTest('/make-node-resolver', verifySingleEntry, { spanLength: 2 }); // calls fs.readFile
runTest('/with-event-emitter');
runTest('/entry-exit', verifyEntryAndExit);

function runTest(path, verification = verifySingleEntry) {
function runTest(path, verification = verifySingleEntry, opts = { spanLength: 1 }) {
it(`must trace: ${path}`, () =>
controls
.sendRequest({
method: 'GET',
path
})
.then(response => verification(response, path)));
.then(response => verification(response, path, opts)));
}

function verifySingleEntry(response, path) {
function verifySingleEntry(response, path, opts) {
expect(response.span).to.be.an('object');
expect(response.error).to.not.exist;
return testUtils.retry(() =>
agentControls.getSpans().then(spans => {
const entrySpan = verifyRootEntrySpan(spans, path);
expect(response.span.t).to.equal(entrySpan.t);
expect(spans).to.have.lengthOf(1);
expect(spans).to.have.lengthOf(opts.spanLength);
})
);
}
Expand Down
Loading

0 comments on commit 60f3bb9

Please sign in to comment.