appdynamics 21.6.0 → 22.2.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 +70 -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 +113 -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 +199 -112
- 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 +13 -12
- package/packageBck.json +13 -12
- 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
|
@@ -6,6 +6,7 @@ All Rights Reserved
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
8
|
var EventLoopMetrics = require('./eventloop').EventLoopMetrics;
|
|
9
|
+
var Metric = require('./metric').Metric;
|
|
9
10
|
|
|
10
11
|
/*
|
|
11
12
|
* MetricsManager manages metric lifecycle, i.e. keeps list
|
|
@@ -476,16 +477,16 @@ MetricsManager.prototype.createMetric = function (definition, isCustom) {
|
|
|
476
477
|
|
|
477
478
|
if (this.metrics.length == 5000) {
|
|
478
479
|
self.agent.logger.warn('too many metrics, ignoring metric');
|
|
479
|
-
return new
|
|
480
|
+
return new Metric(self.agent, definition, isCustom);
|
|
480
481
|
}
|
|
481
482
|
|
|
482
483
|
var path = definition.path;
|
|
483
484
|
if (!self.validatePath(path)) {
|
|
484
485
|
self.agent.logger.warn('metric parameter(s) missing or invalid, ignoring metric');
|
|
485
|
-
return new
|
|
486
|
+
return new Metric(self.agent, definition, isCustom); // dummy metric
|
|
486
487
|
}
|
|
487
488
|
|
|
488
|
-
metric = new
|
|
489
|
+
metric = new Metric(self.agent, definition, isCustom);
|
|
489
490
|
self.metrics.push(metric);
|
|
490
491
|
self.metricMap[definition.path] = metric;
|
|
491
492
|
|
|
@@ -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
|
+
};
|
|
@@ -77,7 +77,7 @@ ClusterProbe.prototype.attach = function(obj) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
function writeIndexPid() {
|
|
80
|
-
fs.writeFile(indexDir + '/' + freeIndex + '.pid', ret.process.pid, function(err) {
|
|
80
|
+
fs.writeFile(indexDir + '/' + freeIndex + '.pid', String(ret.process.pid), function(err) {
|
|
81
81
|
if(err) return self.agent.logger.error(err);
|
|
82
82
|
});
|
|
83
83
|
}
|
|
@@ -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
|
});
|
|
@@ -4,10 +4,14 @@ Copyright (c) AppDynamics, Inc., and its affiliates
|
|
|
4
4
|
All Rights Reserved
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
|
+
var HttpOTUtils = require('./http-ot-utils.js');
|
|
7
8
|
|
|
8
9
|
module.exports.getHttpStatusCodeConfig = getHttpStatusCodeConfig;
|
|
9
10
|
module.exports.generateError = generateError;
|
|
10
11
|
module.exports.getHttpExitCallError = getHttpExitCallError;
|
|
12
|
+
module.exports.finalizeTransaction = finalizeTransaction;
|
|
13
|
+
module.exports.startTransactionHandler = startTransactionHandler;
|
|
14
|
+
|
|
11
15
|
|
|
12
16
|
function getHttpStatusCodeConfig(statusCode, statusCodesConfig) {
|
|
13
17
|
if (!statusCodesConfig) {
|
|
@@ -61,3 +65,96 @@ function getHttpExitCallError(statusCode, stack, locals) {
|
|
|
61
65
|
stack: stack};
|
|
62
66
|
return error;
|
|
63
67
|
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
function finalizeTransaction (err, profiler, time, transaction, req, res, span) {
|
|
71
|
+
if (!time.done()) return;
|
|
72
|
+
|
|
73
|
+
transaction.error = transaction.error || res.error || err;
|
|
74
|
+
transaction.statusCode = transaction.statusCode ||
|
|
75
|
+
(transaction.error && transaction.error.statusCode) ||
|
|
76
|
+
(res && res.statusCode) ||
|
|
77
|
+
500;
|
|
78
|
+
transaction.stackTrace = transaction.stackTrace || profiler.formatStackTrace(transaction.error);
|
|
79
|
+
|
|
80
|
+
var error = generateError(transaction.error, transaction.statusCode);
|
|
81
|
+
if (error) {
|
|
82
|
+
transaction.error = error;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (transaction.api && transaction.api.onResponseComplete) {
|
|
86
|
+
transaction.api.onResponseComplete.apply(transaction.api, [req, res]);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (span) {
|
|
90
|
+
span.setAttributes(HttpOTUtils.getIncomingRequestAttributesOnResponse(res));
|
|
91
|
+
span.setStatus(HttpOTUtils.parseResponseStatus(res));
|
|
92
|
+
span.end();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
profiler.endTransaction(time, transaction);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function startTransactionHandler(req, res, agent, isHTTPs, tracer, ot_api) {
|
|
99
|
+
var profiler = agent.profiler;
|
|
100
|
+
var proxy = agent.proxy;
|
|
101
|
+
var time = profiler.time(true);
|
|
102
|
+
|
|
103
|
+
agent.metricsManager.addMetric(
|
|
104
|
+
agent.metricsManager.HTTP_INCOMING_COUNT,
|
|
105
|
+
1
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
var span = undefined;
|
|
109
|
+
var baggageCorrHeader = undefined;
|
|
110
|
+
var otContext = undefined;
|
|
111
|
+
|
|
112
|
+
if (tracer) {
|
|
113
|
+
otContext = ot_api.propagation.extract(agent.TracerProvider.ot_api.ROOT_CONTEXT, req.headers);
|
|
114
|
+
var baggage = ot_api.propagation.getBaggage(otContext);
|
|
115
|
+
if (baggage && baggage.getEntry(agent.correlation.HEADER_NAME)) {
|
|
116
|
+
baggageCorrHeader = baggage.getEntry(agent.correlation.HEADER_NAME).value;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
var transaction = profiler.startTransaction(time, req, "NODEJS_WEB", baggageCorrHeader);
|
|
121
|
+
|
|
122
|
+
if (tracer) {
|
|
123
|
+
ot_api.context.with(otContext, () => {
|
|
124
|
+
span = tracer.startSpan(transaction.name, {
|
|
125
|
+
kind: ot_api.SpanKind.SERVER,
|
|
126
|
+
attributes: HttpOTUtils.getIncomingRequestAttributes(req)
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
agent.context.set("threadId", transaction.threadId);
|
|
132
|
+
req.__appdThreadId = transaction.threadId;
|
|
133
|
+
|
|
134
|
+
transaction.url = req.url;
|
|
135
|
+
transaction.method = req.method;
|
|
136
|
+
transaction.requestHeaders = req.headers;
|
|
137
|
+
|
|
138
|
+
var eumEnabled = transaction.eumEnabled && !transaction.skip;
|
|
139
|
+
|
|
140
|
+
if (!transaction.corrHeader && eumEnabled) {
|
|
141
|
+
proxy.before(res, "writeHead", function (obj) {
|
|
142
|
+
if (!transaction.isFinished) {
|
|
143
|
+
var eumCookie = agent.eum.newEumCookie(
|
|
144
|
+
transaction,
|
|
145
|
+
req,
|
|
146
|
+
obj,
|
|
147
|
+
isHTTPs
|
|
148
|
+
);
|
|
149
|
+
eumCookie.build();
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
proxy.after(res, "end", function () {
|
|
155
|
+
finalizeTransaction(null, profiler, time, transaction, req, res, span);
|
|
156
|
+
transaction = null;
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
return { transaction, span, otContext };
|
|
160
|
+
}
|
|
@@ -3,27 +3,19 @@ Copyright (c) AppDynamics, Inc., and its affiliates
|
|
|
3
3
|
2015
|
|
4
4
|
All Rights Reserved
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
"use strict";
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var utility = require("../utility");
|
|
9
|
+
var HttpCommon = require("./http-common");
|
|
9
10
|
var getGraphQLParams;
|
|
10
11
|
|
|
11
12
|
function HttpEntryProbe(agent) {
|
|
12
13
|
this.agent = agent;
|
|
13
|
-
|
|
14
|
-
this.statusCodesConfig = undefined;
|
|
15
|
-
this.delayedCallbackQueue = [];
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
exports.HttpEntryProbe = HttpEntryProbe;
|
|
19
17
|
|
|
20
|
-
HttpEntryProbe.prototype.init = function () {
|
|
21
|
-
var self = this;
|
|
22
|
-
|
|
23
|
-
self.agent.on('configUpdated', function () {
|
|
24
|
-
self.statusCodesConfig = self.agent.configManager.getConfigValue('errorConfig.httpStatusCodes');
|
|
25
|
-
});
|
|
26
|
-
};
|
|
18
|
+
HttpEntryProbe.prototype.init = function () {};
|
|
27
19
|
|
|
28
20
|
HttpEntryProbe.prototype.enableGraphQL = function (egql) {
|
|
29
21
|
getGraphQLParams = egql.getGraphQLParams;
|
|
@@ -32,18 +24,12 @@ HttpEntryProbe.prototype.enableGraphQL = function (egql) {
|
|
|
32
24
|
HttpEntryProbe.prototype.attach = function (obj, moduleName) {
|
|
33
25
|
var self = this;
|
|
34
26
|
|
|
35
|
-
self.agent.timers.startTimer(100, true, function () {
|
|
36
|
-
var now = Date.now();
|
|
27
|
+
self.agent.timers.startTimer(100, true, function () {});
|
|
37
28
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
} else {
|
|
43
|
-
break;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
});
|
|
29
|
+
if (self.agent.tracer) {
|
|
30
|
+
self.ot_api = self.agent.TracerProvider.ot_api;
|
|
31
|
+
self.tracer = self.agent.tracer;
|
|
32
|
+
}
|
|
47
33
|
|
|
48
34
|
self.isHTTPs = obj.Agent && (obj.Agent.prototype.defaultPort == 443);
|
|
49
35
|
|
|
@@ -60,59 +46,16 @@ HttpEntryProbe.prototype.attach = function (obj, moduleName) {
|
|
|
60
46
|
});
|
|
61
47
|
};
|
|
62
48
|
|
|
63
|
-
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
var error = HttpCommon.generateError(transaction.error, transaction.statusCode, this.statusCodesConfig);
|
|
74
|
-
if (error) {
|
|
75
|
-
transaction.error = error;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (transaction.api && transaction.api.onResponseComplete) {
|
|
79
|
-
transaction.api.onResponseComplete.apply(transaction.api, [req, res]);
|
|
80
|
-
}
|
|
81
|
-
profiler.endTransaction(time, transaction);
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
function createBTCallback(agent, profiler, time, transaction, req, res, thread, callback, self, origSelf, origArgs) {
|
|
85
|
-
var didRun = false;
|
|
86
|
-
var threadId = thread.current();
|
|
87
|
-
|
|
88
|
-
// Node 0.8: need to ensure request isn't consumed
|
|
89
|
-
// before delayed handler gets run
|
|
90
|
-
if (agent.processInfo.isv0_8) {
|
|
91
|
-
req.pause();
|
|
49
|
+
function invokeOriginal(callback, self, args, ot_api, span, otCtx, req, res) {
|
|
50
|
+
if (ot_api) {
|
|
51
|
+
ot_api.context.with(ot_api.trace.setSpan(otCtx, span), () => {
|
|
52
|
+
ot_api.context.bind(ot_api.context.active(), req);
|
|
53
|
+
ot_api.context.bind(ot_api.context.active(), res);
|
|
54
|
+
return callback.apply(self, args);
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
return callback.apply(self, args);
|
|
92
58
|
}
|
|
93
|
-
|
|
94
|
-
return self.agent.context.bind(function () {
|
|
95
|
-
if (didRun) return;
|
|
96
|
-
didRun = true;
|
|
97
|
-
|
|
98
|
-
// Node 0.8: safe to resume the request now
|
|
99
|
-
// we're ready to process it
|
|
100
|
-
if (agent.processInfo.isv0_8) {
|
|
101
|
-
req.resume();
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
var oldThreadId = thread.current();
|
|
105
|
-
thread.resume(threadId);
|
|
106
|
-
try {
|
|
107
|
-
callback = agent.proxy.wrapWithThreadProxyIfEnabled(callback);
|
|
108
|
-
callback.apply(origSelf, origArgs);
|
|
109
|
-
} catch (e) {
|
|
110
|
-
self.finalizeTransaction(e, profiler, time, transaction, req, res);
|
|
111
|
-
throw e;
|
|
112
|
-
} finally {
|
|
113
|
-
thread.resume(oldThreadId);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
59
|
}
|
|
117
60
|
|
|
118
61
|
HttpEntryProbe.prototype.__createRequestHandler = function (callback, isHTTPs) {
|
|
@@ -129,66 +72,43 @@ HttpEntryProbe.prototype.__createRequestHandler = function (callback, isHTTPs) {
|
|
|
129
72
|
self.agent.context.run(requestHandler, req, res);
|
|
130
73
|
});
|
|
131
74
|
} else {
|
|
132
|
-
|
|
75
|
+
if (
|
|
76
|
+
self.agent.opts.enableGraphQL
|
|
77
|
+
&& self.agent.libagentConnector.getBusinessTransactionQueryType(
|
|
78
|
+
"NODEJS_WEB",
|
|
79
|
+
utility.createBtNamingWrapper(req)
|
|
80
|
+
) == utility.constants.GRAPHQL_QUERY_TYPE
|
|
81
|
+
) {
|
|
82
|
+
self.agent.context.run(callback, req, res);
|
|
83
|
+
} else {
|
|
84
|
+
self.agent.context.run(requestHandler, req, res);
|
|
85
|
+
}
|
|
133
86
|
}
|
|
134
87
|
};
|
|
135
88
|
|
|
136
89
|
function requestHandler(req, res) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
var time = profiler.time(true);
|
|
90
|
+
let profiler = self.agent.profiler;
|
|
91
|
+
let time = profiler.time(true);
|
|
140
92
|
|
|
141
93
|
self.agent.metricsManager.addMetric(self.agent.metricsManager.HTTP_INCOMING_COUNT, 1);
|
|
142
94
|
|
|
143
|
-
|
|
144
|
-
self.agent.context.set('threadId', transaction.threadId);
|
|
145
|
-
req.__appdThreadId = transaction.threadId;
|
|
146
|
-
|
|
147
|
-
transaction.url = req.url;
|
|
148
|
-
transaction.method = req.method;
|
|
149
|
-
transaction.requestHeaders = req.headers;
|
|
95
|
+
let { transaction, span, otContext } = HttpCommon.startTransactionHandler(req, res, self.agent, isHTTPs, self.tracer, self.ot_api);
|
|
150
96
|
|
|
151
|
-
var
|
|
97
|
+
var threadId = transaction.threadId;
|
|
98
|
+
self.agent.context.run(() => {
|
|
99
|
+
|
|
100
|
+
var oldThreadId = self.agent.thread.current();
|
|
101
|
+
self.agent.thread.resume(threadId);
|
|
152
102
|
|
|
153
|
-
if (!transaction.corrHeader && eumEnabled) {
|
|
154
|
-
proxy.before(res, 'writeHead', function (obj) {
|
|
155
|
-
if (!transaction.isFinished) {
|
|
156
|
-
var eumCookie = self.agent.eum.newEumCookie(transaction, req, obj, isHTTPs);
|
|
157
|
-
eumCookie.build();
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
proxy.after(res, 'end', function () {
|
|
163
|
-
self.finalizeTransaction(null, profiler, time, transaction, req, res);
|
|
164
|
-
transaction = null;
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
if (self.agent.opts.btEntryPointDelayDisabled) {
|
|
168
103
|
try {
|
|
169
|
-
|
|
170
|
-
return threadProxyWrappedCb.apply(this, arguments);
|
|
104
|
+
return invokeOriginal(callback, this, arguments, self.ot_api, span, otContext, req, res);
|
|
171
105
|
} catch (e) {
|
|
172
|
-
|
|
106
|
+
HttpCommon.finalizeTransaction(e, profiler, time, transaction, req, res, span);
|
|
173
107
|
transaction = null;
|
|
174
108
|
throw e;
|
|
109
|
+
} finally {
|
|
110
|
+
self.agent.thread.resume(oldThreadId);
|
|
175
111
|
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
var delayedCallback = createBTCallback(self.agent,
|
|
179
|
-
profiler,
|
|
180
|
-
time,
|
|
181
|
-
transaction,
|
|
182
|
-
req, res,
|
|
183
|
-
self.agent.thread,
|
|
184
|
-
callback,
|
|
185
|
-
self,
|
|
186
|
-
this,
|
|
187
|
-
arguments);
|
|
188
|
-
|
|
189
|
-
transaction.once('ignoreTransactionCbExecute', delayedCallback);
|
|
190
|
-
transaction.emit('delayedCallbackReady');
|
|
191
|
-
transaction.once('btInfoResponse', delayedCallback);
|
|
192
|
-
self.delayedCallbackQueue.push({ ts: Date.now(), func: delayedCallback });
|
|
112
|
+
});
|
|
193
113
|
}
|
|
194
114
|
};
|