From c2f53c09f29134dee1634304fc97d5faa507f4ad Mon Sep 17 00:00:00 2001 From: Sergey Kanzhelev Date: Wed, 4 Jan 2017 16:33:37 -0800 Subject: [PATCH 1/5] extend telemetry client to pass the context --- AutoCollection/ClientRequests.ts | 4 ++-- Library/Client.ts | 13 +++++++------ Tests/Library/Client.tests.ts | 17 +++++++++++++++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/AutoCollection/ClientRequests.ts b/AutoCollection/ClientRequests.ts index 4a2dc5faa..8fd595014 100644 --- a/AutoCollection/ClientRequests.ts +++ b/AutoCollection/ClientRequests.ts @@ -98,11 +98,11 @@ class AutoCollectClientRequests { if (request.on) { request.on('response', (response: http.ClientResponse) => { requestParser.onResponse(response, properties); - client.track(requestParser.getDependencyData()); + client.track(requestParser.getDependencyData(), null, { requestOptions: requestOptions, request: request, response: response }); }); request.on('error', (e: Error) => { requestParser.onError(e, properties); - client.track(requestParser.getDependencyData()); + client.track(requestParser.getDependencyData(), null, { requestOptions: requestOptions, request: request, error: e }); }); } } diff --git a/Library/Client.ts b/Library/Client.ts index d26a21a46..01e123d3e 100644 --- a/Library/Client.ts +++ b/Library/Client.ts @@ -235,10 +235,11 @@ class Client { */ public track( data: ContractsModule.Contracts.Data, - tagOverrides?: { [key: string]: string; }) { + tagOverrides?: { [key: string]: string; }, + contextObject?: any) { var envelope = this.getEnvelope(data, tagOverrides); - var accepted = this.runTelemetryProcessors(envelope); + var accepted = this.runTelemetryProcessors(envelope, contextObject); if (accepted) { this.channel.send(envelope); @@ -249,9 +250,9 @@ class Client { * Adds telemetry processor to the collection. Telemetry processors will be called one by one * before telemetry item is pushed for sending and in the order they were added. * - * @param telemetryProcessor function, takes Envelope, returns boolean + * @param telemetryProcessor function, takes Envelope, and optional context object and returns boolean */ - public addTelemetryProcessor(telemetryProcessor: (envelope: ContractsModule.Contracts.Envelope) => boolean) { + public addTelemetryProcessor(telemetryProcessor: (envelope: ContractsModule.Contracts.Envelope, contextObject?: any) => boolean) { this._telemetryProcessors.push(telemetryProcessor); } @@ -270,7 +271,7 @@ class Client { return [array[0], parseInt(array[1])]; } - private runTelemetryProcessors(envelope: ContractsModule.Contracts.Envelope): boolean { + private runTelemetryProcessors(envelope: ContractsModule.Contracts.Envelope, contextObject: any): boolean { var accepted = true; var telemetryProcessorsCount = this._telemetryProcessors.length; @@ -283,7 +284,7 @@ class Client { try { var processor = this._telemetryProcessors[i]; if (processor) { - if (processor.apply(null, [envelope]) === false) { + if (processor.apply(null, [envelope, contextObject]) === false) { accepted = false; break; } diff --git a/Tests/Library/Client.tests.ts b/Tests/Library/Client.tests.ts index 8cb84a9b3..ae1964eb1 100644 --- a/Tests/Library/Client.tests.ts +++ b/Tests/Library/Client.tests.ts @@ -713,6 +713,23 @@ describe("Library/Client", () => { assert.equal(actualData.name, expectedName, "envelope name should be changed by the processor"); }); + it("telemetry processor can access the context object", () => { + trackStub.restore(); + var expectedName = "I was here"; + + client.addTelemetryProcessor((env, contextObject) => { + env.name = contextObject; + return true; + }); + + client.track(mockData, null, expectedName); + + assert.equal(sendStub.callCount, 1, "send called once"); + + var actualData = sendStub.firstCall.args[0] as ContractsModule.Contracts.Envelope; + assert.equal(actualData.name, expectedName, "envelope name should be changed by the processor"); + }); + it("telemetry processors are executed in a right order", () => { trackStub.restore(); From 1860210b82533de4a17a6b50b0018a048706bae9 Mon Sep 17 00:00:00 2001 From: Sergey Kanzhelev Date: Thu, 5 Jan 2017 18:19:06 -0800 Subject: [PATCH 2/5] added context to the server requests --- AutoCollection/ClientRequests.ts | 7 +++++-- AutoCollection/ServerRequests.ts | 12 +++++++----- Library/ContextObject/ClientRequestContextObject.ts | 11 +++++++++++ Library/ContextObject/ServerRequestContextObject.ts | 9 +++++++++ 4 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 Library/ContextObject/ClientRequestContextObject.ts create mode 100644 Library/ContextObject/ServerRequestContextObject.ts diff --git a/AutoCollection/ClientRequests.ts b/AutoCollection/ClientRequests.ts index 8fd595014..eb267b554 100644 --- a/AutoCollection/ClientRequests.ts +++ b/AutoCollection/ClientRequests.ts @@ -10,6 +10,7 @@ import Logging = require("../Library/Logging"); import Util = require("../Library/Util"); import RequestResponseHeaders = require("../Library/RequestResponseHeaders"); import ClientRequestParser = require("./ClientRequestParser"); +import ClientRequestContextObject = require("../Library/ContextObject/ClientRequestContextObject"); class AutoCollectClientRequests { public static disableCollectionRequestOption = 'disableAppInsightsAutoCollection'; @@ -98,11 +99,13 @@ class AutoCollectClientRequests { if (request.on) { request.on('response', (response: http.ClientResponse) => { requestParser.onResponse(response, properties); - client.track(requestParser.getDependencyData(), null, { requestOptions: requestOptions, request: request, response: response }); + var context : ClientRequestContextObject = { requestOptions: requestOptions, request: request, response: response, error: null }; + client.track(requestParser.getDependencyData(), null, context); }); request.on('error', (e: Error) => { requestParser.onError(e, properties); - client.track(requestParser.getDependencyData(), null, { requestOptions: requestOptions, request: request, error: e }); + var context : ClientRequestContextObject = { requestOptions: requestOptions, request: request, response: null, error: e }; + client.track(requestParser.getDependencyData(), null, context); }); } } diff --git a/AutoCollection/ServerRequests.ts b/AutoCollection/ServerRequests.ts index 8a96bac45..73bf7d969 100644 --- a/AutoCollection/ServerRequests.ts +++ b/AutoCollection/ServerRequests.ts @@ -10,6 +10,7 @@ import Logging = require("../Library/Logging"); import Util = require("../Library/Util"); import RequestResponseHeaders = require("../Library/RequestResponseHeaders"); import ServerRequestParser = require("./ServerRequestParser"); +import ServerRequestContextObject = require("../Library/ContextObject/ServerRequestContextObject"); class AutoCollectServerRequests { @@ -84,7 +85,7 @@ class AutoCollectServerRequests { // store data about the request var requestParser = new ServerRequestParser(request); - AutoCollectServerRequests.endRequest(client, requestParser, response, ellapsedMilliseconds, properties, error); + AutoCollectServerRequests.endRequest(client, requestParser, request, response, ellapsedMilliseconds, properties, error); } /** @@ -106,14 +107,14 @@ class AutoCollectServerRequests { // response listeners if (response.once) { response.once("finish", () => { - AutoCollectServerRequests.endRequest(client, requestParser, response, null, properties, null); + AutoCollectServerRequests.endRequest(client, requestParser, request, response, null, properties, null); }); } // track a failed request if an error is emitted if (request.on) { request.on("error", (error:any) => { - AutoCollectServerRequests.endRequest(client, requestParser, response, null, properties, error); + AutoCollectServerRequests.endRequest(client, requestParser, request, response, null, properties, error); }); } } @@ -131,7 +132,7 @@ class AutoCollectServerRequests { } } - private static endRequest(client: Client, requestParser: ServerRequestParser, response: http.ServerResponse, ellapsedMilliseconds?: number, properties?: { [key: string]: string}, error?: any) { + private static endRequest(client: Client, requestParser: ServerRequestParser, request: http.ServerRequest, response: http.ServerResponse, ellapsedMilliseconds?: number, properties?: { [key: string]: string}, error?: any) { if (error) { requestParser.onError(error, properties, ellapsedMilliseconds); } else { @@ -140,7 +141,8 @@ class AutoCollectServerRequests { var data = requestParser.getRequestData(); var tags = requestParser.getRequestTags(client.context.tags); - client.track(data, tags); + var context : ServerRequestContextObject = {request: null, response: response}; + client.track(data, tags, context); } public dispose() { diff --git a/Library/ContextObject/ClientRequestContextObject.ts b/Library/ContextObject/ClientRequestContextObject.ts new file mode 100644 index 000000000..b9ffc5af7 --- /dev/null +++ b/Library/ContextObject/ClientRequestContextObject.ts @@ -0,0 +1,11 @@ +/// +import http = require("http"); + +declare class ClientRequestContextObject { + requestOptions: http.RequestOptions; + request: http.ClientRequest; + response: http.ClientResponse; + error: Error; +} + +export = ClientRequestContextObject; diff --git a/Library/ContextObject/ServerRequestContextObject.ts b/Library/ContextObject/ServerRequestContextObject.ts new file mode 100644 index 000000000..6d02c0e94 --- /dev/null +++ b/Library/ContextObject/ServerRequestContextObject.ts @@ -0,0 +1,9 @@ +/// +import http = require("http"); + +declare class ServerRequestContextObject { + request: http.ServerRequest; + response: http.ServerResponse; +} + +export = ServerRequestContextObject; From 023d83e844ac913cde1b93dd94c05dcab6a57adf Mon Sep 17 00:00:00 2001 From: Sergey Kanzhelev Date: Thu, 5 Jan 2017 18:21:41 -0800 Subject: [PATCH 3/5] make context object more strongly typed --- Library/Client.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Library/Client.ts b/Library/Client.ts index 01e123d3e..0e178bee6 100644 --- a/Library/Client.ts +++ b/Library/Client.ts @@ -15,6 +15,8 @@ import ClientRequestTracking = require("../AutoCollection/ClientRequests"); import Sender = require("./Sender"); import Util = require("./Util"); import Logging = require("./Logging"); +import ServerRequestContextObject = require("../Library/contextObject/ServerRequestContextObject"); +import ClientRequestContextObject = require("../Library/contextObject/ClientRequestContextObject"); class Client { @@ -236,7 +238,7 @@ class Client { public track( data: ContractsModule.Contracts.Data, tagOverrides?: { [key: string]: string; }, - contextObject?: any) { + contextObject?: ServerRequestContextObject | ClientRequestContextObject | any) { var envelope = this.getEnvelope(data, tagOverrides); var accepted = this.runTelemetryProcessors(envelope, contextObject); From fcb40762ac8a2a97a713b2c8eafccb47780373e4 Mon Sep 17 00:00:00 2001 From: Sergey Kanzhelev Date: Thu, 5 Jan 2017 18:32:43 -0800 Subject: [PATCH 4/5] upper case in folder name --- Library/Client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Client.ts b/Library/Client.ts index 0e178bee6..9b3a152d9 100644 --- a/Library/Client.ts +++ b/Library/Client.ts @@ -15,8 +15,8 @@ import ClientRequestTracking = require("../AutoCollection/ClientRequests"); import Sender = require("./Sender"); import Util = require("./Util"); import Logging = require("./Logging"); -import ServerRequestContextObject = require("../Library/contextObject/ServerRequestContextObject"); -import ClientRequestContextObject = require("../Library/contextObject/ClientRequestContextObject"); +import ServerRequestContextObject = require("../Library/ContextObject/ServerRequestContextObject"); +import ClientRequestContextObject = require("../Library/ContextObject/ClientRequestContextObject"); class Client { From 4cbd3d7389ce3b5b785a37c157a7f087649f28f8 Mon Sep 17 00:00:00 2001 From: Sergey Kanzhelev Date: Wed, 11 Jan 2017 22:05:41 -0800 Subject: [PATCH 5/5] changed strongly typed context object to the dictionary --- .vscode/settings.json | 3 ++- AutoCollection/ClientRequests.ts | 5 ++--- AutoCollection/ServerRequests.ts | 3 +-- Library/Client.ts | 12 +++++------- Library/ContextObject/ClientRequestContextObject.ts | 11 ----------- Library/ContextObject/ServerRequestContextObject.ts | 9 --------- Tests/Library/Client.tests.ts | 6 +++--- 7 files changed, 13 insertions(+), 36 deletions(-) delete mode 100644 Library/ContextObject/ClientRequestContextObject.ts delete mode 100644 Library/ContextObject/ServerRequestContextObject.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index c22468949..12e68f782 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,8 @@ { "files.exclude": { "**/*.js": { "when": "$(basename).ts"}, - "**/*.js.map": true + "**/*.js.map": true, + "**/*.d.ts": true }, "typescript.tsdk": "./node_modules/typescript/lib" } \ No newline at end of file diff --git a/AutoCollection/ClientRequests.ts b/AutoCollection/ClientRequests.ts index eb267b554..5895fc5fe 100644 --- a/AutoCollection/ClientRequests.ts +++ b/AutoCollection/ClientRequests.ts @@ -10,7 +10,6 @@ import Logging = require("../Library/Logging"); import Util = require("../Library/Util"); import RequestResponseHeaders = require("../Library/RequestResponseHeaders"); import ClientRequestParser = require("./ClientRequestParser"); -import ClientRequestContextObject = require("../Library/ContextObject/ClientRequestContextObject"); class AutoCollectClientRequests { public static disableCollectionRequestOption = 'disableAppInsightsAutoCollection'; @@ -99,12 +98,12 @@ class AutoCollectClientRequests { if (request.on) { request.on('response', (response: http.ClientResponse) => { requestParser.onResponse(response, properties); - var context : ClientRequestContextObject = { requestOptions: requestOptions, request: request, response: response, error: null }; + var context : { [name: string]: any; } = { "http.RequestOptions": requestOptions, "http.ClientRequest": request, "http.ClientResponse": response }; client.track(requestParser.getDependencyData(), null, context); }); request.on('error', (e: Error) => { requestParser.onError(e, properties); - var context : ClientRequestContextObject = { requestOptions: requestOptions, request: request, response: null, error: e }; + var context : { [name: string]: any; } = { "http.RequestOptions": requestOptions, "http.ClientRequest": request, "Error": e }; client.track(requestParser.getDependencyData(), null, context); }); } diff --git a/AutoCollection/ServerRequests.ts b/AutoCollection/ServerRequests.ts index 73bf7d969..d927a87b1 100644 --- a/AutoCollection/ServerRequests.ts +++ b/AutoCollection/ServerRequests.ts @@ -10,7 +10,6 @@ import Logging = require("../Library/Logging"); import Util = require("../Library/Util"); import RequestResponseHeaders = require("../Library/RequestResponseHeaders"); import ServerRequestParser = require("./ServerRequestParser"); -import ServerRequestContextObject = require("../Library/ContextObject/ServerRequestContextObject"); class AutoCollectServerRequests { @@ -141,7 +140,7 @@ class AutoCollectServerRequests { var data = requestParser.getRequestData(); var tags = requestParser.getRequestTags(client.context.tags); - var context : ServerRequestContextObject = {request: null, response: response}; + var context : { [name: string]: any; } = {"http.ServerRequest": request, "http.ServerResponse": response}; client.track(data, tags, context); } diff --git a/Library/Client.ts b/Library/Client.ts index 9b3a152d9..557cfd23c 100644 --- a/Library/Client.ts +++ b/Library/Client.ts @@ -15,8 +15,6 @@ import ClientRequestTracking = require("../AutoCollection/ClientRequests"); import Sender = require("./Sender"); import Util = require("./Util"); import Logging = require("./Logging"); -import ServerRequestContextObject = require("../Library/ContextObject/ServerRequestContextObject"); -import ClientRequestContextObject = require("../Library/ContextObject/ClientRequestContextObject"); class Client { @@ -238,10 +236,10 @@ class Client { public track( data: ContractsModule.Contracts.Data, tagOverrides?: { [key: string]: string; }, - contextObject?: ServerRequestContextObject | ClientRequestContextObject | any) { + contextObjects?: { [name: string]: any; }) { var envelope = this.getEnvelope(data, tagOverrides); - var accepted = this.runTelemetryProcessors(envelope, contextObject); + var accepted = this.runTelemetryProcessors(envelope, contextObjects); if (accepted) { this.channel.send(envelope); @@ -254,7 +252,7 @@ class Client { * * @param telemetryProcessor function, takes Envelope, and optional context object and returns boolean */ - public addTelemetryProcessor(telemetryProcessor: (envelope: ContractsModule.Contracts.Envelope, contextObject?: any) => boolean) { + public addTelemetryProcessor(telemetryProcessor: (envelope: ContractsModule.Contracts.Envelope, contextObjects?: { [name: string]: any; }) => boolean) { this._telemetryProcessors.push(telemetryProcessor); } @@ -273,7 +271,7 @@ class Client { return [array[0], parseInt(array[1])]; } - private runTelemetryProcessors(envelope: ContractsModule.Contracts.Envelope, contextObject: any): boolean { + private runTelemetryProcessors(envelope: ContractsModule.Contracts.Envelope, contextObjects: { [name: string]: any; }): boolean { var accepted = true; var telemetryProcessorsCount = this._telemetryProcessors.length; @@ -286,7 +284,7 @@ class Client { try { var processor = this._telemetryProcessors[i]; if (processor) { - if (processor.apply(null, [envelope, contextObject]) === false) { + if (processor.apply(null, [envelope, contextObjects]) === false) { accepted = false; break; } diff --git a/Library/ContextObject/ClientRequestContextObject.ts b/Library/ContextObject/ClientRequestContextObject.ts deleted file mode 100644 index b9ffc5af7..000000000 --- a/Library/ContextObject/ClientRequestContextObject.ts +++ /dev/null @@ -1,11 +0,0 @@ -/// -import http = require("http"); - -declare class ClientRequestContextObject { - requestOptions: http.RequestOptions; - request: http.ClientRequest; - response: http.ClientResponse; - error: Error; -} - -export = ClientRequestContextObject; diff --git a/Library/ContextObject/ServerRequestContextObject.ts b/Library/ContextObject/ServerRequestContextObject.ts deleted file mode 100644 index 6d02c0e94..000000000 --- a/Library/ContextObject/ServerRequestContextObject.ts +++ /dev/null @@ -1,9 +0,0 @@ -/// -import http = require("http"); - -declare class ServerRequestContextObject { - request: http.ServerRequest; - response: http.ServerResponse; -} - -export = ServerRequestContextObject; diff --git a/Tests/Library/Client.tests.ts b/Tests/Library/Client.tests.ts index ae1964eb1..9a6c13a49 100644 --- a/Tests/Library/Client.tests.ts +++ b/Tests/Library/Client.tests.ts @@ -717,12 +717,12 @@ describe("Library/Client", () => { trackStub.restore(); var expectedName = "I was here"; - client.addTelemetryProcessor((env, contextObject) => { - env.name = contextObject; + client.addTelemetryProcessor((env, contextObjects) => { + env.name = contextObjects["name"]; return true; }); - client.track(mockData, null, expectedName); + client.track(mockData, null, {"name": expectedName}); assert.equal(sendStub.callCount, 1, "send called once");