From dfe14dbeb22231a2878f74699a10603fae62745a Mon Sep 17 00:00:00 2001 From: Kamil Szostak Date: Tue, 30 Aug 2016 16:05:01 -0700 Subject: [PATCH 1/9] Send telemetry over https --- Library/Config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/Config.ts b/Library/Config.ts index 5a64a2aad..5214a1357 100644 --- a/Library/Config.ts +++ b/Library/Config.ts @@ -19,7 +19,7 @@ class Config { constructor(instrumentationKey?: string) { this.instrumentationKey = instrumentationKey || this._getInstrumentationKey(); - this.endpointUrl = "http://dc.services.visualstudio.com/v2/track"; + this.endpointUrl = "https://dc.services.visualstudio.com/v2/track"; this.sessionRenewalMs = 30 * 60 * 1000; this.sessionExpirationMs = 24 * 60 * 60 * 1000; this.maxBatchSize = 250; From 458559b2d7dfd568967955493396685ea1d407dc Mon Sep 17 00:00:00 2001 From: Kevin Zhao Date: Mon, 5 Sep 2016 22:23:29 +0800 Subject: [PATCH 2/9] [Sender] make resend interval configurable --- Library/Channel.ts | 4 ++-- Library/Sender.ts | 9 +++++++-- applicationinsights.ts | 7 ++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Library/Channel.ts b/Library/Channel.ts index 749f9b6b1..04fe05820 100644 --- a/Library/Channel.ts +++ b/Library/Channel.ts @@ -24,8 +24,8 @@ class Channel { /** * Enable or disable offline mode */ - public setOfflineMode(value: boolean) { - this._sender.setOfflineMode(value); + public setOfflineMode(value: boolean, resendInterval?: number) { + this._sender.setOfflineMode(value, resendInterval); } /** diff --git a/Library/Sender.ts b/Library/Sender.ts index 062fe0ea0..f91344ddb 100644 --- a/Library/Sender.ts +++ b/Library/Sender.ts @@ -20,19 +20,24 @@ class Sender { private _onSuccess: (response: string) => void; private _onError: (error: Error) => void; private _enableOfflineMode: boolean; + private _resendInterval: number; constructor(getUrl: () => string, onSuccess?: (response: string) => void, onError?: (error: Error) => void) { this._getUrl = getUrl; this._onSuccess = onSuccess; this._onError = onError; this._enableOfflineMode = false; + this._resendInterval = Sender.WAIT_BETWEEN_RESEND; } /** * Enable or disable offline mode */ - public setOfflineMode(value: boolean) { + public setOfflineMode(value: boolean, resendInterval?: number) { this._enableOfflineMode = value; + if (typeof resendInterval === 'number' && resendInterval >= 1) { + this._resendInterval = Math.floor(resendInterval); + } } public send(payload: Buffer, callback?: (string) => void) { @@ -90,7 +95,7 @@ class Sender { if (this._enableOfflineMode) { // try to send any cached events if the user is back online if (res.statusCode === 200) { - setTimeout(() => this._sendFirstFileOnDisk(), Sender.WAIT_BETWEEN_RESEND); + setTimeout(() => this._sendFirstFileOnDisk(), this._resendInterval); // store to disk in case of burst throttling } else if (res.statusCode === 206 || res.statusCode === 429 || diff --git a/applicationinsights.ts b/applicationinsights.ts index c50b9e26f..9b5be25d8 100644 --- a/applicationinsights.ts +++ b/applicationinsights.ts @@ -138,13 +138,14 @@ class ApplicationInsights { /** * Enable or disable offline mode to cache events when client is offline (disabled by default) - * @param value if true events that occured while client is offline will be cahced on disk + * @param value if true events that occured while client is offline will be cached on disk + * @param resendInterval. The wait interval for resending cached events. * @returns {ApplicationInsights} this class */ - public static setOfflineMode(value: boolean) { + public static setOfflineMode(value: boolean, resendInterval?: number) { ApplicationInsights._isOfflineMode = value; if (ApplicationInsights.client && ApplicationInsights.client.channel){ - ApplicationInsights.client.channel.setOfflineMode(value); + ApplicationInsights.client.channel.setOfflineMode(value, resendInterval); } return ApplicationInsights; From 4d958ba48b82f7ba50e92fbac32a41708e4d1a7d Mon Sep 17 00:00:00 2001 From: Kevin Zhao Date: Sat, 10 Sep 2016 16:03:44 +0800 Subject: [PATCH 3/9] [Sender] add unit test --- Library/Sender.ts | 4 ++-- Tests/EndToEnd.tests.ts | 3 +-- Tests/Library/Sender.tests.ts | 43 +++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 Tests/Library/Sender.tests.ts diff --git a/Library/Sender.ts b/Library/Sender.ts index f91344ddb..9a57c96fb 100644 --- a/Library/Sender.ts +++ b/Library/Sender.ts @@ -20,7 +20,7 @@ class Sender { private _onSuccess: (response: string) => void; private _onError: (error: Error) => void; private _enableOfflineMode: boolean; - private _resendInterval: number; + protected _resendInterval: number; constructor(getUrl: () => string, onSuccess?: (response: string) => void, onError?: (error: Error) => void) { this._getUrl = getUrl; @@ -35,7 +35,7 @@ class Sender { */ public setOfflineMode(value: boolean, resendInterval?: number) { this._enableOfflineMode = value; - if (typeof resendInterval === 'number' && resendInterval >= 1) { + if (typeof resendInterval === 'number' && resendInterval >= 0) { this._resendInterval = Math.floor(resendInterval); } } diff --git a/Tests/EndToEnd.tests.ts b/Tests/EndToEnd.tests.ts index 076deedc0..ff3b5b14c 100644 --- a/Tests/EndToEnd.tests.ts +++ b/Tests/EndToEnd.tests.ts @@ -272,10 +272,9 @@ describe("EndToEnd", () => { var req = new fakeRequest(false); var res = new fakeResponse(); res.statusCode = 200; - Sender.WAIT_BETWEEN_RESEND =0; var client = AppInsights.getClient("key"); - client.channel.setOfflineMode(true); + client.channel.setOfflineMode(true, 0); client.trackEvent("test event"); diff --git a/Tests/Library/Sender.tests.ts b/Tests/Library/Sender.tests.ts new file mode 100644 index 000000000..fd7dfe3d9 --- /dev/null +++ b/Tests/Library/Sender.tests.ts @@ -0,0 +1,43 @@ +/// +/// + +import assert = require("assert"); + +import Sender = require("../../Library/Sender"); + +class SenderMock extends Sender { + public getResendInterval() { + return this._resendInterval; + } +} + +describe("Library/Sender", () => { + var sender:SenderMock; + + beforeEach(() => { + sender = new SenderMock(() => 'https://www.microsoft.com'); + }); + + describe("#setOfflineMode(value, resendInterval)", () => { + it("default resend interval is 60 seconds", () => { + sender.setOfflineMode(true); + assert.equal(Sender.WAIT_BETWEEN_RESEND, sender.getResendInterval()); + }); + + it("resend interval can be configured", () => { + sender.setOfflineMode(true, 0); + assert.equal(0, sender.getResendInterval()); + + sender.setOfflineMode(true, 1234); + assert.equal(1234, sender.getResendInterval()); + + sender.setOfflineMode(true, 1234.56); + assert.equal(1234, sender.getResendInterval()); + }); + + it("resend interval can't be negative", () => { + sender.setOfflineMode(true, -1234); + assert.equal(Sender.WAIT_BETWEEN_RESEND, sender.getResendInterval()); + }); + }); +}); \ No newline at end of file From b234d412afe751e27b2ebbacd5d6e538f9d55b4d Mon Sep 17 00:00:00 2001 From: Kevin Zhao Date: Sat, 10 Sep 2016 16:09:16 +0800 Subject: [PATCH 4/9] [Sender] use double quote for consistency --- Tests/Library/Sender.tests.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/Library/Sender.tests.ts b/Tests/Library/Sender.tests.ts index fd7dfe3d9..e1a276a96 100644 --- a/Tests/Library/Sender.tests.ts +++ b/Tests/Library/Sender.tests.ts @@ -15,7 +15,7 @@ describe("Library/Sender", () => { var sender:SenderMock; beforeEach(() => { - sender = new SenderMock(() => 'https://www.microsoft.com'); + sender = new SenderMock(() => "https://www.microsoft.com"); }); describe("#setOfflineMode(value, resendInterval)", () => { @@ -40,4 +40,4 @@ describe("Library/Sender", () => { assert.equal(Sender.WAIT_BETWEEN_RESEND, sender.getResendInterval()); }); }); -}); \ No newline at end of file +}); From 57aca760607b348d0b5d830f52a2da028c052b59 Mon Sep 17 00:00:00 2001 From: gzepeda Date: Fri, 30 Sep 2016 18:04:04 -0600 Subject: [PATCH 5/9] Commit to resolve issue #73 - Changed the definition of the trackException method to have the additional parameter - Changed the definition of the getExceptionData method to consider the measurements parameter - No need to change the Exception Data Contract since it already had a measurements property --- AutoCollection/Exceptions.ts | 6 +++--- Library/Client.ts | 4 ++-- Tests/Library/Client.tests.ts | 9 ++++++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/AutoCollection/Exceptions.ts b/AutoCollection/Exceptions.ts index b235c958c..4a9348f84 100644 --- a/AutoCollection/Exceptions.ts +++ b/AutoCollection/Exceptions.ts @@ -67,14 +67,14 @@ class AutoCollectExceptions { * @param error the exception to track * @param handledAt where this exception was handled (leave null for unhandled) * @param properties additional properties + * @param measurements metrics associated with this event, displayed in Metrics Explorer on the portal. Defaults to empty. */ - public static getExceptionData(error: Error, isHandled: boolean, properties?:{ [key: string]: string; }) { - + public static getExceptionData(error: Error, isHandled: boolean, properties?:{ [key: string]: string; }, measurements?:{ [key: string]: number; }) { var exception = new ContractsModule.Contracts.ExceptionData(); exception.handledAt = isHandled ? "User" : "Unhandled"; exception.properties = properties; exception.severityLevel = ContractsModule.Contracts.SeverityLevel.Error; - exception.properties = properties; + exception.measurements = measurements; exception.exceptions = []; var stack = error["stack"]; diff --git a/Library/Client.ts b/Library/Client.ts index b79ca20cd..cdc79ef80 100644 --- a/Library/Client.ts +++ b/Library/Client.ts @@ -87,12 +87,12 @@ class Client { * @param properties map[string, string] - additional data used to filter events and metrics in the portal. Defaults to empty. * @param measurements map[string, number] - metrics associated with this event, displayed in Metrics Explorer on the portal. Defaults to empty. */ - public trackException(exception: Error, properties?: { [key: string]: string; }) { + public trackException(exception: Error, properties?: { [key: string]: string; }, measurements?:{ [key: string]: number; }) { if (!Util.isError(exception)) { exception = new Error(exception); } - var data = ExceptionTracking.getExceptionData(exception, true, properties) + var data = ExceptionTracking.getExceptionData(exception, true, properties, measurements); this.track(data); } diff --git a/Tests/Library/Client.tests.ts b/Tests/Library/Client.tests.ts index 73ecf6833..eecaeeea0 100644 --- a/Tests/Library/Client.tests.ts +++ b/Tests/Library/Client.tests.ts @@ -124,13 +124,20 @@ describe("Library/Client", () => { trackStub.reset(); client.trackException(new Error(name)); client.trackException(new Error(name), properties); + client.trackException(new Error(name), properties, measurements); - assert.ok(trackStub.calledTwice); + assert.ok(trackStub.calledThrice); var args = trackStub.args; + assert.equal(args[0][0].baseData.exceptions[0].message, name); + assert.equal(args[1][0].baseData.exceptions[0].message, name); assert.deepEqual(args[1][0].baseData.properties, properties); + + assert.equal(args[2][0].baseData.exceptions[0].message, name); + assert.deepEqual(args[2][0].baseData.properties, properties); + assert.deepEqual(args[2][0].baseData.measurements, measurements); }); it("should not crash with invalid input", () => { From 0be2c45faf3d6902ebfb38a9deb6642b832a653f Mon Sep 17 00:00:00 2001 From: gzepeda Date: Tue, 4 Oct 2016 15:55:07 -0600 Subject: [PATCH 6/9] Adding tests to verify calls to track exception with properties and calls to track properties and measurements --- Tests/Library/Client.tests.ts | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/Tests/Library/Client.tests.ts b/Tests/Library/Client.tests.ts index eecaeeea0..f5cf9a3ee 100644 --- a/Tests/Library/Client.tests.ts +++ b/Tests/Library/Client.tests.ts @@ -120,26 +120,41 @@ describe("Library/Client", () => { }); describe("#trackException()", () => { - it("should track Exception with correct data", () => { + it("should track Exception with correct data - Error only", () => { trackStub.reset(); client.trackException(new Error(name)); - client.trackException(new Error(name), properties); - client.trackException(new Error(name), properties, measurements); - assert.ok(trackStub.calledThrice); + assert.ok(trackStub.calledOnce); var args = trackStub.args; - assert.equal(args[0][0].baseData.exceptions[0].message, name); + }); - assert.equal(args[1][0].baseData.exceptions[0].message, name); - assert.deepEqual(args[1][0].baseData.properties, properties); + it("should track Exception with correct data - Error and properties", () => { + trackStub.reset(); + client.trackException(new Error(name), properties); + + assert.ok(trackStub.calledOnce); + + var args = trackStub.args; - assert.equal(args[2][0].baseData.exceptions[0].message, name); - assert.deepEqual(args[2][0].baseData.properties, properties); - assert.deepEqual(args[2][0].baseData.measurements, measurements); + assert.equal(args[0][0].baseData.exceptions[0].message, name); + assert.deepEqual(args[0][0].baseData.properties, properties); }); + it("should track Exception with correct data - Error, properties and measurements", () => { + trackStub.reset(); + client.trackException(new Error(name), properties, measurements); + + assert.ok(trackStub.calledOnce); + + var args = trackStub.args; + + assert.equal(args[0][0].baseData.exceptions[0].message, name); + assert.deepEqual(args[0][0].baseData.properties, properties); + assert.deepEqual(args[0][0].baseData.measurements, measurements); + }); + it("should not crash with invalid input", () => { invalidInputHelper("trackException"); }); From 5b5251170d0eaee961f611775985bfe05cd337fb Mon Sep 17 00:00:00 2001 From: Kamil Szostak Date: Tue, 4 Oct 2016 15:45:28 -0700 Subject: [PATCH 7/9] Fix cloud.role and cloud.roleInstance names --- Library/Contracts.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Contracts.ts b/Library/Contracts.ts index ad1430efc..c726fe940 100644 --- a/Library/Contracts.ts +++ b/Library/Contracts.ts @@ -81,8 +81,8 @@ export module Contracts { this.deviceOEMName = "ai.device.oemName"; this.deviceOS = "ai.device.os"; this.deviceOSVersion = "ai.device.osVersion"; - this.deviceRoleInstance = "ai.device.roleInstance"; - this.deviceRoleName = "ai.device.roleName"; + this.deviceRoleInstance = "ai.cloud.roleInstance"; + this.deviceRoleName = "ai.cloud.role"; this.deviceScreenResolution = "ai.device.screenResolution"; this.deviceType = "ai.device.type"; this.deviceMachineName = "ai.device.machineName"; From c43ac2824aa99dbe24fb551e60c83033aeedc781 Mon Sep 17 00:00:00 2001 From: Kamil Szostak Date: Wed, 5 Oct 2016 18:58:05 -0700 Subject: [PATCH 8/9] Fix fake https server for unit tests --- Tests/EndToEnd.tests.ts | 7 ++----- package.json | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Tests/EndToEnd.tests.ts b/Tests/EndToEnd.tests.ts index ff3b5b14c..dcde10518 100644 --- a/Tests/EndToEnd.tests.ts +++ b/Tests/EndToEnd.tests.ts @@ -212,7 +212,7 @@ describe("EndToEnd", () => { beforeEach(() => { AppInsights.client = undefined; - this.request = sinon.stub(http, 'request'); + this.request = sinon.stub(https, 'request'); this.writeFile = sinon.stub(fs, 'writeFile'); this.writeFileSync = sinon.stub(fs, 'writeFileSync'); this.exists = sinon.stub(fs, 'exists').yields(true); @@ -247,7 +247,7 @@ describe("EndToEnd", () => { done(); }); }); - }); + }); it("stores data to disk when enabled", (done) => { var req = new fakeRequest(); @@ -306,8 +306,5 @@ describe("EndToEnd", () => { assert(this.existsSync.callCount === 1); assert(this.writeFileSync.callCount === 1); }); - - - }); }); diff --git a/package.json b/package.json index dd75410a2..b25db4c03 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "chai": "^2.3.0", "mocha": "^2.2.4", "node-mocks-http": "^1.2.3", - "sinon": "^1.14.1", + "sinon": "^1.17.6", "typescript": "^1.8.9" } } From 53efc4e1a07e158ae99c9be51e089b4a4c8ce653 Mon Sep 17 00:00:00 2001 From: Kamil Szostak Date: Thu, 6 Oct 2016 09:45:19 -0700 Subject: [PATCH 9/9] Release v0.16.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b25db4c03..e5b2c62e9 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "applicationinsights", "license": "MIT", "bugs": "/~https://github.com/Microsoft/ApplicationInsights-node.js/issues", - "version": "0.15.19", + "version": "0.16.0", "description": "Microsoft Application Insights module for Node.JS", "repository": { "type": "git",