appdynamics 21.8.0 → 22.3.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/README.md +1 -1
- package/appdynamics_version.json +2 -2
- package/lib/core/agent.js +21 -44
- package/lib/core/appDProxy.js +12 -12
- package/lib/core/logger.js +27 -79
- package/lib/core/opentelemetry-tracer.js +89 -0
- package/lib/libagent/libagent-connector.js +5 -47
- package/lib/libagent/libagent.js +2 -3
- package/lib/libagent/transaction-sender.js +15 -16
- package/lib/libagent/transactions/transaction-reporter.js +0 -5
- package/lib/{libagent/metrics → metrics}/metric.js +4 -1
- package/lib/metrics/metrics-manager.js +4 -3
- package/lib/probes/apollo-entry-probe.js +69 -0
- package/lib/probes/cluster-probe.js +1 -1
- package/lib/probes/couchbase-probe.js +19 -0
- package/lib/probes/grpc-exit-probe.js +1 -1
- package/lib/probes/http-common.js +97 -0
- package/lib/probes/http-entry-probe.js +42 -122
- package/lib/probes/http-exit-probe.js +112 -48
- package/lib/probes/http-ot-utils.js +117 -0
- package/lib/probes/http-probe.js +14 -7
- package/lib/probes/http2-entry-probe.js +1 -7
- package/lib/probes/http2-exit-probe.js +4 -7
- package/lib/probes/ioredis-probe.js +2 -2
- package/lib/probes/mongodb-probe.js +200 -113
- package/lib/probes/rabbitmq-entry-probe.js +184 -0
- package/lib/probes/rabbitmq-exit-probe.js +108 -0
- package/lib/probes/rabbitmq-probe.js +76 -0
- package/lib/process/process-scanner.js +2 -2
- package/lib/profiler/profiler.js +6 -2
- package/lib/profiler/time-promise.js +0 -3
- package/lib/proxy/protobuf-model.js +0 -264
- package/lib/transactions/correlation.js +1 -20
- package/lib/transactions/eum.js +2 -34
- package/lib/utility.js +20 -1
- package/package.json +15 -13
- package/packageBck.json +15 -13
- package/lib/libproxy/instance-info-sender.js +0 -41
- package/lib/libproxy/libproxy.js +0 -204
- package/lib/libproxy/metric.js +0 -109
- package/lib/libproxy/proxy-launcher.js +0 -308
- package/lib/libproxy/proxy-transport.js +0 -634
- package/lib/libproxy/transaction-reporter.js +0 -168
- package/lib/proxy/backend-config.js +0 -488
- package/lib/transactions/analytics-reporter.js +0 -187
- package/lib/transactions/config-manager.js +0 -87
- package/lib/transactions/correlation-header.js +0 -495
- package/lib/transactions/data-collectors.js +0 -95
- package/lib/transactions/sep-config.js +0 -66
- package/lib/transactions/transaction-naming.js +0 -231
- package/lib/transactions/transaction-registry.js +0 -156
- package/lib/transactions/transaction-rules.js +0 -173
- package/postInstallScript.js +0 -33
package/README.md
CHANGED
|
@@ -56,4 +56,4 @@ require('appdynamics').profile({
|
|
|
56
56
|
|
|
57
57
|
For more information, see [Install the Node.js Agent](https://docs.appdynamics.com/display/PRO21/Install+the+Node.js+Agent) and [Application Monitoring](https://docs.appdynamics.com/display/PRO21/Application+Monitoring).
|
|
58
58
|
|
|
59
|
-
Copyright (c) AppDynamics, Inc. 2021 CA. All rights reserved.
|
|
59
|
+
Copyright (c) AppDynamics, Inc. 2021 CA. All rights reserved.
|
package/appdynamics_version.json
CHANGED
package/lib/core/agent.js
CHANGED
|
@@ -12,14 +12,12 @@ var path = require('path');
|
|
|
12
12
|
var EventEmitter = require('events').EventEmitter;
|
|
13
13
|
var crypto = require('crypto');
|
|
14
14
|
|
|
15
|
-
// modules used by both proxy and libagent
|
|
16
15
|
var Context = require('./context').Context;
|
|
17
16
|
var Logger = require('./logger').Logger;
|
|
18
17
|
var Timers = require('./timers').Timers;
|
|
19
18
|
var System = require('./system').System;
|
|
20
19
|
var AppDProxy = require('./appDProxy').AppDProxy;
|
|
21
20
|
var Thread = require('./thread').Thread;
|
|
22
|
-
var AnalyticsReporter = require('../transactions/analytics-reporter').AnalyticsReporter;
|
|
23
21
|
var MetricsManager = require('../metrics/metrics-manager').MetricsManager;
|
|
24
22
|
var ProcessInfo = require('../process/process-info').ProcessInfo;
|
|
25
23
|
var ProcessScanner = require('../process/process-scanner').ProcessScanner;
|
|
@@ -27,24 +25,17 @@ var ProcessStats = require('../process/process-stats').ProcessStats;
|
|
|
27
25
|
var InstanceTracker = require('../process/instance-tracker').InstanceTracker;
|
|
28
26
|
var StringMatcher = require('../proxy/string-matcher').StringMatcher;
|
|
29
27
|
var ExpressionEvaluator = require('../proxy/expression-evaluator').ExpressionEvaluator;
|
|
30
|
-
var ConfigManager = require('../transactions/config-manager').ConfigManager;
|
|
31
|
-
var TransactionRegistry = require('../transactions/transaction-registry').TransactionRegistry;
|
|
32
|
-
var TransactionNaming = require('../transactions/transaction-naming').TransactionNaming;
|
|
33
|
-
var TransactionRules = require('../transactions/transaction-rules').TransactionRules;
|
|
34
|
-
var SepRules = require('../transactions/sep-config').SepRules;
|
|
35
28
|
var Correlation = require('../transactions/correlation').Correlation;
|
|
36
|
-
var DataCollectors = require('../transactions/data-collectors').DataCollectors;
|
|
37
29
|
var Eum = require('../transactions/eum').Eum;
|
|
38
30
|
var Profiler = require('../profiler/profiler').Profiler;
|
|
39
31
|
var CustomTransaction = require('../profiler/custom-transaction').CustomTransaction;
|
|
40
32
|
var GCStats = require('../v8/gc-stats').GCStats;
|
|
41
33
|
var CpuProfiler = require('../v8/cpu-profiler').CpuProfiler;
|
|
42
34
|
var HeapProfiler = require('../v8/heap-profiler').HeapProfiler;
|
|
43
|
-
var BackendConfig = require('../proxy/backend-config').BackendConfig;
|
|
44
35
|
var agentVersion = require('../../appdynamics_version.json');
|
|
45
36
|
var appDNativeLoader = require('appdynamics-native');
|
|
46
37
|
|
|
47
|
-
|
|
38
|
+
var LibAgent = require('../libagent/libagent').LibAgent;
|
|
48
39
|
var LibagentConnector = require('../libagent/libagent-connector').LibagentConnector;
|
|
49
40
|
var TransactionSender = require('../libagent/transaction-sender').TransactionSender;
|
|
50
41
|
var ProcessSnapshotSender = require('../libagent/process-snapshot-sender').ProcessSnapshotSender;
|
|
@@ -83,7 +74,6 @@ function Agent() {
|
|
|
83
74
|
this.system = new System(this);
|
|
84
75
|
this.proxy = new AppDProxy(this);
|
|
85
76
|
this.thread = new Thread(this);
|
|
86
|
-
this.analyticsReporter = new AnalyticsReporter(this);
|
|
87
77
|
this.metricsManager = new MetricsManager(this);
|
|
88
78
|
this.processInfo = new ProcessInfo(this);
|
|
89
79
|
this.processScanner = new ProcessScanner(this);
|
|
@@ -91,22 +81,14 @@ function Agent() {
|
|
|
91
81
|
this.instanceTracker = new InstanceTracker(this);
|
|
92
82
|
this.stringMatcher = new StringMatcher(this);
|
|
93
83
|
this.expressionEvaluator = new ExpressionEvaluator(this);
|
|
94
|
-
this.configManager = new ConfigManager(this);
|
|
95
|
-
this.transactionRegistry = new TransactionRegistry(this);
|
|
96
|
-
this.transactionNaming = new TransactionNaming(this);
|
|
97
|
-
this.transactionRules = new TransactionRules(this);
|
|
98
|
-
this.sepRules = new SepRules(this);
|
|
99
84
|
this.correlation = new Correlation(this);
|
|
100
|
-
this.dataCollectors = new DataCollectors(this);
|
|
101
85
|
this.eum = new Eum(this);
|
|
102
86
|
this.profiler = new Profiler(this);
|
|
103
87
|
this.customTransaction = new CustomTransaction(this);
|
|
104
88
|
this.gcStats = new GCStats(this);
|
|
105
89
|
this.cpuProfiler = new CpuProfiler(this);
|
|
106
90
|
this.heapProfiler = new HeapProfiler(this);
|
|
107
|
-
this.backendConfig = new BackendConfig(this);
|
|
108
91
|
|
|
109
|
-
this.libproxy = null;
|
|
110
92
|
this.libagent = null;
|
|
111
93
|
|
|
112
94
|
// nsolid support
|
|
@@ -193,7 +175,17 @@ Agent.prototype.init = function (opts) {
|
|
|
193
175
|
|
|
194
176
|
self.opts.clsDisabled = !!self.opts.clsDisabled;
|
|
195
177
|
|
|
196
|
-
self.backendConnector =
|
|
178
|
+
self.backendConnector = new LibAgent(this);
|
|
179
|
+
|
|
180
|
+
if (opts.openTelemetry && opts.openTelemetry.enabled) {
|
|
181
|
+
var TracerProvider = require('./opentelemetry-tracer');
|
|
182
|
+
self.TracerProvider = new TracerProvider(self.logger);
|
|
183
|
+
if (!self.TracerProvider.register(opts)) {
|
|
184
|
+
self.logger.error('AppDynamics agent cannot be started: Tracer Provider registration has failed');
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
self.tracer = self.TracerProvider.getTracer('appdynamics-tracer');
|
|
188
|
+
}
|
|
197
189
|
|
|
198
190
|
self.precompiled = opts.precompiled === undefined || opts.precompiled;
|
|
199
191
|
|
|
@@ -272,13 +264,7 @@ Agent.prototype.init = function (opts) {
|
|
|
272
264
|
self.backendConnector.init();
|
|
273
265
|
self.stringMatcher.init();
|
|
274
266
|
self.expressionEvaluator.init();
|
|
275
|
-
self.configManager.init();
|
|
276
|
-
self.transactionRegistry.init();
|
|
277
|
-
self.transactionNaming.init();
|
|
278
|
-
self.transactionRules.init();
|
|
279
|
-
self.sepRules.init();
|
|
280
267
|
self.correlation.init();
|
|
281
|
-
self.dataCollectors.init();
|
|
282
268
|
self.eum.init();
|
|
283
269
|
|
|
284
270
|
// Metrics aggregator should be initialize before
|
|
@@ -286,7 +272,6 @@ Agent.prototype.init = function (opts) {
|
|
|
286
272
|
self.metricsManager.init();
|
|
287
273
|
|
|
288
274
|
// Initialize the rest.
|
|
289
|
-
self.analyticsReporter.init();
|
|
290
275
|
self.processInfo.init();
|
|
291
276
|
self.processScanner.init();
|
|
292
277
|
self.processStats.init();
|
|
@@ -296,7 +281,6 @@ Agent.prototype.init = function (opts) {
|
|
|
296
281
|
self.gcStats.init();
|
|
297
282
|
self.cpuProfiler.init();
|
|
298
283
|
self.heapProfiler.init();
|
|
299
|
-
self.backendConfig.init();
|
|
300
284
|
|
|
301
285
|
// Initialize libagent
|
|
302
286
|
self.backendConnector.intializeAgentHelpers();
|
|
@@ -440,6 +424,7 @@ Agent.prototype.loadProbes = function () {
|
|
|
440
424
|
probeCons.push(require('../probes/couchbase-probe').CouchBaseProbe);
|
|
441
425
|
probeCons.push(require('../probes/cassandra-probe').CassandraProbe);
|
|
442
426
|
probeCons.push(require('../probes/express-probe').ExpressProbe);
|
|
427
|
+
probeCons.push(require('../probes/rabbitmq-probe').RabbitMQProbe);
|
|
443
428
|
|
|
444
429
|
var packageProbes = {};
|
|
445
430
|
probeCons.forEach(function (ProbeCon) {
|
|
@@ -524,14 +509,16 @@ Agent.prototype.startTransaction = function (transactionInfo, cb) {
|
|
|
524
509
|
};
|
|
525
510
|
|
|
526
511
|
Agent.prototype.parseCorrelationInfo = function (source) {
|
|
527
|
-
var
|
|
512
|
+
var self = this;
|
|
528
513
|
if (typeof (source) === 'object') {
|
|
529
|
-
source = source.headers && source.headers[
|
|
530
|
-
}
|
|
531
|
-
if (!corrHeader.parse(source)) {
|
|
532
|
-
return false;
|
|
514
|
+
source = source.headers && source.headers[self.correlation.HEADER_NAME];
|
|
533
515
|
}
|
|
534
|
-
return
|
|
516
|
+
return {
|
|
517
|
+
businessTransactionName: 'NodeJS API Business Transaction',
|
|
518
|
+
headers: {
|
|
519
|
+
'singularityheader': source
|
|
520
|
+
}
|
|
521
|
+
};
|
|
535
522
|
};
|
|
536
523
|
|
|
537
524
|
|
|
@@ -606,16 +593,6 @@ Agent.prototype.dumpRuntimeProperties = function () {
|
|
|
606
593
|
}
|
|
607
594
|
};
|
|
608
595
|
|
|
609
|
-
Agent.prototype.getAgentCustomFns = function (isProxy) {
|
|
610
|
-
if (isProxy) {
|
|
611
|
-
var LibProxy = require('../libproxy/libproxy').LibProxy;
|
|
612
|
-
return new LibProxy(this);
|
|
613
|
-
} else {
|
|
614
|
-
var LibAgent = require('../libagent/libagent').LibAgent;
|
|
615
|
-
return new LibAgent(this);
|
|
616
|
-
}
|
|
617
|
-
};
|
|
618
|
-
|
|
619
596
|
var AppDynamics = function () {
|
|
620
597
|
var self = this;
|
|
621
598
|
|
package/lib/core/appDProxy.js
CHANGED
|
@@ -217,7 +217,7 @@ AppDProxy.prototype.before = function(obj, meths, hook, isCallbackHook, copyAllP
|
|
|
217
217
|
var beforeExecLogic = function() {
|
|
218
218
|
var currentCtxt = self.agent.thread.current();
|
|
219
219
|
try {
|
|
220
|
-
var args = arguments;
|
|
220
|
+
var args = [...arguments];
|
|
221
221
|
var methsInvocationCtxtLocal = methsInvocationCtxt;
|
|
222
222
|
if (methsInvocationCtxtLocal)
|
|
223
223
|
self.agent.thread.resume(methsInvocationCtxtLocal);
|
|
@@ -225,19 +225,19 @@ AppDProxy.prototype.before = function(obj, meths, hook, isCallbackHook, copyAllP
|
|
|
225
225
|
var selfProxy = this;
|
|
226
226
|
|
|
227
227
|
// the hook code should contain try/catch
|
|
228
|
-
args = hook(this,
|
|
229
|
-
return orig.apply(selfProxy, args
|
|
230
|
-
});
|
|
228
|
+
args = hook(this, args, function() {
|
|
229
|
+
return orig.apply(selfProxy, args);
|
|
230
|
+
}) || args;
|
|
231
231
|
}
|
|
232
232
|
else {
|
|
233
233
|
try {
|
|
234
|
-
args = hook(this,
|
|
234
|
+
args = hook(this, args) || args;
|
|
235
235
|
}
|
|
236
236
|
catch (e) {
|
|
237
237
|
self.logError(e);
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
var retValue = orig.apply(this, args
|
|
240
|
+
var retValue = orig.apply(this, args);
|
|
241
241
|
return retValue;
|
|
242
242
|
}
|
|
243
243
|
} finally {
|
|
@@ -277,7 +277,7 @@ AppDProxy.prototype.after = function(obj, meths, hook, copyAllProps, methsInvoca
|
|
|
277
277
|
|
|
278
278
|
var hookRet;
|
|
279
279
|
try {
|
|
280
|
-
hookRet = hook(this, arguments, ret);
|
|
280
|
+
hookRet = hook(this, [...arguments], ret);
|
|
281
281
|
}
|
|
282
282
|
catch (e) {
|
|
283
283
|
self.logError(e);
|
|
@@ -350,14 +350,14 @@ AppDProxy.prototype.around = function(obj, meths, hookBefore, hookAfter, copyAll
|
|
|
350
350
|
defineProperty(obj, meth, function() {
|
|
351
351
|
var currentCtxt = self.agent.thread.current();
|
|
352
352
|
try {
|
|
353
|
-
var args = arguments;
|
|
353
|
+
var args = [...arguments];
|
|
354
354
|
var methsInvocationCtxtLocal = methsInvocationCtxt;
|
|
355
355
|
if (methsInvocationCtxtLocal)
|
|
356
356
|
self.agent.thread.resume(methsInvocationCtxtLocal);
|
|
357
357
|
var locals = new Locals();
|
|
358
358
|
|
|
359
359
|
try {
|
|
360
|
-
args = hookBefore(this,
|
|
360
|
+
args = hookBefore(this, args, locals) || args;
|
|
361
361
|
}
|
|
362
362
|
catch (e) {
|
|
363
363
|
self.logError(e);
|
|
@@ -372,8 +372,8 @@ AppDProxy.prototype.around = function(obj, meths, hookBefore, hookAfter, copyAll
|
|
|
372
372
|
}
|
|
373
373
|
}
|
|
374
374
|
|
|
375
|
-
var ret = orig.apply(this, args
|
|
376
|
-
var promiseRet = self.promise(ret, hookAfter, this,
|
|
375
|
+
var ret = orig.apply(this, args);
|
|
376
|
+
var promiseRet = self.promise(ret, hookAfter, this, args, locals, methsInvocationCtxtLocal);
|
|
377
377
|
if (promiseRet) {
|
|
378
378
|
self.agent.thread.resume(currentCtxt);
|
|
379
379
|
return promiseRet;
|
|
@@ -381,7 +381,7 @@ AppDProxy.prototype.around = function(obj, meths, hookBefore, hookAfter, copyAll
|
|
|
381
381
|
|
|
382
382
|
var hookRet;
|
|
383
383
|
try {
|
|
384
|
-
hookRet = hookAfter(this,
|
|
384
|
+
hookRet = hookAfter(this, args, ret, locals);
|
|
385
385
|
}
|
|
386
386
|
catch (e) {
|
|
387
387
|
self.logError(e);
|
package/lib/core/logger.js
CHANGED
|
@@ -5,9 +5,6 @@ All Rights Reserved
|
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
-
var cluster = require('cluster');
|
|
9
|
-
var log4js = require('log4js');
|
|
10
|
-
var path = require('path');
|
|
11
8
|
|
|
12
9
|
|
|
13
10
|
function isDebugEnabled(agent) {
|
|
@@ -50,94 +47,45 @@ function Logger(agent) {
|
|
|
50
47
|
};
|
|
51
48
|
}
|
|
52
49
|
exports.Logger = Logger;
|
|
53
|
-
Logger.sharedLogger = undefined; // (for unit tests)
|
|
54
|
-
|
|
55
50
|
|
|
56
51
|
/* istanbul ignore next -- log4j mocked in unit tests */
|
|
57
|
-
Logger.prototype.init = function (config
|
|
52
|
+
Logger.prototype.init = function (config) {
|
|
58
53
|
if (!config) {
|
|
59
54
|
config = {};
|
|
60
55
|
}
|
|
61
56
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
var dateString = new Date().toJSON();
|
|
68
|
-
dateString = dateString.replace(/[-:]/g, "_").replace("T", "__").replace(/\..*$/, "");
|
|
69
|
-
var logFileName = 'appd_node_agent_' + dateString + ".log";
|
|
70
|
-
var rootPath = config.root_directory || this.agent.tmpDir;
|
|
71
|
-
var baseName = config.filename || logFileName;
|
|
72
|
-
// Libagent logFile is already created in the libagent. Since, there is no
|
|
73
|
-
// way to tap on to the file name created by boost::log used by libagent
|
|
74
|
-
// show the log filePath till agent tmpDir.
|
|
75
|
-
var fileName = initializeBackend ? path.join(rootPath, baseName) : this.agent.tmpDir;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
var consoleOnly = (this.agent.opts.logging && this.agent.opts.logging.logfiles &&
|
|
79
|
-
this.agent.opts.logging.logfiles.every(function (lf) {
|
|
80
|
-
return lf.outputType == 'console';
|
|
81
|
-
}));
|
|
82
|
-
|
|
83
|
-
// If console logging env variable is set and no custom logging config is provided
|
|
84
|
-
// then don't create temp path for logs
|
|
85
|
-
if (process.env.APPDYNAMICS_LOGGER_OUTPUT_TYPE === "console" && (!config.logfiles || config.logfiles.length == 0)) {
|
|
86
|
-
consoleOnly = true;
|
|
87
|
-
}
|
|
57
|
+
var rootPath = config.root_directory || this.agent.tmpDir;
|
|
58
|
+
// Libagent logFile is already created in the libagent. Since, there is no
|
|
59
|
+
// way to tap on to the file name created by boost::log used by libagent
|
|
60
|
+
// show the log filePath till agent tmpDir.
|
|
61
|
+
var fileName = this.agent.tmpDir;
|
|
88
62
|
|
|
89
|
-
if (!consoleOnly) {
|
|
90
|
-
this.agent.recursiveMkDir(rootPath);
|
|
91
|
-
}
|
|
92
63
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
console.log('[DEBUG] Appdynamics agent logs: ' + fileName);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
64
|
+
var consoleOnly = (this.agent.opts.logging && this.agent.opts.logging.logfiles &&
|
|
65
|
+
this.agent.opts.logging.logfiles.every(function (lf) {
|
|
66
|
+
return lf.outputType == 'console';
|
|
67
|
+
}));
|
|
100
68
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
69
|
+
// If console logging env variable is set and no custom logging config is provided
|
|
70
|
+
// then don't create temp path for logs
|
|
71
|
+
if (process.env.APPDYNAMICS_LOGGER_OUTPUT_TYPE === "console" && (!config.logfiles || config.logfiles.length == 0)) {
|
|
72
|
+
consoleOnly = true;
|
|
73
|
+
}
|
|
106
74
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
75
|
+
if (!consoleOnly) {
|
|
76
|
+
this.agent.recursiveMkDir(rootPath);
|
|
77
|
+
}
|
|
111
78
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
type: 'logLevelFilter',
|
|
118
|
-
level: config.level || process.env.APPDYNAMICS_LOGGER_LEVEL || 'INFO',
|
|
119
|
-
appender: {
|
|
120
|
-
type: config.outputType || 'file',
|
|
121
|
-
filename: fileName,
|
|
122
|
-
maxLogSize: config.max_size || 5242880,
|
|
123
|
-
backups: config.max_files || 10,
|
|
124
|
-
category: 'default',
|
|
125
|
-
mode: config.mode || 'append'
|
|
126
|
-
}
|
|
127
|
-
}]
|
|
128
|
-
}]
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
log4js.configure({
|
|
133
|
-
appenders: [{
|
|
134
|
-
type: 'clustered'
|
|
135
|
-
}]
|
|
136
|
-
});
|
|
79
|
+
if (this.agent.opts.debug) {
|
|
80
|
+
// force logging level to DEBUG and output location of logs
|
|
81
|
+
config.level = 'DEBUG';
|
|
82
|
+
if (!consoleOnly) {
|
|
83
|
+
console.log('[DEBUG] Appdynamics agent logs: ' + fileName);
|
|
137
84
|
}
|
|
138
|
-
|
|
139
|
-
Logger.sharedLogger = this.logger = log4js.getLogger('default');
|
|
140
85
|
}
|
|
86
|
+
|
|
87
|
+
// libagent uses its own logging, and does not need the log4js backend to be initialized
|
|
88
|
+
this.libAgentConnector.initLogger();
|
|
141
89
|
};
|
|
142
90
|
|
|
143
91
|
Logger.prototype.trace = function (msg) {
|
|
@@ -222,4 +170,4 @@ Logger.prototype.isErrorEnabled = function () {
|
|
|
222
170
|
|
|
223
171
|
Logger.prototype.isFatalEnabled = function () {
|
|
224
172
|
return this.logger.isFatalEnabled();
|
|
225
|
-
};
|
|
173
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const opentelemetry_api = require('@opentelemetry/api');
|
|
4
|
+
const { ROOT_CONTEXT } = require('@opentelemetry/api');
|
|
5
|
+
const { BatchSpanProcessor, ConsoleSpanExporter, BasicTracerProvider } = require('@opentelemetry/sdk-trace-base');
|
|
6
|
+
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-proto");
|
|
7
|
+
const { AsyncHooksContextManager, AsyncLocalStorageContextManager } = require("@opentelemetry/context-async-hooks");
|
|
8
|
+
const { ParentBasedSampler, AlwaysOnSampler } = require("@opentelemetry/core");
|
|
9
|
+
const { Resource } = require('@opentelemetry/resources');
|
|
10
|
+
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
|
|
11
|
+
const url = require('url');
|
|
12
|
+
|
|
13
|
+
module.exports = TracerProvider;
|
|
14
|
+
|
|
15
|
+
function TracerProvider(logger) {
|
|
16
|
+
this.host = 'localhost';
|
|
17
|
+
this.port = '55681';
|
|
18
|
+
this.ot_api = opentelemetry_api;
|
|
19
|
+
this.ROOT_CONTEXT = ROOT_CONTEXT;
|
|
20
|
+
this.logger = logger;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
TracerProvider.prototype.register = function(config) {
|
|
24
|
+
const provider = new BasicTracerProvider({
|
|
25
|
+
sampler: new ParentBasedSampler({
|
|
26
|
+
root: new AlwaysOnSampler()
|
|
27
|
+
}),
|
|
28
|
+
resource: new Resource({
|
|
29
|
+
[SemanticResourceAttributes.SERVICE_NAME]: config.tierName,
|
|
30
|
+
"service.name": config.tierName,
|
|
31
|
+
"service.namespace": config.applicationName
|
|
32
|
+
}),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// default collector configuration, can be overridden from agent config
|
|
36
|
+
const collectorOptions = {
|
|
37
|
+
attributes: {'service.name': config.tierName,
|
|
38
|
+
'service.namespace': config.applicationName}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// batch export config, empty by default
|
|
42
|
+
const batchExporterConfig = {};
|
|
43
|
+
|
|
44
|
+
if (config.openTelemetry) {
|
|
45
|
+
if (config.openTelemetry.collector) {
|
|
46
|
+
Object.assign(collectorOptions, config.openTelemetry.collector);
|
|
47
|
+
this.url = collectorOptions.url;
|
|
48
|
+
try {
|
|
49
|
+
var urlObj = url.parse(this.url);
|
|
50
|
+
this.host = urlObj.hostname;
|
|
51
|
+
this.port = urlObj.port;
|
|
52
|
+
} catch (e) {
|
|
53
|
+
this.logger.error('Collector url must be in <host>:<port> format');
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if(config.openTelemetry.exporter) {
|
|
58
|
+
if(config.openTelemetry.exporter.maxExportBatchSize) {
|
|
59
|
+
batchExporterConfig.maxExportBatchSize = config.openTelemetry.exporter.maxExportBatchSize;
|
|
60
|
+
}
|
|
61
|
+
if(config.openTelemetry.exporter.maxQueueSize) {
|
|
62
|
+
batchExporterConfig.maxQueueSize = config.openTelemetry.exporter.maxQueueSize;
|
|
63
|
+
}
|
|
64
|
+
if(config.openTelemetry.exporter.exportTimeoutMillis) {
|
|
65
|
+
batchExporterConfig.exportTimeoutMillis = config.openTelemetry.exporter.exportTimeoutMillis;
|
|
66
|
+
}
|
|
67
|
+
if(config.openTelemetry.exporter.maxExportBatchSize) {
|
|
68
|
+
batchExporterConfig.maxExportBatchSize = config.openTelemetry.exporter.maxExportBatchSize;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const exporter = new OTLPTraceExporter(collectorOptions);
|
|
74
|
+
provider.addSpanProcessor(new BatchSpanProcessor(exporter, batchExporterConfig));
|
|
75
|
+
if (config.openTelemetry && config.openTelemetry.debug) {
|
|
76
|
+
provider.addSpanProcessor(new BatchSpanProcessor(new ConsoleSpanExporter(), batchExporterConfig));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const majorVersion = parseInt(process.versions.node.split('.')[0]);
|
|
80
|
+
const minorVersion = parseInt(process.versions.node.split('.')[1]);
|
|
81
|
+
const contextManager = majorVersion > 14 || majorVersion == 14 && minorVersion >= 8 ?
|
|
82
|
+
AsyncLocalStorageContextManager : AsyncHooksContextManager;
|
|
83
|
+
provider.register({contextManager: new contextManager()});
|
|
84
|
+
return true;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
TracerProvider.prototype.getTracer = function(name) {
|
|
88
|
+
return opentelemetry_api.trace.getTracer(name);
|
|
89
|
+
};
|
|
@@ -48,8 +48,6 @@ function toHoleHandling(str) {
|
|
|
48
48
|
return str;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
51
|
function toAggregator(str) {
|
|
54
52
|
if (str === 'AVG') {
|
|
55
53
|
return Constants.AGGREGATOR_AVERAGE;
|
|
@@ -102,8 +100,6 @@ LibagentConnector.prototype.initLogger = function () {
|
|
|
102
100
|
LibagentConnector.prototype.init = function () {
|
|
103
101
|
var self = this;
|
|
104
102
|
|
|
105
|
-
// override libagent-specific definitions in core agent
|
|
106
|
-
self.overrideFunctionDefinitions(self.agent);
|
|
107
103
|
// initialize protobuf
|
|
108
104
|
self.protobufModel = new ProtobufModel(self.agent);
|
|
109
105
|
self.protobufModel.init();
|
|
@@ -350,6 +346,11 @@ LibagentConnector.prototype.startProcessSnapshot = function () {
|
|
|
350
346
|
self.libagent.startProcessSnapshot();
|
|
351
347
|
};
|
|
352
348
|
|
|
349
|
+
LibagentConnector.prototype.getBusinessTransactionQueryType = function (entryPointType, callback) {
|
|
350
|
+
var self = this;
|
|
351
|
+
return self.libagent.getBusinessTransactionQueryType(entryPointType, callback);
|
|
352
|
+
};
|
|
353
|
+
|
|
353
354
|
LibagentConnector.prototype.sendProcessSnapshot = function (processSnapshot) {
|
|
354
355
|
var self = this;
|
|
355
356
|
self.libagent.addProcessSnapshot(processSnapshot);
|
|
@@ -540,49 +541,6 @@ LibagentConnector.prototype.getEumCookieFields = function (transaction, shortFor
|
|
|
540
541
|
return {};
|
|
541
542
|
};
|
|
542
543
|
|
|
543
|
-
LibagentConnector.prototype.overrideFunctionDefinitions = function (agent) {
|
|
544
|
-
agent.parseCorrelationInfo = function (source) {
|
|
545
|
-
var self = agent;
|
|
546
|
-
if (typeof (source) === 'object') {
|
|
547
|
-
source = source.headers && source.headers[self.correlation.HEADER_NAME];
|
|
548
|
-
}
|
|
549
|
-
return {
|
|
550
|
-
businessTransactionName: 'NodeJS API Business Transaction',
|
|
551
|
-
headers: {
|
|
552
|
-
'singularityheader': source
|
|
553
|
-
}
|
|
554
|
-
};
|
|
555
|
-
};
|
|
556
|
-
|
|
557
|
-
agent.profiler.addExitCall = function (time, exitCall, error) {
|
|
558
|
-
var self = agent.profiler;
|
|
559
|
-
exitCall.error = error;
|
|
560
|
-
var transaction = self.transactions[exitCall.threadId];
|
|
561
|
-
|
|
562
|
-
if (transaction && transaction.api && transaction.api.exitCallCompleted) {
|
|
563
|
-
exitCall = transaction.api.exitCallCompleted(exitCall) || exitCall;
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
agent.backendConnector.stopExitCall(exitCall, error);
|
|
567
|
-
self.tryEndingTransactionAfterExitCall(transaction, exitCall, time);
|
|
568
|
-
};
|
|
569
|
-
|
|
570
|
-
agent.eum.init = function () {
|
|
571
|
-
var self = agent.eum;
|
|
572
|
-
self.registerEumCookieType();
|
|
573
|
-
};
|
|
574
|
-
|
|
575
|
-
agent.eum.enabledForTransaction = function (transaction) {
|
|
576
|
-
return !transaction.skip && transaction.eumEnabled;
|
|
577
|
-
};
|
|
578
|
-
|
|
579
|
-
/* always pass url property for libagent */
|
|
580
|
-
agent.backendConfig.isParsedUrlRequired = function () {
|
|
581
|
-
return true;
|
|
582
|
-
};
|
|
583
|
-
|
|
584
|
-
};
|
|
585
|
-
|
|
586
544
|
LibagentConnector.prototype.setupEum = function (agent) {
|
|
587
545
|
var libAgentConnector = this;
|
|
588
546
|
agent.eum.eumCookie.prototype.setFieldValues = function () {
|
package/lib/libagent/libagent.js
CHANGED
|
@@ -5,7 +5,6 @@ All Rights Reserved
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
|
-
var Metric = require('./metrics/metric').Metric;
|
|
9
8
|
var LibagentTransactionReporter = require('./transactions/transaction-reporter').TransactionReporter;
|
|
10
9
|
var cluster = require('cluster');
|
|
11
10
|
var fs = require('fs');
|
|
@@ -21,7 +20,6 @@ function LibAgent(agent) {
|
|
|
21
20
|
this.nodeIndexComputed = false;
|
|
22
21
|
// For unit-testing
|
|
23
22
|
this.libagent = true;
|
|
24
|
-
agent.Metric = Metric;
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
exports.LibAgent = LibAgent;
|
|
@@ -145,7 +143,7 @@ LibAgent.prototype.readNodeIndex = function(callback) {
|
|
|
145
143
|
LibAgent.prototype.initializeLogger = function() {
|
|
146
144
|
var self = this;
|
|
147
145
|
self.agent.logger.setLibAgentConnector(self.agent.libagentConnector);
|
|
148
|
-
self.agent.logger.init(self.agent.opts.logging
|
|
146
|
+
self.agent.logger.init(self.agent.opts.logging);
|
|
149
147
|
};
|
|
150
148
|
|
|
151
149
|
LibAgent.prototype.createCLRDirectories = function() {
|
|
@@ -184,6 +182,7 @@ LibAgent.prototype.createExitCall = function(time, exitCallInfo) {
|
|
|
184
182
|
command: exitCallInfo.command || '',
|
|
185
183
|
properties: exitCallInfo.supportedProperties,
|
|
186
184
|
useBackendConfig: exitCallInfo.useBackendConfig,
|
|
185
|
+
protocol: exitCallInfo.protocol,
|
|
187
186
|
addAnalyticsData: function(key, value) {
|
|
188
187
|
this.userData = this.userData || [];
|
|
189
188
|
if (value instanceof Date) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* 2016
|
|
4
4
|
* All Rights Reserved
|
|
5
5
|
*/
|
|
6
|
-
var
|
|
6
|
+
var utility = require('../utility');
|
|
7
7
|
|
|
8
8
|
function TransactionSender(agent) {
|
|
9
9
|
this.agent = agent;
|
|
@@ -18,10 +18,8 @@ TransactionSender.prototype.init = function() {
|
|
|
18
18
|
var libagentConnector = self.agent.libagentConnector;
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
libagentConnector.on("btNamingProperties", function(
|
|
21
|
+
libagentConnector.on("btNamingProperties", function() {
|
|
22
22
|
self.isEnabled = true;
|
|
23
|
-
|
|
24
|
-
self.agent.transactionNaming.namingProps = btNamingProperties;
|
|
25
23
|
});
|
|
26
24
|
|
|
27
25
|
|
|
@@ -48,6 +46,18 @@ TransactionSender.prototype.init = function() {
|
|
|
48
46
|
isHttpRequest = true;
|
|
49
47
|
if('singularityheader' in req.headers) {
|
|
50
48
|
corrHeader = req.headers.singularityheader || "";
|
|
49
|
+
} else if(self.agent.tracer && transaction.baggageCorrHeader) {
|
|
50
|
+
/*
|
|
51
|
+
* 1: We append the doNotResolveSubHeader when the upstream is a pure OT service to
|
|
52
|
+
* prevent resolution to the preceding APPD service
|
|
53
|
+
2: The noTxDetectHeader is treated specially by libagent, so do not append the doNotResolveSubHeader
|
|
54
|
+
in this case
|
|
55
|
+
*/
|
|
56
|
+
const noTxDetectHeader = self.agent.correlation.DISABLE_TRANSACTION_DETECTION + '=true';
|
|
57
|
+
const doNotResolveSubHeader = self.agent.correlation.DONOTRESOLVE + '=true';
|
|
58
|
+
corrHeader = transaction.baggageCorrHeader != noTxDetectHeader ? transaction.baggageCorrHeader + '*' +
|
|
59
|
+
doNotResolveSubHeader : transaction.baggageCorrHeader;
|
|
60
|
+
self.agent.logger.debug(`Using Singularity Header from Opentelemetry Baggage ${corrHeader}`);
|
|
51
61
|
}
|
|
52
62
|
}
|
|
53
63
|
if (req.businessTransactionName) {
|
|
@@ -55,7 +65,7 @@ TransactionSender.prototype.init = function() {
|
|
|
55
65
|
}
|
|
56
66
|
}
|
|
57
67
|
|
|
58
|
-
var txData = libagentConnector.startBusinessTransaction('NODEJS_WEB', name, corrHeader,
|
|
68
|
+
var txData = libagentConnector.startBusinessTransaction('NODEJS_WEB', name, corrHeader, utility.createBtNamingWrapper(req), isHttpRequest);
|
|
59
69
|
|
|
60
70
|
if (txData === undefined || txData.isExcluded) {
|
|
61
71
|
transaction.skip = true;
|
|
@@ -110,14 +120,3 @@ TransactionSender.prototype.init = function() {
|
|
|
110
120
|
libagentConnector.stopExitCall(exitCall, error);
|
|
111
121
|
});
|
|
112
122
|
};
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
TransactionSender.prototype.createBtNamingWrapper = function(req) {
|
|
116
|
-
// TODO: replace these with boost::regex in libagent bindings
|
|
117
|
-
if (req.url) {
|
|
118
|
-
var parsedUrl = url.parse(req.url);
|
|
119
|
-
req.parsedPathName = parsedUrl.pathname;
|
|
120
|
-
req.parsedParameterString = parsedUrl.query;
|
|
121
|
-
}
|
|
122
|
-
return req;
|
|
123
|
-
};
|
|
@@ -15,9 +15,4 @@ exports.TransactionReporter = TransactionReporter;
|
|
|
15
15
|
TransactionReporter.prototype.init = function() {
|
|
16
16
|
var self = this;
|
|
17
17
|
self.enabled = true;
|
|
18
|
-
|
|
19
|
-
// self.agent.on('configUpdated', function() {});
|
|
20
|
-
// self.agent.on('transactionStarted', function(transaction, req) {});
|
|
21
|
-
// self.agent.on('transactionStopped', function(transaction, req) {});
|
|
22
|
-
|
|
23
18
|
};
|