Outlook_Addin_LLM/node_modules/applicationinsights/out/AutoCollection/HttpRequests.js

238 lines
13 KiB
JavaScript

"use strict";
var http = require("http");
var https = require("https");
var Logging = require("../Library/Logging");
var Util = require("../Library/Util");
var RequestResponseHeaders = require("../Library/RequestResponseHeaders");
var HttpRequestParser = require("./HttpRequestParser");
var CorrelationContextManager_1 = require("./CorrelationContextManager");
var AutoCollectPerformance = require("./Performance");
var AutoCollectHttpRequests = (function () {
function AutoCollectHttpRequests(client) {
if (!!AutoCollectHttpRequests.INSTANCE) {
throw new Error("Server request tracking should be configured from the applicationInsights object");
}
AutoCollectHttpRequests.INSTANCE = this;
this._client = client;
}
AutoCollectHttpRequests.prototype.enable = function (isEnabled) {
this._isEnabled = isEnabled;
// Autocorrelation requires automatic monitoring of incoming server requests
// Disabling autocollection but enabling autocorrelation will still enable
// request monitoring but will not produce request events
if ((this._isAutoCorrelating || this._isEnabled || AutoCollectPerformance.isEnabled()) && !this._isInitialized) {
this.useAutoCorrelation(this._isAutoCorrelating);
this._initialize();
}
};
AutoCollectHttpRequests.prototype.useAutoCorrelation = function (isEnabled, forceClsHooked) {
if (isEnabled && !this._isAutoCorrelating) {
CorrelationContextManager_1.CorrelationContextManager.enable(forceClsHooked);
}
else if (!isEnabled && this._isAutoCorrelating) {
CorrelationContextManager_1.CorrelationContextManager.disable();
}
this._isAutoCorrelating = isEnabled;
};
AutoCollectHttpRequests.prototype.isInitialized = function () {
return this._isInitialized;
};
AutoCollectHttpRequests.prototype.isAutoCorrelating = function () {
return this._isAutoCorrelating;
};
AutoCollectHttpRequests.prototype._generateCorrelationContext = function (requestParser) {
if (!this._isAutoCorrelating) {
return;
}
return CorrelationContextManager_1.CorrelationContextManager.generateContextObject(requestParser.getOperationId(this._client.context.tags), requestParser.getRequestId(), requestParser.getOperationName(this._client.context.tags), requestParser.getCorrelationContextHeader(), requestParser.getTraceparent(), requestParser.getTracestate());
};
AutoCollectHttpRequests.prototype._initialize = function () {
var _this = this;
this._isInitialized = true;
var wrapOnRequestHandler = function (onRequest) {
if (!onRequest) {
return undefined;
}
if (typeof onRequest !== 'function') {
throw new Error('onRequest handler must be a function');
}
return function (request, response) {
CorrelationContextManager_1.CorrelationContextManager.wrapEmitter(request);
CorrelationContextManager_1.CorrelationContextManager.wrapEmitter(response);
var shouldCollect = request && !request[AutoCollectHttpRequests.alreadyAutoCollectedFlag];
if (request && shouldCollect) {
// Set up correlation context
var requestParser_1 = new HttpRequestParser(request);
var correlationContext = _this._generateCorrelationContext(requestParser_1);
// Note: Check for if correlation is enabled happens within this method.
// If not enabled, function will directly call the callback.
CorrelationContextManager_1.CorrelationContextManager.runWithContext(correlationContext, function () {
if (_this._isEnabled) {
// Mark as auto collected
request[AutoCollectHttpRequests.alreadyAutoCollectedFlag] = true;
// Auto collect request
AutoCollectHttpRequests.trackRequest(_this._client, { request: request, response: response }, requestParser_1);
}
if (typeof onRequest === "function") {
onRequest(request, response);
}
});
}
else {
if (typeof onRequest === "function") {
onRequest(request, response);
}
}
};
};
// The `http.createServer` function will instantiate a new http.Server object.
// Inside the Server's constructor, it is using addListener to register the
// onRequest handler. So there are two ways to inject the wrapped onRequest handler:
// 1) Overwrite Server.prototype.addListener (and .on()) globally and not patching
// the http.createServer call. Or
// 2) Overwrite the http.createServer method and add a patched addListener to the
// fresh server instance. This seems more stable for possible future changes as
// it also covers the case where the Server might not use addListener to manage
// the callback internally.
// And also as long as the constructor uses addListener to add the handle, it is
// ok to patch the addListener after construction only. Because if we would patch
// the prototype one and the createServer method, we would wrap the handler twice
// in case of the constructor call.
var wrapServerEventHandler = function (server) {
var originalAddListener = server.addListener.bind(server);
server.addListener = function (eventType, eventHandler) {
switch (eventType) {
case 'request':
case 'checkContinue':
return originalAddListener(eventType, wrapOnRequestHandler(eventHandler));
default:
return originalAddListener(eventType, eventHandler);
}
};
// on is an alias to addListener only
server.on = server.addListener;
};
var originalHttpServer = http.createServer;
// options parameter was added in Node.js v9.6.0, v8.12.0
// function createServer(requestListener?: RequestListener): Server;
// function createServer(options: ServerOptions, requestListener?: RequestListener): Server;
http.createServer = function (param1, param2) {
// todo: get a pointer to the server so the IP address can be read from server.address
if (param2 && typeof param2 === 'function') {
var server = originalHttpServer(param1, wrapOnRequestHandler(param2));
wrapServerEventHandler(server);
return server;
}
else {
var server = originalHttpServer(wrapOnRequestHandler(param1));
wrapServerEventHandler(server);
return server;
}
};
var originalHttpsServer = https.createServer;
https.createServer = function (options, onRequest) {
var server = originalHttpsServer(options, wrapOnRequestHandler(onRequest));
wrapServerEventHandler(server);
return server;
};
};
/**
* Tracks a request synchronously (doesn't wait for response 'finish' event)
*/
AutoCollectHttpRequests.trackRequestSync = function (client, telemetry) {
if (!telemetry.request || !telemetry.response || !client) {
Logging.info("AutoCollectHttpRequests.trackRequestSync was called with invalid parameters: ", !telemetry.request, !telemetry.response, !client);
return;
}
AutoCollectHttpRequests.addResponseCorrelationIdHeader(client, telemetry.response);
// store data about the request
var correlationContext = CorrelationContextManager_1.CorrelationContextManager.getCurrentContext();
var requestParser = new HttpRequestParser(telemetry.request, (correlationContext && correlationContext.operation.parentId));
// Overwrite correlation context with request parser results
if (correlationContext) {
correlationContext.operation.id = requestParser.getOperationId(client.context.tags) || correlationContext.operation.id;
correlationContext.operation.name = requestParser.getOperationName(client.context.tags) || correlationContext.operation.name;
correlationContext.operation.parentId = requestParser.getRequestId() || correlationContext.operation.parentId;
correlationContext.customProperties.addHeaderData(requestParser.getCorrelationContextHeader());
}
AutoCollectHttpRequests.endRequest(client, requestParser, telemetry, telemetry.duration, telemetry.error);
};
/**
* Tracks a request by listening to the response 'finish' event
*/
AutoCollectHttpRequests.trackRequest = function (client, telemetry, _requestParser) {
if (!telemetry.request || !telemetry.response || !client) {
Logging.info("AutoCollectHttpRequests.trackRequest was called with invalid parameters: ", !telemetry.request, !telemetry.response, !client);
return;
}
// store data about the request
var correlationContext = CorrelationContextManager_1.CorrelationContextManager.getCurrentContext();
var requestParser = _requestParser || new HttpRequestParser(telemetry.request, correlationContext && correlationContext.operation.parentId);
if (Util.canIncludeCorrelationHeader(client, requestParser.getUrl())) {
AutoCollectHttpRequests.addResponseCorrelationIdHeader(client, telemetry.response);
}
// Overwrite correlation context with request parser results (if not an automatic track. we've already precalculated the correlation context in that case)
if (correlationContext && !_requestParser) {
correlationContext.operation.id = requestParser.getOperationId(client.context.tags) || correlationContext.operation.id;
correlationContext.operation.name = requestParser.getOperationName(client.context.tags) || correlationContext.operation.name;
correlationContext.operation.parentId = requestParser.getOperationParentId(client.context.tags) || correlationContext.operation.parentId;
correlationContext.customProperties.addHeaderData(requestParser.getCorrelationContextHeader());
}
// response listeners
if (telemetry.response.once) {
telemetry.response.once("finish", function () {
AutoCollectHttpRequests.endRequest(client, requestParser, telemetry, null, null);
});
}
// track a failed request if an error is emitted
if (telemetry.request.on) {
telemetry.request.on("error", function (error) {
AutoCollectHttpRequests.endRequest(client, requestParser, telemetry, null, error);
});
}
};
/**
* Add the target correlationId to the response headers, if not already provided.
*/
AutoCollectHttpRequests.addResponseCorrelationIdHeader = function (client, response) {
if (client.config && client.config.correlationId &&
response.getHeader && response.setHeader && !response.headersSent) {
var correlationHeader = response.getHeader(RequestResponseHeaders.requestContextHeader);
Util.safeIncludeCorrelationHeader(client, response, correlationHeader);
}
};
AutoCollectHttpRequests.endRequest = function (client, requestParser, telemetry, ellapsedMilliseconds, error) {
if (error) {
requestParser.onError(error, ellapsedMilliseconds);
}
else {
requestParser.onResponse(telemetry.response, ellapsedMilliseconds);
}
var requestTelemetry = requestParser.getRequestTelemetry(telemetry);
requestTelemetry.tagOverrides = requestParser.getRequestTags(client.context.tags);
if (telemetry.tagOverrides) {
for (var key in telemetry.tagOverrides) {
requestTelemetry.tagOverrides[key] = telemetry.tagOverrides[key];
}
}
var legacyRootId = requestParser.getLegacyRootId();
if (legacyRootId) {
requestTelemetry.properties["ai_legacyRootId"] = legacyRootId;
}
requestTelemetry.contextObjects = requestTelemetry.contextObjects || {};
requestTelemetry.contextObjects["http.ServerRequest"] = telemetry.request;
requestTelemetry.contextObjects["http.ServerResponse"] = telemetry.response;
client.trackRequest(requestTelemetry);
};
AutoCollectHttpRequests.prototype.dispose = function () {
AutoCollectHttpRequests.INSTANCE = null;
this.enable(false);
this._isInitialized = false;
CorrelationContextManager_1.CorrelationContextManager.disable();
this._isAutoCorrelating = false;
};
AutoCollectHttpRequests.alreadyAutoCollectedFlag = '_appInsightsAutoCollected';
return AutoCollectHttpRequests;
}());
module.exports = AutoCollectHttpRequests;
//# sourceMappingURL=HttpRequests.js.map