in AutoCollection/HttpDependencies.ts [134:244]
public static trackRequest(client: TelemetryClient, telemetry: Contracts.NodeHttpDependencyTelemetry) {
if (!telemetry.options || !telemetry.request || !client) {
Logging.info("AutoCollectHttpDependencies.trackRequest was called with invalid parameters: ", !telemetry.options, !telemetry.request, !client);
return;
}
let requestParser = new HttpDependencyParser(telemetry.options, telemetry.request);
const currentContext = CorrelationContextManager.getCurrentContext();
let uniqueRequestId: string;
let uniqueTraceparent: string;
if (currentContext && currentContext.operation && currentContext.operation.traceparent && Traceparent.isValidTraceId(currentContext.operation.traceparent.traceId)) {
currentContext.operation.traceparent.updateSpanId();
uniqueRequestId = currentContext.operation.traceparent.getBackCompatRequestId();
} else if (CorrelationIdManager.w3cEnabled) {
// Start an operation now so that we can include the w3c headers in the outgoing request
const traceparent = new Traceparent();
uniqueTraceparent = traceparent.toString();
uniqueRequestId = traceparent.getBackCompatRequestId();
} else {
uniqueRequestId = currentContext && currentContext.operation && (currentContext.operation.parentId + AutoCollectHttpDependencies.requestNumber++ + '.');
}
// Add the source correlationId to the request headers, if a value was not already provided.
// The getHeader/setHeader methods aren't available on very old Node versions, and
// are not included in the v0.10 type declarations currently used. So check if the
// methods exist before invoking them.
if (Util.canIncludeCorrelationHeader(client, requestParser.getUrl()) && telemetry.request.getHeader && telemetry.request.setHeader) {
if (client.config && client.config.correlationId) {
// getHeader returns "any" type in newer versions of node. In basic scenarios, this will be <string | string[] | number>, but could be modified to anything else via middleware
const correlationHeader = <any>telemetry.request.getHeader(RequestResponseHeaders.requestContextHeader)
try {
Util.safeIncludeCorrelationHeader(client, telemetry.request, correlationHeader);
} catch (err) {
Logging.warn("Request-Context header could not be set. Correlation of requests may be lost", err);
}
if (currentContext && currentContext.operation) {
try {
telemetry.request.setHeader(RequestResponseHeaders.requestIdHeader, uniqueRequestId);
// Also set legacy headers
if (!client.config.ignoreLegacyHeaders) {
telemetry.request.setHeader(RequestResponseHeaders.parentIdHeader, currentContext.operation.id);
telemetry.request.setHeader(RequestResponseHeaders.rootIdHeader, uniqueRequestId);
}
// Set W3C headers, if available
if (uniqueTraceparent || currentContext.operation.traceparent) {
telemetry.request.setHeader(RequestResponseHeaders.traceparentHeader, uniqueTraceparent || currentContext.operation.traceparent.toString());
} else if (CorrelationIdManager.w3cEnabled) {
// should never get here since we set uniqueTraceparent above for the w3cEnabled scenario
const traceparent = new Traceparent().toString();
telemetry.request.setHeader(RequestResponseHeaders.traceparentHeader, traceparent);
}
if (currentContext.operation.tracestate) {
const tracestate = currentContext.operation.tracestate.toString();
if (tracestate) {
telemetry.request.setHeader(RequestResponseHeaders.traceStateHeader, tracestate);
}
}
const correlationContextHeader = (<PrivateCustomProperties>currentContext.customProperties).serializeToHeader();
if (correlationContextHeader) {
telemetry.request.setHeader(RequestResponseHeaders.correlationContextHeader, correlationContextHeader);
}
} catch (err) {
Logging.warn("Correlation headers could not be set. Correlation of requests may be lost.", err);
}
}
}
}
// Collect dependency telemetry about the request when it finishes.
if (telemetry.request.on) {
telemetry.request.on('response', (response: http.ClientResponse) => {
requestParser.onResponse(response);
var dependencyTelemetry = requestParser.getDependencyTelemetry(telemetry, uniqueRequestId);
dependencyTelemetry.contextObjects = dependencyTelemetry.contextObjects || {};
dependencyTelemetry.contextObjects["http.RequestOptions"] = telemetry.options;
dependencyTelemetry.contextObjects["http.ClientRequest"] = telemetry.request;
dependencyTelemetry.contextObjects["http.ClientResponse"] = response;
client.trackDependency(dependencyTelemetry);
});
telemetry.request.on('error', (error: Error) => {
requestParser.onError(error);
var dependencyTelemetry = requestParser.getDependencyTelemetry(telemetry, uniqueRequestId);
dependencyTelemetry.contextObjects = dependencyTelemetry.contextObjects || {};
dependencyTelemetry.contextObjects["http.RequestOptions"] = telemetry.options;
dependencyTelemetry.contextObjects["http.ClientRequest"] = telemetry.request;
dependencyTelemetry.contextObjects["Error"] = error;
client.trackDependency(dependencyTelemetry);
});
telemetry.request.on('abort', () => {
requestParser.onError(new Error());
var dependencyTelemetry = requestParser.getDependencyTelemetry(telemetry, uniqueRequestId);
dependencyTelemetry.contextObjects = dependencyTelemetry.contextObjects || {};
dependencyTelemetry.contextObjects["http.RequestOptions"] = telemetry.options;
dependencyTelemetry.contextObjects["http.ClientRequest"] = telemetry.request;
client.trackDependency(dependencyTelemetry);
});
}
}