appdynamics 22.2.0 → 22.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/appdynamics_version.json +2 -2
- package/lib/core/agent.js +12 -0
- package/lib/core/appdynamics_span_exporter.js +43 -0
- package/lib/core/opentelemetry-tracer.js +55 -24
- package/lib/libagent/libagent-connector.js +40 -2
- package/lib/probes/http-exit-probe.js +10 -2
- package/lib/probes/http-ot-utils.js +40 -36
- package/lib/probes/mongodb-probe.js +3 -0
- package/lib/profiler/profiler.js +7 -1
- package/lib/secure_app/library_metadata.js +56 -0
- package/lib/secure_app/secure_app.js +311 -0
- package/package.json +13 -11
- package/packageBck.json +13 -11
package/appdynamics_version.json
CHANGED
package/lib/core/agent.js
CHANGED
|
@@ -34,6 +34,7 @@ var CpuProfiler = require('../v8/cpu-profiler').CpuProfiler;
|
|
|
34
34
|
var HeapProfiler = require('../v8/heap-profiler').HeapProfiler;
|
|
35
35
|
var agentVersion = require('../../appdynamics_version.json');
|
|
36
36
|
var appDNativeLoader = require('appdynamics-native');
|
|
37
|
+
var SecureApp = require('../secure_app/secure_app').SecureApp;
|
|
37
38
|
|
|
38
39
|
var LibAgent = require('../libagent/libagent').LibAgent;
|
|
39
40
|
var LibagentConnector = require('../libagent/libagent-connector').LibagentConnector;
|
|
@@ -88,6 +89,7 @@ function Agent() {
|
|
|
88
89
|
this.gcStats = new GCStats(this);
|
|
89
90
|
this.cpuProfiler = new CpuProfiler(this);
|
|
90
91
|
this.heapProfiler = new HeapProfiler(this);
|
|
92
|
+
this.secureApp = new SecureApp(this);
|
|
91
93
|
|
|
92
94
|
this.libagent = null;
|
|
93
95
|
|
|
@@ -282,6 +284,10 @@ Agent.prototype.init = function (opts) {
|
|
|
282
284
|
self.cpuProfiler.init();
|
|
283
285
|
self.heapProfiler.init();
|
|
284
286
|
|
|
287
|
+
if(self.opts.secureAppEnabled) {
|
|
288
|
+
self.secureApp.init(this);
|
|
289
|
+
}
|
|
290
|
+
|
|
285
291
|
// Initialize libagent
|
|
286
292
|
self.backendConnector.intializeAgentHelpers();
|
|
287
293
|
|
|
@@ -342,6 +348,12 @@ Agent.prototype.initializeOpts = function (opts) {
|
|
|
342
348
|
if (self.opts.nodeName === undefined) {
|
|
343
349
|
self.opts.nodeName = process.env.APPDYNAMICS_AGENT_NODE_NAME;
|
|
344
350
|
}
|
|
351
|
+
if (self.opts.reuseNode === undefined) {
|
|
352
|
+
self.opts.reuseNode = process.env.APPDYNAMICS_AGENT_REUSE_NODE_NAME;
|
|
353
|
+
}
|
|
354
|
+
if (self.opts.reuseNodePrefix === undefined) {
|
|
355
|
+
self.opts.reuseNodePrefix = process.env.APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX;
|
|
356
|
+
}
|
|
345
357
|
if (self.opts.analyticsMaxSegmentSizeInBytes === undefined && process.env.APPDYNAMICS_ANALYTICS_MAX_SEGMENT_SIZE) {
|
|
346
358
|
self.opts.analyticsMaxSegmentSizeInBytes = parseInt(process.env.APPDYNAMICS_ANALYTICS_MAX_SEGMENT_SIZE, 10);
|
|
347
359
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const core_1 = require("@opentelemetry/core");
|
|
3
|
+
|
|
4
|
+
class AppdynamicsSpanExporter {
|
|
5
|
+
constructor(logger) {
|
|
6
|
+
this.logger = logger;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export(spans, resultCallback) {
|
|
10
|
+
return this._sendSpans(spans, resultCallback);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
shutdown() {
|
|
14
|
+
this._sendSpans([]);
|
|
15
|
+
return Promise.resolve();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
_exportInfo(span) {
|
|
19
|
+
return {
|
|
20
|
+
traceId: span.spanContext().traceId,
|
|
21
|
+
parentId: span.parentSpanId,
|
|
22
|
+
name: span.name,
|
|
23
|
+
id: span.spanContext().spanId,
|
|
24
|
+
kind: span.kind,
|
|
25
|
+
timestamp: core_1.hrTimeToMicroseconds(span.startTime),
|
|
26
|
+
duration: core_1.hrTimeToMicroseconds(span.duration),
|
|
27
|
+
attributes: span.attributes,
|
|
28
|
+
status: span.status,
|
|
29
|
+
events: span.events,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
_sendSpans(spans, done) {
|
|
34
|
+
for (const span of spans) {
|
|
35
|
+
this.logger.trace("Exporting span : " + JSON.stringify(this._exportInfo(span)));
|
|
36
|
+
}
|
|
37
|
+
if (done) {
|
|
38
|
+
return done({ code: core_1.ExportResultCode.SUCCESS });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports.AppdynamicsSpanExporter = AppdynamicsSpanExporter;
|
|
@@ -2,60 +2,91 @@
|
|
|
2
2
|
|
|
3
3
|
const opentelemetry_api = require('@opentelemetry/api');
|
|
4
4
|
const { ROOT_CONTEXT } = require('@opentelemetry/api');
|
|
5
|
-
const { BatchSpanProcessor,
|
|
6
|
-
const {
|
|
5
|
+
const { BatchSpanProcessor, BasicTracerProvider } = require('@opentelemetry/sdk-trace-base');
|
|
6
|
+
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-proto");
|
|
7
7
|
const { AsyncHooksContextManager, AsyncLocalStorageContextManager } = require("@opentelemetry/context-async-hooks");
|
|
8
|
-
const { ParentBasedSampler, AlwaysOnSampler } = require("@opentelemetry/core");
|
|
8
|
+
const { ParentBasedSampler, AlwaysOnSampler, TraceIdRatioBasedSampler } = require("@opentelemetry/core");
|
|
9
9
|
const { Resource } = require('@opentelemetry/resources');
|
|
10
10
|
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
|
|
11
|
+
const AppdynamicsSpanExporter = require('./appdynamics_span_exporter').AppdynamicsSpanExporter;
|
|
11
12
|
const url = require('url');
|
|
12
13
|
|
|
13
14
|
module.exports = TracerProvider;
|
|
14
15
|
|
|
15
16
|
function TracerProvider(logger) {
|
|
16
17
|
this.host = 'localhost';
|
|
17
|
-
this.port = '
|
|
18
|
+
this.port = '4318';
|
|
19
|
+
this.url = `http://${this.host}:${this.port}/v1/traces`;
|
|
18
20
|
this.ot_api = opentelemetry_api;
|
|
19
21
|
this.ROOT_CONTEXT = ROOT_CONTEXT;
|
|
20
22
|
this.logger = logger;
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
function getSamplerFromConfig(config) {
|
|
26
|
+
if(config.sampler && config.sampler.TraceIdRatioBasedSampler) {
|
|
27
|
+
const ratio = config.sampler.TraceIdRatioBasedSampler.Ratio || 1;
|
|
28
|
+
return new TraceIdRatioBasedSampler(ratio);
|
|
29
|
+
} else {
|
|
30
|
+
return new AlwaysOnSampler();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
23
34
|
TracerProvider.prototype.register = function(config) {
|
|
24
35
|
const provider = new BasicTracerProvider({
|
|
25
36
|
sampler: new ParentBasedSampler({
|
|
26
|
-
root:
|
|
37
|
+
root: getSamplerFromConfig(config.openTelemetry)
|
|
27
38
|
}),
|
|
28
39
|
resource: new Resource({
|
|
29
40
|
[SemanticResourceAttributes.SERVICE_NAME]: config.tierName,
|
|
30
|
-
|
|
31
|
-
"service.namespance": config.applicationName
|
|
41
|
+
[SemanticResourceAttributes.SERVICE_NAMESPACE]: config.applicationName
|
|
32
42
|
}),
|
|
33
43
|
});
|
|
34
44
|
|
|
35
45
|
// default collector configuration, can be overridden from agent config
|
|
36
|
-
const
|
|
46
|
+
const collectorOptions = {
|
|
47
|
+
url: this.url,
|
|
37
48
|
attributes: {'service.name': config.tierName,
|
|
38
49
|
'service.namespace': config.applicationName}
|
|
39
50
|
};
|
|
40
51
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
this.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
// batch export config, empty by default
|
|
53
|
+
const batchProcessorConfig = {};
|
|
54
|
+
|
|
55
|
+
if (config.openTelemetry) {
|
|
56
|
+
if (config.openTelemetry.collector) {
|
|
57
|
+
Object.assign(collectorOptions, config.openTelemetry.collector);
|
|
58
|
+
this.url = collectorOptions.url;
|
|
59
|
+
this.logger.debug('Exporter using config ' + JSON.stringify(collectorOptions));
|
|
60
|
+
try {
|
|
61
|
+
var urlObj = url.parse(this.url);
|
|
62
|
+
this.host = urlObj.hostname;
|
|
63
|
+
this.port = urlObj.port;
|
|
64
|
+
} catch (e) {
|
|
65
|
+
this.logger.error('Collector url must be in <host>:<port> format');
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
51
68
|
}
|
|
69
|
+
if(config.openTelemetry.exporter) {
|
|
70
|
+
if(config.openTelemetry.exporter.maxExportBatchSize) {
|
|
71
|
+
batchProcessorConfig.maxExportBatchSize = config.openTelemetry.exporter.maxExportBatchSize;
|
|
72
|
+
}
|
|
73
|
+
if(config.openTelemetry.exporter.maxQueueSize) {
|
|
74
|
+
batchProcessorConfig.maxQueueSize = config.openTelemetry.exporter.maxQueueSize;
|
|
75
|
+
}
|
|
76
|
+
if(config.openTelemetry.exporter.exportTimeoutMillis) {
|
|
77
|
+
batchProcessorConfig.exportTimeoutMillis = config.openTelemetry.exporter.exportTimeoutMillis;
|
|
78
|
+
}
|
|
79
|
+
if(config.openTelemetry.exporter.maxExportBatchSize) {
|
|
80
|
+
batchProcessorConfig.maxExportBatchSize = config.openTelemetry.exporter.maxExportBatchSize;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
this.logger.debug('Batch Processor config ' + JSON.stringify(batchProcessorConfig));
|
|
52
84
|
}
|
|
53
85
|
|
|
54
|
-
const exporter = new
|
|
55
|
-
provider.addSpanProcessor(new BatchSpanProcessor(exporter));
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
86
|
+
const exporter = new OTLPTraceExporter(collectorOptions);
|
|
87
|
+
provider.addSpanProcessor(new BatchSpanProcessor(exporter, batchProcessorConfig));
|
|
88
|
+
const appdExporter = new AppdynamicsSpanExporter(this.logger, batchProcessorConfig);
|
|
89
|
+
provider.addSpanProcessor(new BatchSpanProcessor(appdExporter, batchProcessorConfig));
|
|
59
90
|
|
|
60
91
|
const majorVersion = parseInt(process.versions.node.split('.')[0]);
|
|
61
92
|
const minorVersion = parseInt(process.versions.node.split('.')[1]);
|
|
@@ -67,4 +98,4 @@ TracerProvider.prototype.register = function(config) {
|
|
|
67
98
|
|
|
68
99
|
TracerProvider.prototype.getTracer = function(name) {
|
|
69
100
|
return opentelemetry_api.trace.getTracer(name);
|
|
70
|
-
};
|
|
101
|
+
};
|
|
@@ -163,6 +163,10 @@ LibagentConnector.prototype.startBusinessTransaction = function (entryPointType,
|
|
|
163
163
|
LibagentConnector.prototype.stopBusinessTransaction = function (transaction) {
|
|
164
164
|
var self = this;
|
|
165
165
|
|
|
166
|
+
if(!self.agent.profiler.isValidThreadId(transaction.threadId)) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
166
170
|
if (transaction.error) {
|
|
167
171
|
var name = self.protobufModel.extractErrorName(transaction.error);
|
|
168
172
|
if (!name) {
|
|
@@ -203,6 +207,9 @@ LibagentConnector.prototype.stopBusinessTransaction = function (transaction) {
|
|
|
203
207
|
|
|
204
208
|
LibagentConnector.prototype.startExitCall = function (transaction, exitCall) {
|
|
205
209
|
var self = this;
|
|
210
|
+
if(!self.agent.profiler.isValidThreadId(exitCall.threadId)) {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
206
213
|
|
|
207
214
|
var propertiesArray = [];
|
|
208
215
|
for (var propName in exitCall.properties) {
|
|
@@ -248,7 +255,10 @@ LibagentConnector.prototype.startExitCall = function (transaction, exitCall) {
|
|
|
248
255
|
|
|
249
256
|
LibagentConnector.prototype.disableResolutionForExitCall = function (exitCall) {
|
|
250
257
|
var self = this;
|
|
251
|
-
|
|
258
|
+
|
|
259
|
+
if(!self.agent.profiler.isValidThreadId(exitCall.threadId)) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
252
262
|
if (exitCall.exitCallGuid !== undefined) {
|
|
253
263
|
self.libagent.disableResolutionForExitCall(exitCall.exitCallGuid);
|
|
254
264
|
}
|
|
@@ -256,6 +266,9 @@ LibagentConnector.prototype.disableResolutionForExitCall = function (exitCall) {
|
|
|
256
266
|
|
|
257
267
|
LibagentConnector.prototype.getCorrelationHeader = function (exitCall) {
|
|
258
268
|
var self = this;
|
|
269
|
+
if(!self.agent.profiler.isValidThreadId(exitCall.threadId)) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
259
272
|
|
|
260
273
|
if (exitCall.exitCallGuid !== undefined) {
|
|
261
274
|
return self.libagent.getCorrelationHeader(exitCall.exitCallGuid);
|
|
@@ -264,6 +277,9 @@ LibagentConnector.prototype.getCorrelationHeader = function (exitCall) {
|
|
|
264
277
|
|
|
265
278
|
LibagentConnector.prototype.stopExitCall = function (exitCall, error) {
|
|
266
279
|
var self = this;
|
|
280
|
+
if(!self.agent.profiler.isValidThreadId(exitCall.threadId)) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
267
283
|
|
|
268
284
|
if (exitCall.exitCallGuid == undefined) {
|
|
269
285
|
return;
|
|
@@ -310,12 +326,20 @@ LibagentConnector.prototype.sendInstanceTrackerInfo = function (instanceCounts)
|
|
|
310
326
|
|
|
311
327
|
LibagentConnector.prototype.isSnapshotRequired = function (transaction) {
|
|
312
328
|
var self = this;
|
|
329
|
+
if(!self.agent.profiler.isValidThreadId(transaction.threadId)) {
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
|
|
313
333
|
return self.libagent.isSnapshotRequired(transaction.btGuid);
|
|
314
334
|
};
|
|
315
335
|
|
|
316
336
|
LibagentConnector.prototype.sendTransactionSnapshot = function (transaction, transactionSnapshot) {
|
|
317
337
|
var self = this;
|
|
318
338
|
|
|
339
|
+
if(!self.agent.profiler.isValidThreadId(transaction.threadId)) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
|
|
319
343
|
// fixup exit calls: set all required fields so that the protobuf message remains valid
|
|
320
344
|
if (transactionSnapshot.snapshot.exitCalls) {
|
|
321
345
|
transactionSnapshot.snapshot.exitCalls.forEach(function (item) {
|
|
@@ -418,6 +442,9 @@ LibagentConnector.prototype.getBusinessTransactionId = function (txnGuid) {
|
|
|
418
442
|
LibagentConnector.prototype.setHttpParamsInTransactionSnapshot = function (transaction) {
|
|
419
443
|
var self = this;
|
|
420
444
|
// url, methis and statusCode should be present for all http requests
|
|
445
|
+
if(!self.agent.profiler.isValidThreadId(transaction.threadId)) {
|
|
446
|
+
return false;
|
|
447
|
+
}
|
|
421
448
|
if (transaction.url && transaction.method && transaction.statusCode) {
|
|
422
449
|
return self.libagent.setHttpParamsInTransactionSnapshot(
|
|
423
450
|
transaction.btGuid, transaction.url, transaction.method, transaction.statusCode);
|
|
@@ -426,11 +453,17 @@ LibagentConnector.prototype.setHttpParamsInTransactionSnapshot = function (trans
|
|
|
426
453
|
|
|
427
454
|
LibagentConnector.prototype.addHttpDataToTransactionSnapshot = function (transaction, request) {
|
|
428
455
|
var self = this;
|
|
456
|
+
if(!self.agent.profiler.isValidThreadId(transaction.threadId)) {
|
|
457
|
+
return false;
|
|
458
|
+
}
|
|
429
459
|
return self.libagent.addHttpDataToTransactionSnapshot(transaction.btGuid, request);
|
|
430
460
|
};
|
|
431
461
|
|
|
432
462
|
LibagentConnector.prototype.setSnapshotRequired = function (transaction) {
|
|
433
463
|
var self = this;
|
|
464
|
+
if(!self.agent.profiler.isValidThreadId(transaction)) {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
434
467
|
self.libagent.setSnapshotRequired(transaction.btGuid);
|
|
435
468
|
};
|
|
436
469
|
|
|
@@ -535,7 +568,7 @@ LibagentConnector.prototype.initializeTimers = function () {
|
|
|
535
568
|
|
|
536
569
|
LibagentConnector.prototype.getEumCookieFields = function (transaction, shortForm) {
|
|
537
570
|
var self = this;
|
|
538
|
-
if (!transaction.ignore)
|
|
571
|
+
if (self.agent.profiler.isValidThreadId(transaction.threadId) && !transaction.ignore)
|
|
539
572
|
return self.libagent.getEumCookieFields(transaction.btGuid, shortForm);
|
|
540
573
|
else
|
|
541
574
|
return {};
|
|
@@ -545,6 +578,11 @@ LibagentConnector.prototype.setupEum = function (agent) {
|
|
|
545
578
|
var libAgentConnector = this;
|
|
546
579
|
agent.eum.eumCookie.prototype.setFieldValues = function () {
|
|
547
580
|
var self = this;
|
|
581
|
+
|
|
582
|
+
if(!agent.profiler.isValidThreadId(self.transaction.threadId)) {
|
|
583
|
+
return false;
|
|
584
|
+
}
|
|
585
|
+
|
|
548
586
|
var shortForm = self.keyForm == 'short';
|
|
549
587
|
var fields = libAgentConnector.getEumCookieFields(self.transaction, shortForm);
|
|
550
588
|
if (fields) {
|
|
@@ -70,6 +70,7 @@ HttpExitProbe.prototype.attach = function (obj, moduleName) {
|
|
|
70
70
|
var isRepeatForHttps = false;
|
|
71
71
|
|
|
72
72
|
var [input, options] = args;
|
|
73
|
+
|
|
73
74
|
if (typeof(input) != 'string' && !(input instanceof url.URL)) {
|
|
74
75
|
options = input;
|
|
75
76
|
input = null;
|
|
@@ -78,6 +79,13 @@ HttpExitProbe.prototype.attach = function (obj, moduleName) {
|
|
|
78
79
|
args[1] = options;
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
if(typeof(options) == 'function') {
|
|
83
|
+
args[2] = options;
|
|
84
|
+
options = {};
|
|
85
|
+
args[1] = options;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
81
89
|
if (moduleName === 'https') {
|
|
82
90
|
options.__appdIsHttps = true;
|
|
83
91
|
}
|
|
@@ -204,11 +212,12 @@ HttpExitProbe.prototype.attach = function (obj, moduleName) {
|
|
|
204
212
|
},
|
|
205
213
|
function (obj, args, ret, locals) {
|
|
206
214
|
var [input, options] = args;
|
|
215
|
+
|
|
207
216
|
if (typeof(input) != 'string' && !(input instanceof url.URL)) {
|
|
208
217
|
options = input;
|
|
209
218
|
input = null;
|
|
210
219
|
}
|
|
211
|
-
|
|
220
|
+
|
|
212
221
|
options = options || {};
|
|
213
222
|
if (!options.appdIgnore && (moduleName != 'http' || (moduleName === 'http' && !options.__appdIsHttps))) {
|
|
214
223
|
if (locals.parentSpan) {
|
|
@@ -261,7 +270,6 @@ HttpExitProbe.prototype.attach = function (obj, moduleName) {
|
|
|
261
270
|
httpParser = socket.parser;
|
|
262
271
|
var kOnHeadersComplete = HTTPParser.kOnHeadersComplete | 0;
|
|
263
272
|
httpParserMethod = kOnHeadersComplete ? kOnHeadersComplete : 'onHeadersComplete';
|
|
264
|
-
|
|
265
273
|
var socketCloseHandler = function () {
|
|
266
274
|
socket.removeListener('close', socketCloseHandler);
|
|
267
275
|
if (socket.__appdynamicsCleanup) {
|
|
@@ -50,26 +50,28 @@ function getAbsoluteUrl(requestUrl, headers) {
|
|
|
50
50
|
|
|
51
51
|
function getIncomingRequestAttributes(request) {
|
|
52
52
|
const attributes = {};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
53
|
+
if (request) {
|
|
54
|
+
const headers = request.headers;
|
|
55
|
+
const userAgent = headers && headers['user-agent'];
|
|
56
|
+
const method = request.method || 'GET';
|
|
57
|
+
const httpVersion = request.httpVersion;
|
|
58
|
+
const requestUrl = request.url && url.parse(request.url);
|
|
59
|
+
const host = requestUrl && requestUrl.host ? requestUrl.host : headers && headers.host ? headers.host : 'localhost';
|
|
60
|
+
attributes[SemanticAttributes.HTTP_URL] = getAbsoluteUrl(requestUrl, headers);
|
|
61
|
+
attributes[SemanticAttributes.HTTP_HOST] = host;
|
|
62
|
+
attributes[SemanticAttributes.HTTP_METHOD] = method;
|
|
63
|
+
|
|
64
|
+
if(requestUrl) {
|
|
65
|
+
attributes[SemanticAttributes.HTTP_TARGET] = requestUrl.pathname || '/';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if(userAgent) {
|
|
69
|
+
attributes[SemanticAttributes.HTTP_USER_AGENT] = userAgent;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if(httpVersion) {
|
|
73
|
+
attributes[SemanticAttributes.HTTP_FLAVOR] = httpVersion;
|
|
74
|
+
}
|
|
73
75
|
}
|
|
74
76
|
return attributes;
|
|
75
77
|
}
|
|
@@ -83,31 +85,33 @@ function getIncomingRequestAttributesOnResponse(response) {
|
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
function getOutgoingRequestAttributes(parsedRequest, headers) {
|
|
86
|
-
const method = parsedRequest.method || 'GET';
|
|
87
|
-
const userAgent = headers ? headers['user-agent'] : null;
|
|
88
|
-
|
|
89
88
|
const attributes = {};
|
|
90
|
-
|
|
91
|
-
attributes[SemanticAttributes.HTTP_METHOD] = method;
|
|
92
|
-
attributes[SemanticAttributes.HTTP_TARGET] = parsedRequest.path || '/';
|
|
93
|
-
|
|
89
|
+
const userAgent = headers && headers['user-agent'] || undefined;
|
|
94
90
|
if(userAgent) {
|
|
95
91
|
attributes[SemanticAttributes.HTTP_USER_AGENT] = userAgent;
|
|
96
92
|
}
|
|
93
|
+
|
|
94
|
+
attributes[SemanticAttributes.HTTP_METHOD] = parsedRequest && parsedRequest.method || 'GET';
|
|
95
|
+
attributes[SemanticAttributes.HTTP_TARGET] = parsedRequest && parsedRequest.path || '/';
|
|
96
|
+
|
|
97
|
+
attributes[SemanticAttributes.HTTP_URL] = getAbsoluteUrl(parsedRequest, headers);
|
|
98
|
+
|
|
97
99
|
return attributes;
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
function getOutgoingRequestAttributesOnResponse(response, hostname) {
|
|
101
103
|
const attributes = {};
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
104
|
+
if (response) {
|
|
105
|
+
const statusCode = response.statusCode;
|
|
106
|
+
const httpVersion = response.httpVersion;
|
|
107
|
+
const socket = response.socket;
|
|
108
|
+
const remotePort = socket && socket.remotePort || 0;
|
|
109
|
+
attributes[SemanticAttributes.HTTP_HOST] = `${hostname}:${remotePort}`;
|
|
110
|
+
attributes[SemanticAttributes.HTTP_STATUS_CODE] = statusCode;
|
|
111
|
+
|
|
112
|
+
if(httpVersion) {
|
|
113
|
+
attributes[SemanticAttributes.HTTP_FLAVOR] = httpVersion;
|
|
114
|
+
}
|
|
111
115
|
}
|
|
112
116
|
return attributes;
|
|
113
117
|
}
|
|
@@ -99,6 +99,8 @@ MongodbProbe.prototype.attach = function (obj) {
|
|
|
99
99
|
var cid = event.connectionId;
|
|
100
100
|
if (typeof (cid) === 'string')
|
|
101
101
|
serverPool = [cid];
|
|
102
|
+
else if (typeof (cid) === 'number')
|
|
103
|
+
serverPool = [event.address];
|
|
102
104
|
else
|
|
103
105
|
serverPool = [cid.host + ':' + cid.port];
|
|
104
106
|
}
|
|
@@ -146,6 +148,7 @@ MongodbProbe.prototype.attach = function (obj) {
|
|
|
146
148
|
});
|
|
147
149
|
|
|
148
150
|
supportedCommands.forEach(function (command) {
|
|
151
|
+
proxy.before(obj.Collection.prototype, command, withAPMBeforeHandler);
|
|
149
152
|
proxy.before(obj.Server.prototype, command, withAPMBeforeHandler);
|
|
150
153
|
proxy.before(obj.ReplSet.prototype, command, withAPMBeforeHandler);
|
|
151
154
|
});
|
package/lib/profiler/profiler.js
CHANGED
|
@@ -179,6 +179,11 @@ Profiler.prototype.endTransaction = function (time, transaction) {
|
|
|
179
179
|
self._endTransaction(time, transaction);
|
|
180
180
|
};
|
|
181
181
|
|
|
182
|
+
Profiler.prototype.isValidThreadId = function(threadId) {
|
|
183
|
+
var self = this;
|
|
184
|
+
return (threadId && self.transactions[threadId]);
|
|
185
|
+
};
|
|
186
|
+
|
|
182
187
|
Profiler.prototype._endTransaction = function (time, transaction) {
|
|
183
188
|
var self = this;
|
|
184
189
|
|
|
@@ -228,7 +233,8 @@ Profiler.prototype.__getNextSequenceInfo = function (transaction) {
|
|
|
228
233
|
};
|
|
229
234
|
|
|
230
235
|
Profiler.prototype.createExitCall = function (time, exitCallInfo) {
|
|
231
|
-
|
|
236
|
+
var self = this;
|
|
237
|
+
return self.agent.backendConnector.createExitCall(time, exitCallInfo);
|
|
232
238
|
};
|
|
233
239
|
|
|
234
240
|
Profiler.prototype.addExitCall = function (time, exitCall, error) {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
var path = require('path');
|
|
2
|
+
|
|
3
|
+
const MAX_ITEMS_PER_GROUP = 1024;
|
|
4
|
+
|
|
5
|
+
exports.LibraryMetadata = LibraryMetadata;
|
|
6
|
+
function LibraryMetadata(agent) {
|
|
7
|
+
var self = this;
|
|
8
|
+
self.agent = agent;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
LibraryMetadata.prototype.init = function() {
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
LibraryMetadata.prototype.getMetadata = function() {
|
|
15
|
+
var self = this;
|
|
16
|
+
if(!self.metadataCache) {
|
|
17
|
+
self.metadataCache = self._getMetadata();
|
|
18
|
+
}
|
|
19
|
+
return self.metadataCache;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
LibraryMetadata.prototype._getJson = function()
|
|
23
|
+
{
|
|
24
|
+
var rootPath = require('path').resolve('./');
|
|
25
|
+
return require(path.join(rootPath, './package-lock.json'));
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
LibraryMetadata.prototype._getMetadata = function() {
|
|
29
|
+
var self = this;
|
|
30
|
+
try {
|
|
31
|
+
var pkjson = self._getJson();
|
|
32
|
+
var metadataCache = [];
|
|
33
|
+
var cacheGroup = [];
|
|
34
|
+
var itemCount = 0;
|
|
35
|
+
for (var pkg in pkjson.dependencies) {
|
|
36
|
+
if(itemCount == MAX_ITEMS_PER_GROUP) {
|
|
37
|
+
metadataCache.push(cacheGroup);
|
|
38
|
+
cacheGroup = [];
|
|
39
|
+
itemCount = 0;
|
|
40
|
+
}
|
|
41
|
+
cacheGroup.push({
|
|
42
|
+
name: pkg,
|
|
43
|
+
version: pkjson.dependencies[pkg].version
|
|
44
|
+
});
|
|
45
|
+
itemCount = itemCount + 1;
|
|
46
|
+
}
|
|
47
|
+
} catch(error) {
|
|
48
|
+
self.agent.logger.warn('Error reading package metadata ' + error);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if(cacheGroup.length) {
|
|
52
|
+
metadataCache.push(cacheGroup);
|
|
53
|
+
}
|
|
54
|
+
return metadataCache;
|
|
55
|
+
};
|
|
56
|
+
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
const http = require('http');
|
|
2
|
+
const https = require('https');
|
|
3
|
+
const url = require('url');
|
|
4
|
+
const HttpsProxyAgent = require('https-proxy-agent');
|
|
5
|
+
|
|
6
|
+
const LibraryMetadata = require('./library_metadata').LibraryMetadata;
|
|
7
|
+
const MessageSender = require('../libagent/message-sender').MessageSender;
|
|
8
|
+
|
|
9
|
+
const AUTH_PATH = "/auth/v1/oauth/token";
|
|
10
|
+
const EVENT_PATH = "/argento-agent/v1/report";
|
|
11
|
+
const REGISTER_PATH = "/argento-agent/v1/management";
|
|
12
|
+
|
|
13
|
+
const MIN_TIMER = 60 * 1000;
|
|
14
|
+
const DAY_TIMER = 24 * 60 * 60 * 1000;
|
|
15
|
+
const RETRY_THRESHOLD = 2;
|
|
16
|
+
const TIMEOUT = 1000;
|
|
17
|
+
|
|
18
|
+
exports.SecureApp = SecureApp;
|
|
19
|
+
function SecureApp() {
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
SecureApp.prototype.init = function(agent) {
|
|
23
|
+
var self = this;
|
|
24
|
+
self.agent = agent;
|
|
25
|
+
self.libraryMetadata = new LibraryMetadata(agent);
|
|
26
|
+
if(!process.env.SKIP_AUTH_FOR_TESTS) {
|
|
27
|
+
self.authTimerId = new MessageSender(self.agent, 10 * 1000, MIN_TIMER * 9, function () {
|
|
28
|
+
self.authToken();
|
|
29
|
+
});
|
|
30
|
+
} else {
|
|
31
|
+
self.agent.logger.debug('Secure App skipping auth as SKIP_AUTH_FOR_TESTS is ' + process.env.SKIP_AUTH_FOR_TESTS);
|
|
32
|
+
self.regTimerId = new MessageSender(self.agent, 10 * 1000, MIN_TIMER, function () {
|
|
33
|
+
self.register();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
self.httpModule = (self.agent.opts.controllerSslEnabled) ? https : http;
|
|
37
|
+
self.libraryMetadata.init();
|
|
38
|
+
self.agent.logger.debug('Secure App module initialized');
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
SecureApp.prototype._sendRequestWithRetry = function(options, data, cb)
|
|
42
|
+
{
|
|
43
|
+
var self = this;
|
|
44
|
+
options.currentRetryAttempt = 0;
|
|
45
|
+
self._sendRequest(options, data, cb);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
SecureApp.prototype._retryRequest = function(options, data, cb)
|
|
49
|
+
{
|
|
50
|
+
var self = this;
|
|
51
|
+
if (options.currentRetryAttempt === RETRY_THRESHOLD) {
|
|
52
|
+
return cb(null, new Error('Retry Threshold Reached'));
|
|
53
|
+
}
|
|
54
|
+
options.currentRetryAttempt++;
|
|
55
|
+
self.agent.logger.trace('SecureApp._retryRequest: Retry attempt ' + options.currentRetryAttempt + ' ' + options.path);
|
|
56
|
+
setTimeout(() => {
|
|
57
|
+
self._sendRequest(options, data, cb);
|
|
58
|
+
}, TIMEOUT);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
SecureApp.prototype._sendRequest = function(options, data, cb) {
|
|
62
|
+
var self = this;
|
|
63
|
+
self.agent.logger.trace('SecureApp._sendRequest: ' + options.path + " Data: " + ((options.headers['Content-Type'] != 'application/json') ?
|
|
64
|
+
data.length.toString() : JSON.stringify(data).length.toString()));
|
|
65
|
+
|
|
66
|
+
var request = self.httpModule.request(options, function(response) {
|
|
67
|
+
const chunks = [];
|
|
68
|
+
response.on('data', data_chunk => chunks.push(data_chunk));
|
|
69
|
+
response.on('end', () => {
|
|
70
|
+
var statusCode = response.statusCode | 0;
|
|
71
|
+
// don't retry on http 413 (payload too large)
|
|
72
|
+
if(statusCode == 413) {
|
|
73
|
+
self.agent.logger.warn('Secure App Http Request failed ' + ' statusCode ' + statusCode);
|
|
74
|
+
return cb(null, new Error('Http Payload too large'));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (statusCode != 200 || response.is_error) {
|
|
78
|
+
self.agent.logger.info('Secure App Http Request failed ' + ' statusCode ' + statusCode + ' is_error ' + response.is_error);
|
|
79
|
+
return self._retryRequest(options, data, cb);
|
|
80
|
+
}
|
|
81
|
+
let body = Buffer.concat(chunks);
|
|
82
|
+
cb(body, null);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
request.on('error', function(error) {
|
|
87
|
+
self.agent.logger.info('Secure app http request error : ' + error);
|
|
88
|
+
return self._retryRequest(options, data, cb);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
request.end(data);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
SecureApp.prototype._requestHeaders = function(requestOptions) {
|
|
95
|
+
var self = this;
|
|
96
|
+
requestOptions.headers['Authorization'] = `Bearer ${self.accessToken}`;
|
|
97
|
+
requestOptions.headers['User-Agent'] = "NodeJs";
|
|
98
|
+
requestOptions.headers['appdynamics-agent-applicationName'] = self.agent.opts.applicationName;
|
|
99
|
+
requestOptions.headers['appdynamics-agent-tierName'] = self.agent.opts.tierName;
|
|
100
|
+
requestOptions.headers['appdynamics-agent-nodeName'] = self.agent.opts.nodeName;
|
|
101
|
+
requestOptions.headers['appdynamics-agent-accountName'] = 'singularity-agent@' + self.agent.opts.accountName;
|
|
102
|
+
if (self.uuid) {
|
|
103
|
+
requestOptions.headers['appdynamics-agent-nodeUUID'] = self.uuid;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
SecureApp.prototype._requestOptions = function(path, length, type) {
|
|
108
|
+
var self = this;
|
|
109
|
+
var requestOptions = {
|
|
110
|
+
'method': 'POST',
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
requestOptions.headers = {
|
|
114
|
+
'Content-Length': length,
|
|
115
|
+
'Content-Type': type
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
if (self.agent.opts.certificateFile) {
|
|
119
|
+
requestOptions['ca'] = self.agent.opts.certificateFile;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if(process.env.CONTROLLER_HOST_TEST) {
|
|
123
|
+
self.agent.logger.debug('Secure App using controller hostname CONTROLLER_HOST_TEST: ' + process.env.CONTROLLER_HOST_TEST);
|
|
124
|
+
requestOptions['hostname'] = process.env.CONTROLLER_HOST_TEST;
|
|
125
|
+
} else {
|
|
126
|
+
requestOptions['hostname'] = self.agent.opts.controllerHostName;
|
|
127
|
+
}
|
|
128
|
+
if(process.env.CONTROLLER_PORT_TEST) {
|
|
129
|
+
self.agent.logger.debug('Secure App using controller port CONTROLLER_PORT_TEST: ' + process.env.CONTROLLER_PORT_TEST);
|
|
130
|
+
requestOptions['port'] = process.env.CONTROLLER_PORT_TEST;
|
|
131
|
+
} else {
|
|
132
|
+
requestOptions['port'] = self.agent.opts.controllerPort;
|
|
133
|
+
}
|
|
134
|
+
requestOptions['path'] = path;
|
|
135
|
+
|
|
136
|
+
var proxy = {
|
|
137
|
+
hostName: self.agent.opts.proxyHost,
|
|
138
|
+
port: self.agent.opts.proxyPort,
|
|
139
|
+
userName: self.agent.opts.proxyUser,
|
|
140
|
+
password: ""
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
if (self.agent.opts.proxyPasswordFile) {
|
|
144
|
+
var fs = require('fs');
|
|
145
|
+
proxy.password = (fs.readFileSync(self.agent.opts.proxyPasswordFile, 'utf-8')).trim();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (proxy.hostName) {
|
|
149
|
+
self.agent.logger.debug('Secure App using proxy');
|
|
150
|
+
var ro = requestOptions;
|
|
151
|
+
var proxyAuth = proxy.userName && proxy.password && Buffer.from(`${proxy.userName}:${proxy.password}`).toString('base64');
|
|
152
|
+
|
|
153
|
+
if (self.agent.opts.controllerSslEnabled) {
|
|
154
|
+
var proxyUrl = `http://${proxy.hostName}:${proxy.port}`;
|
|
155
|
+
var proxyOpts = url.parse(proxyUrl);
|
|
156
|
+
if (proxyAuth) {
|
|
157
|
+
proxyOpts.headers = {
|
|
158
|
+
'Proxy-Authentication': `Basic ${proxyAuth}`
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
var agent = new HttpsProxyAgent(proxyOpts);
|
|
162
|
+
ro['agent'] = agent;
|
|
163
|
+
} else {
|
|
164
|
+
ro['path'] = `http://${ro.hostname}:${ro.port}${ro.path}`;
|
|
165
|
+
ro['headers']['Host'] = `${ro.hostname}:${ro.port}`;
|
|
166
|
+
ro['hostname'] = proxy.hostName;
|
|
167
|
+
ro['port'] = proxy.port;
|
|
168
|
+
if (proxyAuth) {
|
|
169
|
+
ro['headers']['Proxy-Authorization'] = `Basic ${proxyAuth}`;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return requestOptions;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
SecureApp.prototype._initializeTimers = function() {
|
|
177
|
+
var self = this;
|
|
178
|
+
if (self.timersInitialized) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
self.timersInitialized = true;
|
|
182
|
+
|
|
183
|
+
self.reportEventTimerId = new MessageSender(self.agent, 10 * 1000, DAY_TIMER, function () {
|
|
184
|
+
self.reportEvents();
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
SecureApp.prototype.authenticate = function(grantType) {
|
|
189
|
+
var self = this;
|
|
190
|
+
var postData = "password=" + self.agent.opts.accountAccessKey +
|
|
191
|
+
"&username=" + 'singularity-agent@' + self.agent.opts.accountName +
|
|
192
|
+
"&grant_type=" + grantType;
|
|
193
|
+
|
|
194
|
+
if(grantType == 'refresh_token') {
|
|
195
|
+
postData += '&refresh_token=' + self.refreshToken;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
var requestOptions = self._requestOptions(AUTH_PATH, postData.length.toString(),
|
|
199
|
+
"application/x-www-form-urlencoded; charset=utf-8");
|
|
200
|
+
|
|
201
|
+
self._sendRequestWithRetry(requestOptions, postData, function(body, error) {
|
|
202
|
+
if (error != null) {
|
|
203
|
+
self.agent.logger.info('Secure App authentication failed');
|
|
204
|
+
self.accessToken = null;
|
|
205
|
+
self.refreshToken = null;
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
try {
|
|
210
|
+
body = JSON.parse(body);
|
|
211
|
+
if (!self.accessToken) {
|
|
212
|
+
self.regTimerId = new MessageSender(self.agent, 10 * 1000, MIN_TIMER, function () {
|
|
213
|
+
self.register();
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
self.accessToken = body.access_token;
|
|
218
|
+
self.refreshToken = body.refresh_token;
|
|
219
|
+
|
|
220
|
+
self.agent.logger.debug('Secure App module authenticated');
|
|
221
|
+
} catch(err) {
|
|
222
|
+
self.accessToken = null;
|
|
223
|
+
self.refreshToken = null;
|
|
224
|
+
self.agent.logger.warn('Failed to parse Secure app authentication response ' + err);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
SecureApp.prototype.authToken = function() {
|
|
230
|
+
var self = this;
|
|
231
|
+
if(!self.accessToken) {
|
|
232
|
+
self.authenticate("password");
|
|
233
|
+
} else {
|
|
234
|
+
self.authenticate("refresh_token");
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
SecureApp.prototype.register = function() {
|
|
239
|
+
var self = this;
|
|
240
|
+
var postData = JSON.stringify({
|
|
241
|
+
"message_type": 0,
|
|
242
|
+
"app": self.agent.opts.applicationName,
|
|
243
|
+
"tier": self.agent.opts.tierName,
|
|
244
|
+
"node": self.agent.opts.nodeName,
|
|
245
|
+
"access_key": self.agent.opts.accountAccessKey,
|
|
246
|
+
"account_name": self.agent.opts.accountName,
|
|
247
|
+
"file_name": "",
|
|
248
|
+
"epoch_msec": 0,
|
|
249
|
+
"force": false,
|
|
250
|
+
"version": 1,
|
|
251
|
+
"is_started": true,
|
|
252
|
+
"is_enabled": true,
|
|
253
|
+
"agent_type": "NodeJs",
|
|
254
|
+
"agent_build_version": ""
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
var requestOptions = self._requestOptions(REGISTER_PATH, postData.length.toString(), "application/json");
|
|
258
|
+
self._requestHeaders(requestOptions);
|
|
259
|
+
|
|
260
|
+
self._sendRequestWithRetry(requestOptions, postData, function(body, error) {
|
|
261
|
+
if (error != null) {
|
|
262
|
+
self.agent.logger.info('Secure App module registeration failed');
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
try {
|
|
267
|
+
body = JSON.parse(body);
|
|
268
|
+
self.uuid = body.node_uuid;
|
|
269
|
+
self._initializeTimers();
|
|
270
|
+
self.agent.logger.debug('Secure App module registered');
|
|
271
|
+
} catch(err) {
|
|
272
|
+
self.agent.logger.warn('Failed to parse Secure app registration response ' + err);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
SecureApp.prototype.sendVulnerabilityEvent = function() {
|
|
278
|
+
var self = this;
|
|
279
|
+
if(!self.vulnerabilityEvent) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
self.vulnerabilityEvent.forEach((data, index) => {
|
|
284
|
+
var isDone = index == self.vulnerabilityEvent.length - 1 ? true : false;
|
|
285
|
+
var postData = JSON.stringify({
|
|
286
|
+
"id": 0,
|
|
287
|
+
"is_done": isDone,
|
|
288
|
+
"fragment_index": index,
|
|
289
|
+
"max_fragments": self.vulnerabilityEvent.length,
|
|
290
|
+
"nodejs_report_component_vulnerability_list": data
|
|
291
|
+
});
|
|
292
|
+
var requestOptions = self._requestOptions(EVENT_PATH, postData.length.toString(), "application/json");
|
|
293
|
+
self._requestHeaders(requestOptions);
|
|
294
|
+
|
|
295
|
+
self._sendRequestWithRetry(requestOptions, postData, function(body, error) {
|
|
296
|
+
if (error != null) {
|
|
297
|
+
self.agent.logger.info('Secure App module vulnerability event failed');
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
self.agent.logger.info('Secure App module vulnerability event sent fragment');
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
SecureApp.prototype.reportEvents = function() {
|
|
306
|
+
var self = this;
|
|
307
|
+
if(!self.vulnerabilityEvent) {
|
|
308
|
+
self.vulnerabilityEvent = self.libraryMetadata.getMetadata();
|
|
309
|
+
}
|
|
310
|
+
self.sendVulnerabilityEvent();
|
|
311
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appdynamics",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.7.0",
|
|
4
4
|
"description": "Performance Profiler and Monitor",
|
|
5
5
|
"author": "AppDynamics, Inc.",
|
|
6
6
|
"homepage": "https://www.appdynamics.com",
|
|
@@ -34,18 +34,20 @@
|
|
|
34
34
|
"n": "^6.7.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@opentelemetry/api": "
|
|
38
|
-
"@opentelemetry/
|
|
39
|
-
"@opentelemetry/
|
|
40
|
-
"@opentelemetry/
|
|
41
|
-
"@opentelemetry/
|
|
37
|
+
"@opentelemetry/api": "~1.0.3",
|
|
38
|
+
"@opentelemetry/context-async-hooks": "~1.0.1",
|
|
39
|
+
"@opentelemetry/core": "~1.0.1",
|
|
40
|
+
"@opentelemetry/exporter-trace-otlp-proto": "~0.27.0",
|
|
41
|
+
"@opentelemetry/resources": "~1.0.1",
|
|
42
|
+
"@opentelemetry/sdk-trace-base": "~1.0.1",
|
|
43
|
+
"@opentelemetry/semantic-conventions": "~1.0.1",
|
|
42
44
|
"cls-hooked": "4.2.2",
|
|
43
|
-
"
|
|
44
|
-
"shelljs": "^0.8.5",
|
|
45
|
+
"https-proxy-agent": "^5.0.0",
|
|
45
46
|
"uuid": "^8.3.2",
|
|
46
|
-
"
|
|
47
|
-
"appdynamics-
|
|
48
|
-
"appdynamics-
|
|
47
|
+
"y18n": "^5.0.8",
|
|
48
|
+
"appdynamics-libagent-napi": "https://cdn.appdynamics.com/packages/nodejs/22.7.0.0/appdynamics-libagent-napi-node.tgz",
|
|
49
|
+
"appdynamics-native": "https://cdn.appdynamics.com/packages/nodejs/22.7.0.0/appdynamics-native-node.tgz",
|
|
50
|
+
"appdynamics-protobuf": "https://cdn.appdynamics.com/packages/nodejs/22.7.0.0/appdynamics-protobuf-node.tgz"
|
|
49
51
|
},
|
|
50
52
|
"engines": {
|
|
51
53
|
"node": ">=12 <=v16.*"
|
package/packageBck.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appdynamics",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.7.0",
|
|
4
4
|
"description": "Performance Profiler and Monitor",
|
|
5
5
|
"author": "AppDynamics, Inc.",
|
|
6
6
|
"homepage": "https://www.appdynamics.com",
|
|
@@ -34,18 +34,20 @@
|
|
|
34
34
|
"n": "^6.7.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@opentelemetry/api": "
|
|
38
|
-
"@opentelemetry/
|
|
39
|
-
"@opentelemetry/
|
|
40
|
-
"@opentelemetry/
|
|
41
|
-
"@opentelemetry/
|
|
37
|
+
"@opentelemetry/api": "~1.0.3",
|
|
38
|
+
"@opentelemetry/context-async-hooks": "~1.0.1",
|
|
39
|
+
"@opentelemetry/core": "~1.0.1",
|
|
40
|
+
"@opentelemetry/exporter-trace-otlp-proto": "~0.27.0",
|
|
41
|
+
"@opentelemetry/resources": "~1.0.1",
|
|
42
|
+
"@opentelemetry/sdk-trace-base": "~1.0.1",
|
|
43
|
+
"@opentelemetry/semantic-conventions": "~1.0.1",
|
|
42
44
|
"cls-hooked": "4.2.2",
|
|
43
|
-
"
|
|
44
|
-
"shelljs": "^0.8.5",
|
|
45
|
+
"https-proxy-agent": "^5.0.0",
|
|
45
46
|
"uuid": "^8.3.2",
|
|
46
|
-
"
|
|
47
|
-
"appdynamics-
|
|
48
|
-
"appdynamics-
|
|
47
|
+
"y18n": "^5.0.8",
|
|
48
|
+
"appdynamics-libagent-napi": "https://cdn.appdynamics.com/packages/nodejs/22.7.0.0/appdynamics-libagent-napi-node.tgz",
|
|
49
|
+
"appdynamics-native": "https://cdn.appdynamics.com/packages/nodejs/22.7.0.0/appdynamics-native-node.tgz",
|
|
50
|
+
"appdynamics-protobuf": "https://cdn.appdynamics.com/packages/nodejs/22.7.0.0/appdynamics-protobuf-node.tgz"
|
|
49
51
|
},
|
|
50
52
|
"engines": {
|
|
51
53
|
"node": ">=12 <=v16.*"
|