appdynamics 21.9.0 → 22.5.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 +22 -0
- package/lib/core/appDProxy.js +12 -12
- package/lib/core/logger.js +27 -79
- package/lib/core/opentelemetry-tracer.js +97 -0
- package/lib/libagent/libagent-connector.js +24 -0
- package/lib/libagent/libagent.js +2 -1
- package/lib/libagent/transaction-sender.js +14 -13
- package/lib/probes/apollo-entry-probe.js +69 -0
- 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 -116
- package/lib/probes/http-exit-probe.js +93 -31
- package/lib/probes/http-ot-utils.js +117 -0
- package/lib/probes/http-probe.js +14 -7
- package/lib/probes/mongodb-probe.js +200 -113
- package/lib/profiler/profiler.js +5 -1
- package/lib/secure_app/library_metadata.js +56 -0
- package/lib/secure_app/secure_app.js +276 -0
- package/lib/utility.js +20 -1
- package/package.json +13 -8
- package/packageBck.json +13 -8
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
|
|
|
@@ -177,6 +179,16 @@ Agent.prototype.init = function (opts) {
|
|
|
177
179
|
|
|
178
180
|
self.backendConnector = new LibAgent(this);
|
|
179
181
|
|
|
182
|
+
if (opts.openTelemetry && opts.openTelemetry.enabled) {
|
|
183
|
+
var TracerProvider = require('./opentelemetry-tracer');
|
|
184
|
+
self.TracerProvider = new TracerProvider(self.logger);
|
|
185
|
+
if (!self.TracerProvider.register(opts)) {
|
|
186
|
+
self.logger.error('AppDynamics agent cannot be started: Tracer Provider registration has failed');
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
self.tracer = self.TracerProvider.getTracer('appdynamics-tracer');
|
|
190
|
+
}
|
|
191
|
+
|
|
180
192
|
self.precompiled = opts.precompiled === undefined || opts.precompiled;
|
|
181
193
|
|
|
182
194
|
if (self.opts.excludeAgentFromCallGraph === undefined) {
|
|
@@ -272,6 +284,10 @@ Agent.prototype.init = function (opts) {
|
|
|
272
284
|
self.cpuProfiler.init();
|
|
273
285
|
self.heapProfiler.init();
|
|
274
286
|
|
|
287
|
+
if(self.opts.secureAppEnabled) {
|
|
288
|
+
self.secureApp.init(this);
|
|
289
|
+
}
|
|
290
|
+
|
|
275
291
|
// Initialize libagent
|
|
276
292
|
self.backendConnector.intializeAgentHelpers();
|
|
277
293
|
|
|
@@ -332,6 +348,12 @@ Agent.prototype.initializeOpts = function (opts) {
|
|
|
332
348
|
if (self.opts.nodeName === undefined) {
|
|
333
349
|
self.opts.nodeName = process.env.APPDYNAMICS_AGENT_NODE_NAME;
|
|
334
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
|
+
}
|
|
335
357
|
if (self.opts.analyticsMaxSegmentSizeInBytes === undefined && process.env.APPDYNAMICS_ANALYTICS_MAX_SEGMENT_SIZE) {
|
|
336
358
|
self.opts.analyticsMaxSegmentSizeInBytes = parseInt(process.env.APPDYNAMICS_ANALYTICS_MAX_SEGMENT_SIZE, 10);
|
|
337
359
|
}
|
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,97 @@
|
|
|
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, TraceIdRatioBasedSampler } = 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
|
+
function getSamplerFromConfig(config) {
|
|
24
|
+
if(config.sampler && config.sampler.TraceIdRatioBasedSampler) {
|
|
25
|
+
const ratio = config.sampler.TraceIdRatioBasedSampler.Ratio || 1;
|
|
26
|
+
return new TraceIdRatioBasedSampler(ratio);
|
|
27
|
+
} else {
|
|
28
|
+
return new AlwaysOnSampler();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
TracerProvider.prototype.register = function(config) {
|
|
33
|
+
const provider = new BasicTracerProvider({
|
|
34
|
+
sampler: new ParentBasedSampler({
|
|
35
|
+
root: getSamplerFromConfig(config.openTelemetry)
|
|
36
|
+
}),
|
|
37
|
+
resource: new Resource({
|
|
38
|
+
[SemanticResourceAttributes.SERVICE_NAME]: config.tierName,
|
|
39
|
+
[SemanticResourceAttributes.SERVICE_NAMESPACE]: config.applicationName
|
|
40
|
+
}),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// default collector configuration, can be overridden from agent config
|
|
44
|
+
const collectorOptions = {
|
|
45
|
+
attributes: {'service.name': config.tierName,
|
|
46
|
+
'service.namespace': config.applicationName}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// batch export config, empty by default
|
|
50
|
+
const batchExporterConfig = {};
|
|
51
|
+
|
|
52
|
+
if (config.openTelemetry) {
|
|
53
|
+
if (config.openTelemetry.collector) {
|
|
54
|
+
Object.assign(collectorOptions, config.openTelemetry.collector);
|
|
55
|
+
this.url = collectorOptions.url;
|
|
56
|
+
try {
|
|
57
|
+
var urlObj = url.parse(this.url);
|
|
58
|
+
this.host = urlObj.hostname;
|
|
59
|
+
this.port = urlObj.port;
|
|
60
|
+
} catch (e) {
|
|
61
|
+
this.logger.error('Collector url must be in <host>:<port> format');
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if(config.openTelemetry.exporter) {
|
|
66
|
+
if(config.openTelemetry.exporter.maxExportBatchSize) {
|
|
67
|
+
batchExporterConfig.maxExportBatchSize = config.openTelemetry.exporter.maxExportBatchSize;
|
|
68
|
+
}
|
|
69
|
+
if(config.openTelemetry.exporter.maxQueueSize) {
|
|
70
|
+
batchExporterConfig.maxQueueSize = config.openTelemetry.exporter.maxQueueSize;
|
|
71
|
+
}
|
|
72
|
+
if(config.openTelemetry.exporter.exportTimeoutMillis) {
|
|
73
|
+
batchExporterConfig.exportTimeoutMillis = config.openTelemetry.exporter.exportTimeoutMillis;
|
|
74
|
+
}
|
|
75
|
+
if(config.openTelemetry.exporter.maxExportBatchSize) {
|
|
76
|
+
batchExporterConfig.maxExportBatchSize = config.openTelemetry.exporter.maxExportBatchSize;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const exporter = new OTLPTraceExporter(collectorOptions);
|
|
82
|
+
provider.addSpanProcessor(new BatchSpanProcessor(exporter, batchExporterConfig));
|
|
83
|
+
if (config.openTelemetry && config.openTelemetry.debug) {
|
|
84
|
+
provider.addSpanProcessor(new BatchSpanProcessor(new ConsoleSpanExporter(), batchExporterConfig));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const majorVersion = parseInt(process.versions.node.split('.')[0]);
|
|
88
|
+
const minorVersion = parseInt(process.versions.node.split('.')[1]);
|
|
89
|
+
const contextManager = majorVersion > 14 || majorVersion == 14 && minorVersion >= 8 ?
|
|
90
|
+
AsyncLocalStorageContextManager : AsyncHooksContextManager;
|
|
91
|
+
provider.register({contextManager: new contextManager()});
|
|
92
|
+
return true;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
TracerProvider.prototype.getTracer = function(name) {
|
|
96
|
+
return opentelemetry_api.trace.getTracer(name);
|
|
97
|
+
};
|
|
@@ -144,6 +144,7 @@ LibagentConnector.prototype.init = function () {
|
|
|
144
144
|
self.updateConfigTimerId = new MessageSender(self.agent, 30, 60 * 1000, function () {
|
|
145
145
|
self.libagent.updateConfig();
|
|
146
146
|
});
|
|
147
|
+
self.setupEum(self.agent);
|
|
147
148
|
self.emit("connected");
|
|
148
149
|
|
|
149
150
|
self.agent.transactionSender.isEnabled = true;
|
|
@@ -345,6 +346,11 @@ LibagentConnector.prototype.startProcessSnapshot = function () {
|
|
|
345
346
|
self.libagent.startProcessSnapshot();
|
|
346
347
|
};
|
|
347
348
|
|
|
349
|
+
LibagentConnector.prototype.getBusinessTransactionQueryType = function (entryPointType, callback) {
|
|
350
|
+
var self = this;
|
|
351
|
+
return self.libagent.getBusinessTransactionQueryType(entryPointType, callback);
|
|
352
|
+
};
|
|
353
|
+
|
|
348
354
|
LibagentConnector.prototype.sendProcessSnapshot = function (processSnapshot) {
|
|
349
355
|
var self = this;
|
|
350
356
|
self.libagent.addProcessSnapshot(processSnapshot);
|
|
@@ -534,3 +540,21 @@ LibagentConnector.prototype.getEumCookieFields = function (transaction, shortFor
|
|
|
534
540
|
else
|
|
535
541
|
return {};
|
|
536
542
|
};
|
|
543
|
+
|
|
544
|
+
LibagentConnector.prototype.setupEum = function (agent) {
|
|
545
|
+
var libAgentConnector = this;
|
|
546
|
+
agent.eum.eumCookie.prototype.setFieldValues = function () {
|
|
547
|
+
var self = this;
|
|
548
|
+
var shortForm = self.keyForm == 'short';
|
|
549
|
+
var fields = libAgentConnector.getEumCookieFields(self.transaction, shortForm);
|
|
550
|
+
if (fields) {
|
|
551
|
+
for (var key in fields) {
|
|
552
|
+
self.addSubCookie(key, fields[key]);
|
|
553
|
+
}
|
|
554
|
+
self.transaction.eumGuid = fields.g || fields.clientRequestGuid;
|
|
555
|
+
self.guid = self.transaction.eumGuid;
|
|
556
|
+
self.setCookie();
|
|
557
|
+
}
|
|
558
|
+
return true;
|
|
559
|
+
};
|
|
560
|
+
};
|
package/lib/libagent/libagent.js
CHANGED
|
@@ -143,7 +143,7 @@ LibAgent.prototype.readNodeIndex = function(callback) {
|
|
|
143
143
|
LibAgent.prototype.initializeLogger = function() {
|
|
144
144
|
var self = this;
|
|
145
145
|
self.agent.logger.setLibAgentConnector(self.agent.libagentConnector);
|
|
146
|
-
self.agent.logger.init(self.agent.opts.logging
|
|
146
|
+
self.agent.logger.init(self.agent.opts.logging);
|
|
147
147
|
};
|
|
148
148
|
|
|
149
149
|
LibAgent.prototype.createCLRDirectories = function() {
|
|
@@ -182,6 +182,7 @@ LibAgent.prototype.createExitCall = function(time, exitCallInfo) {
|
|
|
182
182
|
command: exitCallInfo.command || '',
|
|
183
183
|
properties: exitCallInfo.supportedProperties,
|
|
184
184
|
useBackendConfig: exitCallInfo.useBackendConfig,
|
|
185
|
+
protocol: exitCallInfo.protocol,
|
|
185
186
|
addAnalyticsData: function(key, value) {
|
|
186
187
|
this.userData = this.userData || [];
|
|
187
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;
|
|
@@ -46,6 +46,18 @@ TransactionSender.prototype.init = function() {
|
|
|
46
46
|
isHttpRequest = true;
|
|
47
47
|
if('singularityheader' in req.headers) {
|
|
48
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}`);
|
|
49
61
|
}
|
|
50
62
|
}
|
|
51
63
|
if (req.businessTransactionName) {
|
|
@@ -53,7 +65,7 @@ TransactionSender.prototype.init = function() {
|
|
|
53
65
|
}
|
|
54
66
|
}
|
|
55
67
|
|
|
56
|
-
var txData = libagentConnector.startBusinessTransaction('NODEJS_WEB', name, corrHeader,
|
|
68
|
+
var txData = libagentConnector.startBusinessTransaction('NODEJS_WEB', name, corrHeader, utility.createBtNamingWrapper(req), isHttpRequest);
|
|
57
69
|
|
|
58
70
|
if (txData === undefined || txData.isExcluded) {
|
|
59
71
|
transaction.skip = true;
|
|
@@ -108,14 +120,3 @@ TransactionSender.prototype.init = function() {
|
|
|
108
120
|
libagentConnector.stopExitCall(exitCall, error);
|
|
109
121
|
});
|
|
110
122
|
};
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
TransactionSender.prototype.createBtNamingWrapper = function(req) {
|
|
114
|
-
// TODO: replace these with boost::regex in libagent bindings
|
|
115
|
-
if (req.url) {
|
|
116
|
-
var parsedUrl = url.parse(req.url);
|
|
117
|
-
req.parsedPathName = parsedUrl.pathname;
|
|
118
|
-
req.parsedParameterString = parsedUrl.query;
|
|
119
|
-
}
|
|
120
|
-
return req;
|
|
121
|
-
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*
|
|
2
|
+
This is for apollo-server entry probe
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
let HttpCommon = require("./http-common");
|
|
6
|
+
|
|
7
|
+
exports.ApolloEntryProbe = ApolloEntryProbe;
|
|
8
|
+
|
|
9
|
+
function ApolloEntryProbe(agent) {
|
|
10
|
+
this.agent = agent;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
ApolloEntryProbe.prototype.init = function () {};
|
|
14
|
+
|
|
15
|
+
ApolloEntryProbe.prototype.attach = function (obj) {
|
|
16
|
+
let self = this;
|
|
17
|
+
self.agent.proxy.before(
|
|
18
|
+
obj.ApolloServer.prototype,
|
|
19
|
+
"createServerInfo",
|
|
20
|
+
(args) => this.addLifeCycleHooks(args)
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
ApolloEntryProbe.prototype.addLifeCycleHooks = function (obj) {
|
|
25
|
+
let self = this;
|
|
26
|
+
let userDefinedContext = obj.context;
|
|
27
|
+
obj.context = function ({ req, res }) {
|
|
28
|
+
let userCtx;
|
|
29
|
+
if (userDefinedContext instanceof Function) {
|
|
30
|
+
userCtx = userDefinedContext.call(this, ...arguments);
|
|
31
|
+
} else if (userDefinedContext instanceof Object) {
|
|
32
|
+
userDefinedContext.gqlReq = req;
|
|
33
|
+
userDefinedContext.gqlRes = res;
|
|
34
|
+
return userDefinedContext;
|
|
35
|
+
}
|
|
36
|
+
return Object.assign({ gqlReq: req, gqlRes: res }, userCtx);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
obj.plugins = [
|
|
40
|
+
{
|
|
41
|
+
requestDidStart() {
|
|
42
|
+
return {
|
|
43
|
+
didResolveOperation(response) {
|
|
44
|
+
response.context.gqlReq.graphqlop = response.operationName;
|
|
45
|
+
response.context.gqlReq.transactionStarted = true;
|
|
46
|
+
HttpCommon.startTransactionHandler(
|
|
47
|
+
response.context.gqlReq,
|
|
48
|
+
response.context.gqlRes,
|
|
49
|
+
self.agent
|
|
50
|
+
);
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
didEncounterErrors(response) {
|
|
54
|
+
response.context.gqlRes.error = response.errors[0];
|
|
55
|
+
if(response.context.gqlReq.transactionStarted) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
HttpCommon.startTransactionHandler(
|
|
59
|
+
response.context.gqlReq,
|
|
60
|
+
response.context.gqlRes,
|
|
61
|
+
self.agent
|
|
62
|
+
);
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
...obj.plugins,
|
|
68
|
+
];
|
|
69
|
+
};
|
|
@@ -64,6 +64,25 @@ CouchBaseProbe.prototype.attach = function(obj) {
|
|
|
64
64
|
after
|
|
65
65
|
);
|
|
66
66
|
}
|
|
67
|
+
|
|
68
|
+
// driver 3.x Cluster prototype
|
|
69
|
+
proxy.around(obj.Cluster.prototype, 'query',
|
|
70
|
+
function(obj, args, locals) {
|
|
71
|
+
locals.time = self.agent.profiler.time();
|
|
72
|
+
locals.methodHasCb = proxy.callback(args, -1, function() {}, null, self.agent.thread.current());
|
|
73
|
+
|
|
74
|
+
var addresses;
|
|
75
|
+
var bucketName = Object.keys(obj._conns);
|
|
76
|
+
addresses = obj._connStr || '';
|
|
77
|
+
addresses = (addresses.match(/(?:.*:\/\/)?([^/?]+)/)[1] || '').split(',');
|
|
78
|
+
|
|
79
|
+
var command = 'query';
|
|
80
|
+
var commandArgs = args;
|
|
81
|
+
|
|
82
|
+
self.createExitCall(bucketName, addresses, command, commandArgs, locals);
|
|
83
|
+
},
|
|
84
|
+
after
|
|
85
|
+
);
|
|
67
86
|
} else {
|
|
68
87
|
// driver 2.x
|
|
69
88
|
proxy.around(obj.Cluster.prototype, 'openBucket', function(obj, args, locals) {
|
|
@@ -121,7 +121,7 @@ GrpcExitProbe.prototype.injectCorrelationHeader = function(args, type, corrHeade
|
|
|
121
121
|
var metadataIndex = args.findIndex((arg) => {
|
|
122
122
|
return (arg &&
|
|
123
123
|
typeof arg === 'object' &&
|
|
124
|
-
arg.
|
|
124
|
+
arg.internalRepr &&
|
|
125
125
|
typeof arg.getMap === 'function'
|
|
126
126
|
);
|
|
127
127
|
});
|