From 0896755bd16f4b74961958d2cd676cb0552588cb Mon Sep 17 00:00:00 2001 From: psquickitjayant Date: Mon, 20 Jul 2015 22:25:28 +0530 Subject: [PATCH 1/4] Send requests through XMLHttpRequest --- src/loggly.tracker.js | 112 +++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 50 deletions(-) diff --git a/src/loggly.tracker.js b/src/loggly.tracker.js index 3b0bb1d..56b8a85 100644 --- a/src/loggly.tracker.js +++ b/src/loggly.tracker.js @@ -1,10 +1,9 @@ (function(window, document) { var LOGGLY_INPUT_PREFIX = 'http' + ( ('https:' === document.location.protocol ? 's' : '') ) + '://', - LOGGLY_COLLECTOR_DOMAIN = 'logs-01.loggly.com', - LOGGLY_INPUT_SUFFIX = '.gif?', - LOGGLY_SESSION_KEY = 'logglytrackingsession', - LOGGLY_SESSION_KEY_LENGTH = LOGGLY_SESSION_KEY.length + 1; - + LOGGLY_COLLECTOR_DOMAIN = 'logs-01.loggly.com', + LOGGLY_SESSION_KEY = 'logglytrackingsession', + LOGGLY_SESSION_KEY_LENGTH = LOGGLY_SESSION_KEY.length + 1; + function uuid() { // lifted from here -> http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { @@ -16,7 +15,8 @@ function LogglyTracker() { this.key = false; this.sendConsoleErrors = false; - } + this.tag = 'jslogger'; + } function setKey(tracker, key) { tracker.key = key; @@ -24,36 +24,41 @@ setInputUrl(tracker); } + function setTag(tracker, tag){ + tracker.tag = tag; + } + function setSendConsoleError(tracker, sendConsoleErrors) { tracker.sendConsoleErrors = sendConsoleErrors; if(tracker.sendConsoleErrors === true){ - var _onerror = window.onerror; - //send console error messages to Loggly - window.onerror = function (msg, url, line, col){ - tracker.push({ - category: 'BrowserJsException', - exception: { - message: msg, - url: url, - lineno: line, - colno: col, - } - }); + var _onerror = window.onerror; + //send console error messages to Loggly + window.onerror = function (msg, url, line, col){ + tracker.push({ + category: 'BrowserJsException', + exception: { + message: msg, + url: url, + lineno: line, + colno: col, + } + }); - if (_onerror && typeof _onerror === 'function') { - _onerror.apply(window, arguments); - } - }; - } - } + if (_onerror && typeof _onerror === 'function') { + _onerror.apply(window, arguments); + } + }; + } + } function setInputUrl(tracker) { tracker.inputUrl = LOGGLY_INPUT_PREFIX - + (tracker.logglyCollectorDomain || LOGGLY_COLLECTOR_DOMAIN) - + '/inputs/' - + tracker.key - + LOGGLY_INPUT_SUFFIX; + + (tracker.logglyCollectorDomain || LOGGLY_COLLECTOR_DOMAIN) + + '/inputs/' + + tracker.key + + '/tag/' + + tracker.tag; } LogglyTracker.prototype = { @@ -61,7 +66,7 @@ if(session_id) { this.session_id = session_id; this.setCookie(this.session_id); - } else if(!this.session_id) { + } else if(!this.session_id) { this.session_id = this.readCookie(); if(!this.session_id) { this.session_id = uuid(); @@ -75,39 +80,44 @@ if( !data || !(type === 'object' || type === 'string') ) { return; } - + var self = this; - - if(type === 'string') { + + if(type === 'string') { data = { 'text': data }; - } else { + } else { if(data.logglyCollectorDomain) { self.logglyCollectorDomain = data.logglyCollectorDomain; return; } - + if(data.sendConsoleErrors !== undefined) { setSendConsoleError(self, data.sendConsoleErrors); - } - - if(data.logglyKey) { + } + + + if(data.tag) { + setTag(self, data.tag); + } + + if(data.logglyKey) { setKey(self, data.logglyKey); return; } - + if(data.session_id) { self.setSession(data.session_id); return; } } - + if(!self.key) { return; } - + self.track(data); @@ -115,12 +125,14 @@ track: function(data) { // inject session id data.sessionId = this.session_id; - + try { - var im = new Image(), - q = 'PLAINTEXT=' + encodeURIComponent(JSON.stringify(data)); - im.src = this.inputUrl + q; - } catch (ex) { + //creating an asynchronous XMLHttpRequest + var xmlHttp = new XMLHttpRequest(); + xmlHttp.open('POST', this.inputUrl, true); //true for asynchronous request + xmlHttp.send(JSON.stringify(data)); + + } catch (ex) { if (window && window.console && typeof window.console.log === 'function') { console.log("Failed to log to loggly because of this exception:\n" + ex); console.log("Failed log data:", data); @@ -128,14 +140,14 @@ } }, /** - * These cookie functions are not a global utilities. It is for purpose of this tracker only - */ + * These cookie functions are not a global utilities. It is for purpose of this tracker only + */ readCookie: function() { var cookie = document.cookie, - i = cookie.indexOf(LOGGLY_SESSION_KEY); + i = cookie.indexOf(LOGGLY_SESSION_KEY); if(i < 0) { return false; - } else { + } else { var end = cookie.indexOf(';', i + 1); end = end < 0 ? cookie.length : end; return cookie.slice(i + LOGGLY_SESSION_KEY_LENGTH, end); @@ -152,7 +164,7 @@ if(existing && existing.length ) { var i = 0, - eLength = existing.length; + eLength = existing.length; for(i = 0; i < eLength; i++) { tracker.push(existing[i]); } From edc9d5a54999a9f4d50c898a2055b60fafc266b2 Mon Sep 17 00:00:00 2001 From: psquickitjayant Date: Mon, 20 Jul 2015 22:26:31 +0530 Subject: [PATCH 2/4] Fixed indentation --- src/loggly.tracker.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/loggly.tracker.js b/src/loggly.tracker.js index 56b8a85..db2b731 100644 --- a/src/loggly.tracker.js +++ b/src/loggly.tracker.js @@ -94,12 +94,12 @@ return; } - if(data.sendConsoleErrors !== undefined) { - setSendConsoleError(self, data.sendConsoleErrors); + if(data.sendConsoleErrors !== undefined) { + setSendConsoleError(self, data.sendConsoleErrors); } - if(data.tag) { + if(data.tag) { setTag(self, data.tag); } @@ -129,10 +129,10 @@ try { //creating an asynchronous XMLHttpRequest var xmlHttp = new XMLHttpRequest(); - xmlHttp.open('POST', this.inputUrl, true); //true for asynchronous request - xmlHttp.send(JSON.stringify(data)); + xmlHttp.open('POST', this.inputUrl, true); //true for asynchronous request + xmlHttp.send(JSON.stringify(data)); - } catch (ex) { + } catch (ex) { if (window && window.console && typeof window.console.log === 'function') { console.log("Failed to log to loggly because of this exception:\n" + ex); console.log("Failed log data:", data); From c5daf799968b927113fb7868baf9b9aab0f18b15 Mon Sep 17 00:00:00 2001 From: psquickitjayant Date: Mon, 20 Jul 2015 22:28:44 +0530 Subject: [PATCH 3/4] Fixed indentation --- src/loggly.tracker.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/loggly.tracker.js b/src/loggly.tracker.js index db2b731..764e80d 100644 --- a/src/loggly.tracker.js +++ b/src/loggly.tracker.js @@ -28,10 +28,10 @@ tracker.tag = tag; } - function setSendConsoleError(tracker, sendConsoleErrors) { - tracker.sendConsoleErrors = sendConsoleErrors; + function setSendConsoleError(tracker, sendConsoleErrors) { + tracker.sendConsoleErrors = sendConsoleErrors; - if(tracker.sendConsoleErrors === true){ + if(tracker.sendConsoleErrors === true){ var _onerror = window.onerror; //send console error messages to Loggly window.onerror = function (msg, url, line, col){ From 4b01c2d7df023e2e420ae5aac50708cd526ba69d Mon Sep 17 00:00:00 2001 From: Jayant Varshney Date: Wed, 22 Jul 2015 22:36:38 +0530 Subject: [PATCH 4/4] Added minified version --- src/loggly.tracker.min.js | 2 +- src/loggly.tracker.min.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/loggly.tracker.min.js b/src/loggly.tracker.min.js index 7798349..f53ef97 100644 --- a/src/loggly.tracker.min.js +++ b/src/loggly.tracker.min.js @@ -1,2 +1,2 @@ -!function(a,b){function c(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"==a?b:3&b|8;return c.toString(16)})}function d(){this.key=!1,this.sendConsoleErrors=!1}function e(a,b){a.key=b,a.setSession(),g(a)}function f(b,c){if(b.sendConsoleErrors=c,b.sendConsoleErrors===!0){var d=a.onerror;a.onerror=function(c,e,f,g){b.push({category:"BrowserJsException",exception:{message:c,url:e,lineno:f,colno:g}}),d&&"function"==typeof d&&d.apply(a,arguments)}}}function g(a){a.inputUrl=h+(a.logglyCollectorDomain||i)+"/inputs/"+a.key+j}var h="http"+("https:"===b.location.protocol?"s":"")+"://",i="logs-01.loggly.com",j=".gif?",k="logglytrackingsession",l=k.length+1;d.prototype={setSession:function(a){a?(this.session_id=a,this.setCookie(this.session_id)):this.session_id||(this.session_id=this.readCookie(),this.session_id||(this.session_id=c(),this.setCookie(this.session_id)))},push:function(a){var b=typeof a;if(a&&("object"===b||"string"===b)){var c=this;if("string"===b)a={text:a};else{if(a.logglyCollectorDomain)return void(c.logglyCollectorDomain=a.logglyCollectorDomain);if(void 0!==a.sendConsoleErrors&&f(c,a.sendConsoleErrors),a.logglyKey)return void e(c,a.logglyKey);if(a.session_id)return void c.setSession(a.session_id)}c.key&&c.track(a)}},track:function(b){b.sessionId=this.session_id;try{var c=new Image,d="PLAINTEXT="+encodeURIComponent(JSON.stringify(b));c.src=this.inputUrl+d}catch(e){a&&a.console&&"function"==typeof a.console.log&&(console.log("Failed to log to loggly because of this exception:\n"+e),console.log("Failed log data:",b))}},readCookie:function(){var a=b.cookie,c=a.indexOf(k);if(0>c)return!1;var d=a.indexOf(";",c+1);return d=0>d?a.length:d,a.slice(c+l,d)},setCookie:function(a){b.cookie=k+"="+a}};var m=a._LTracker,n=new d;if(m&&m.length){var o=0,p=m.length;for(o=0;p>o;o++)n.push(m[o])}a._LTracker=n,a.LogglyTracker=d}(window,document); +!function(a,b){function c(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"==a?b:3&b|8;return c.toString(16)})}function d(){this.key=!1,this.sendConsoleErrors=!1,this.tag="jslogger"}function e(a,b){a.key=b,a.setSession(),h(a)}function f(a,b){a.tag=b}function g(b,c){if(b.sendConsoleErrors=c,b.sendConsoleErrors===!0){var d=a.onerror;a.onerror=function(c,e,f,g){b.push({category:"BrowserJsException",exception:{message:c,url:e,lineno:f,colno:g}}),d&&"function"==typeof d&&d.apply(a,arguments)}}}function h(a){a.inputUrl=i+(a.logglyCollectorDomain||j)+"/inputs/"+a.key+"/tag/"+a.tag}var i="http"+("https:"===b.location.protocol?"s":"")+"://",j="logs-01.loggly.com",k="logglytrackingsession",l=k.length+1;d.prototype={setSession:function(a){a?(this.session_id=a,this.setCookie(this.session_id)):this.session_id||(this.session_id=this.readCookie(),this.session_id||(this.session_id=c(),this.setCookie(this.session_id)))},push:function(a){var b=typeof a;if(a&&("object"===b||"string"===b)){var c=this;if("string"===b)a={text:a};else{if(a.logglyCollectorDomain)return void(c.logglyCollectorDomain=a.logglyCollectorDomain);if(void 0!==a.sendConsoleErrors&&g(c,a.sendConsoleErrors),a.tag&&f(c,a.tag),a.logglyKey)return void e(c,a.logglyKey);if(a.session_id)return void c.setSession(a.session_id)}c.key&&c.track(a)}},track:function(b){b.sessionId=this.session_id;try{var c=new XMLHttpRequest;c.open("POST",this.inputUrl,!0),c.send(JSON.stringify(b))}catch(d){a&&a.console&&"function"==typeof a.console.log&&(console.log("Failed to log to loggly because of this exception:\n"+d),console.log("Failed log data:",b))}},readCookie:function(){var a=b.cookie,c=a.indexOf(k);if(0>c)return!1;var d=a.indexOf(";",c+1);return d=0>d?a.length:d,a.slice(c+l,d)},setCookie:function(a){b.cookie=k+"="+a}};var m=a._LTracker,n=new d;if(m&&m.length){var o=0,p=m.length;for(o=0;p>o;o++)n.push(m[o])}a._LTracker=n,a.LogglyTracker=d}(window,document); //# sourceMappingURL=loggly.tracker.min.map \ No newline at end of file diff --git a/src/loggly.tracker.min.map b/src/loggly.tracker.min.map index 2d5263f..812c8cd 100644 --- a/src/loggly.tracker.min.map +++ b/src/loggly.tracker.min.map @@ -1 +1 @@ -{"version":3,"file":"loggly.tracker.min.js","sources":["loggly.tracker.js"],"names":["window","document","uuid","replace","c","r","Math","random","v","toString","LogglyTracker","this","key","sendConsoleErrors","setKey","tracker","setSession","setInputUrl","setSendConsoleError","_onerror","onerror","msg","url","line","col","push","category","exception","message","lineno","colno","apply","arguments","inputUrl","LOGGLY_INPUT_PREFIX","logglyCollectorDomain","LOGGLY_COLLECTOR_DOMAIN","LOGGLY_INPUT_SUFFIX","location","protocol","LOGGLY_SESSION_KEY","LOGGLY_SESSION_KEY_LENGTH","length","prototype","session_id","setCookie","readCookie","data","type","self","text","undefined","logglyKey","track","sessionId","im","Image","q","encodeURIComponent","JSON","stringify","src","ex","console","log","cookie","i","indexOf","end","slice","value","existing","_LTracker","eLength"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"loggly.tracker.min.js","sources":["loggly.tracker.js"],"names":["window","document","uuid","replace","c","r","Math","random","v","toString","LogglyTracker","this","key","sendConsoleErrors","tag","setKey","tracker","setSession","setInputUrl","setTag","setSendConsoleError","_onerror","onerror","msg","url","line","col","push","category","exception","message","lineno","colno","apply","arguments","inputUrl","LOGGLY_INPUT_PREFIX","logglyCollectorDomain","LOGGLY_COLLECTOR_DOMAIN","location","protocol","LOGGLY_SESSION_KEY","LOGGLY_SESSION_KEY_LENGTH","length","prototype","session_id","setCookie","readCookie","data","type","self","text","undefined","logglyKey","track","sessionId","xmlHttp","XMLHttpRequest","open","send","JSON","stringify","ex","console","log","cookie","i","indexOf","end","slice","value","existing","_LTracker","eLength"],"mappings":"CAAA,SAAUA,EAAQC,GAMd,QAASC,KAEL,MAAO,uCAAuCC,QAAQ,QAAS,SAASC,GACpE,GAAIC,GAAkB,GAAdC,KAAKC,SAAY,EAAGC,EAAS,KAALJ,EAAWC,EAAO,EAAFA,EAAM,CACtD,OAAOG,GAAEC,SAAS,MAI1B,QAASC,KACLC,KAAKC,KAAM,EACjBD,KAAKE,mBAAoB,EACnBF,KAAKG,IAAM,WAGf,QAASC,GAAOC,EAASJ,GACrBI,EAAQJ,IAAMA,EACdI,EAAQC,aACRC,EAAYF,GAGhB,QAASG,GAAOH,EAASF,GACrBE,EAAQF,IAAMA,EAGlB,QAASM,GAAoBJ,EAASH,GAGzC,GAFAG,EAAQH,kBAAoBA,EAEzBG,EAAQH,qBAAsB,EAAK,CAC3B,GAAIQ,GAAWrB,EAAOsB,OAEtBtB,GAAOsB,QAAU,SAAUC,EAAKC,EAAKC,EAAMC,GACvCV,EAAQW,MACJC,SAAU,qBACVC,WACIC,QAASP,EACTC,IAAKA,EACLO,OAAQN,EACRO,MAAON,KAIXL,GAAgC,kBAAbA,IACnBA,EAASY,MAAMjC,EAAQkC,aAMvC,QAAShB,GAAYF,GACjBA,EAAQmB,SAAWC,GAChBpB,EAAQqB,uBAAyBC,GAClC,WACAtB,EAAQJ,IACR,QACAI,EAAQF,IA3Dd,GAAIsB,GAAsB,QAAY,WAAanC,EAASsC,SAASC,SAAW,IAAM,IAAQ,MAC9FF,EAA0B,qBAC1BG,EAAqB,wBACrBC,EAA4BD,EAAmBE,OAAS,CA2DxDjC,GAAckC,WACV3B,WAAY,SAAS4B,GACdA,GACClC,KAAKkC,WAAaA,EAClBlC,KAAKmC,UAAUnC,KAAKkC,aACTlC,KAAKkC,aAChBlC,KAAKkC,WAAalC,KAAKoC,aACnBpC,KAAKkC,aACLlC,KAAKkC,WAAa3C,IAClBS,KAAKmC,UAAUnC,KAAKkC,eAIhClB,KAAM,SAASqB,GACX,GAAIC,SAAcD,EAElB,IAAKA,IAAmB,WAATC,GAA8B,WAATA,GAApC,CAIA,GAAIC,GAAOvC,IAGX,IAAY,WAATsC,EACCD,GACIG,KAAQH,OAEL,CACP,GAAGA,EAAKX,sBAEJ,YADAa,EAAKb,sBAAwBW,EAAKX,sBAatC,IATgBe,SAA3BJ,EAAKnC,mBACJO,EAAoB8B,EAAMF,EAAKnC,mBAIhCmC,EAAKlC,KACUK,EAAO+B,EAAMF,EAAKlC,KAGnBkC,EAAKK,UAEJ,WADAtC,GAAOmC,EAAMF,EAAKK,UAItB,IAAGL,EAAKH,WAEJ,WADAK,GAAKjC,WAAW+B,EAAKH,YAKzBK,EAAKtC,KAITsC,EAAKI,MAAMN,KAIfM,MAAO,SAASN,GAEZA,EAAKO,UAAY5C,KAAKkC,UAEtB,KAEI,GAAIW,GAAU,GAAIC,eAChCD,GAAQE,KAAK,OAAQ/C,KAAKwB,UAAU,GACpCqB,EAAQG,KAAKC,KAAKC,UAAUb,IAEhB,MAAOc,GACD9D,GAAUA,EAAO+D,SAAyC,kBAAvB/D,GAAO+D,QAAQC,MAClDD,QAAQC,IAAI,uDAAyDF,GACrEC,QAAQC,IAAI,mBAAoBhB,MAO5CD,WAAY,WACR,GAAIkB,GAAShE,EAASgE,OACtBC,EAAID,EAAOE,QAAQ1B,EACnB,IAAO,EAAJyB,EACC,OAAO,CAEP,IAAIE,GAAMH,EAAOE,QAAQ,IAAKD,EAAI,EAElC,OADAE,GAAY,EAANA,EAAUH,EAAOtB,OAASyB,EACzBH,EAAOI,MAAMH,EAAIxB,EAA2B0B,IAG3DtB,UAAW,SAASwB,GAChBrE,EAASgE,OAASxB,EAAqB,IAAM6B,GAIrD,IAAIC,GAAWvE,EAAOwE,UAElBxD,EAAU,GAAIN,EAElB,IAAG6D,GAAYA,EAAS5B,OAAS,CAC7B,GAAIuB,GAAI,EACRO,EAAUF,EAAS5B,MACnB,KAAIuB,EAAI,EAAOO,EAAJP,EAAaA,IACpBlD,EAAQW,KAAK4C,EAASL,IAI9BlE,EAAOwE,UAAYxD,EAEnBhB,EAAOU,cAAgBA,GAExBV,OAAQC"} \ No newline at end of file