This is an automated email from the ASF dual-hosted git repository. poorejc pushed a commit to branch FLAGON-469 in repository https://gitbox.apache.org/repos/asf/incubator-flagon-useralejs.git
commit 8014a77fb258aeadfdc6f10af055b94accc0f696 Author: poorejc <[email protected]> AuthorDate: Mon Dec 9 23:38:46 2019 -0500 [FLAGON-468] added packageLog, packageCustomLog support via API and examples --- build/UserAleWebExtension/content.js | 5 ++-- build/userale-2.0.2.js | 56 ++++++++++++++++++++++++++++++++++-- build/userale-2.0.2.min.js | 2 +- example/aleAPI.js | 52 +++++++++++++++++++++------------ example/index.html | 6 ++-- src/attachHandlers.js | 3 +- src/getInitialSettings.js | 1 - src/main.js | 1 + src/packageLogs.js | 51 +++++++++++++++++++++++++++++++- 9 files changed, 146 insertions(+), 31 deletions(-) diff --git a/build/UserAleWebExtension/content.js b/build/UserAleWebExtension/content.js index ec59c1d..b6c4a13 100644 --- a/build/UserAleWebExtension/content.js +++ b/build/UserAleWebExtension/content.js @@ -87,7 +87,6 @@ function getInitialSettings() { })(); var get = script ? script.getAttribute.bind(script) : function() { return null; }; - // @todo add authHeader setting settings.autostart = get('data-autostart') === 'false' ? false : true; settings.url = get('data-url') || 'http://localhost:8000'; settings.transmitInterval = +get('data-interval') || 5000; @@ -287,7 +286,6 @@ function packageLog(e, detailFcn) { (e.timeStamp && e.timeStamp > 0) ? config.time(e.timeStamp) : Date.now() ); - // @todo add host IP in meta data properties var log = { 'target' : getSelector(e.target), 'path' : buildPath(e), @@ -639,7 +637,8 @@ function extractMouseEvent(e) { 'ctrl' : e.ctrlKey, 'alt' : e.altKey, 'shift' : e.shiftKey, - 'meta' : e.metaKey + 'meta' : e.metaKey, +// 'text' : e.target.innerHTML }; } diff --git a/build/userale-2.0.2.js b/build/userale-2.0.2.js index db5a5a1..92875ca 100644 --- a/build/userale-2.0.2.js +++ b/build/userale-2.0.2.js @@ -58,7 +58,6 @@ var userale = (function (exports) { })(); var get = script ? script.getAttribute.bind(script) : function() { return null; }; - // @todo add authHeader setting settings.autostart = get('data-autostart') === 'false' ? false : true; settings.url = get('data-url') || 'http://localhost:8000'; settings.transmitInterval = +get('data-interval') || 5000; @@ -266,7 +265,6 @@ var userale = (function (exports) { (e.timeStamp && e.timeStamp > 0) ? config.time(e.timeStamp) : Date.now() ); - // @todo add host IP in meta data properties var log = { 'target' : getSelector(e.target), 'path' : buildPath(e), @@ -301,6 +299,56 @@ var userale = (function (exports) { } /** + * Packages the provided customLog to include standard meta data and appends it to the log container. + * @param {Object} customLog The behavior to be logged. + * @param {Function} detailFcn The function to extract additional log parameters from the event. + * @param {boolean} userAction Indicates user behavior (true) or system behavior (false) + * @return {boolean} Whether the event was logged. + */ + function packageCustomLog(customLog, detailFcn, userAction) { + if (!config.on) { + return false; + } + + var details = null; + if (detailFcn) { + details = detailFcn(); + } + + var timeFields = extractTimeFields(Date.now()); + + var metaData = { + 'pageUrl': window.location.href, + 'pageTitle': document.title, + 'pageReferrer': document.referrer, + 'clientTime' : timeFields.milli, + 'microTime' : timeFields.micro, + 'logType': 'custom', + 'userAction' : userAction, + 'details' : details, + 'userId' : config.userId, + 'toolVersion' : config.version, + 'toolName' : config.toolName, + 'useraleVersion': config.useraleVersion, + 'sessionID': config.sessionID + }; + + var log = Object.assign(customLog, metaData); + + if ((typeof filterHandler === 'function') && !filterHandler(log)) { + return false; + } + + if (typeof mapHandler === 'function') { + log = mapHandler(log); + } + + logs.push(log); + + return true; + } + + /** * Extract the millisecond and microsecond portions of a timestamp. * @param {Number} timeStamp The timestamp to split into millisecond and microsecond fields. * @return {Object} An object containing the millisecond @@ -618,7 +666,8 @@ var userale = (function (exports) { 'ctrl' : e.ctrlKey, 'alt' : e.altKey, 'shift' : e.shiftKey, - 'meta' : e.metaKey + 'meta' : e.metaKey, + // 'text' : e.target.innerHTML }; } @@ -820,6 +869,7 @@ var userale = (function (exports) { exports.log = log; exports.map = setLogMapper; exports.options = options; + exports.packageCustomLog = packageCustomLog; exports.packageLog = packageLog; exports.start = start; exports.stop = stop; diff --git a/build/userale-2.0.2.min.js b/build/userale-2.0.2.min.js index 2d6fe76..fbef41e 100644 --- a/build/userale-2.0.2.min.js +++ b/build/userale-2.0.2.min.js @@ -15,4 +15,4 @@ * limitations under the License. * @preserved */ -var userale=function(n){"use strict";var a,i,u,l,s,c,d,f,t="2.0.2",r=null;function e(n,o){Object.keys(o).forEach(function(t){if("userFromParams"===t){var e=function(t){var e=new RegExp("[?&]"+t+"(=([^&#]*)|&|#|$)"),n=window.location.href.match(e);return n&&n[2]?decodeURIComponent(n[2].replace(/\+/g," ")):null}(o[t]);e&&(n.userId=e)}n[t]=o[t]})}var m=null,p=null;function o(t,e){if(!i.on)return!1;var n=null;e&&(n=e(t));var o=function(t){return{milli:Math.floor(t),micro:Number((t%1).toFixed [...] \ No newline at end of file +var userale=function(n){"use strict";var u,l,a,i,s,c,d,f,e="2.0.2",r=null;function t(n,o){Object.keys(o).forEach(function(e){if("userFromParams"===e){var t=function(e){var t=new RegExp("[?&]"+e+"(=([^&#]*)|&|#|$)"),n=window.location.href.match(t);return n&&n[2]?decodeURIComponent(n[2].replace(/\+/g," ")):null}(o[e]);t&&(n.userId=t)}n[e]=o[e]})}var m=null,p=null;function o(e,t){if(!l.on)return!1;var n=null;t&&(n=t(e));var o=g(e.timeStamp&&0<e.timeStamp?l.time(e.timeStamp):Date.now()),r={t [...] \ No newline at end of file diff --git a/example/aleAPI.js b/example/aleAPI.js index 51c5f65..e28da8b 100644 --- a/example/aleAPI.js +++ b/example/aleAPI.js @@ -17,15 +17,15 @@ const changeMe = "me"; window.userale.options({ "userId": changeMe, - "version": "4.2.1", - "sessionID": "42" + "version": "next", + "sessionID": "this one" }); /**Filter API /**Try out the 'Filter' API to eliminate the logs that you don't want!*/ window.userale.filter(function (log) { - var type_array = ['mouseup', 'mouseover', 'mousedown', 'keydown', 'dblclick', 'blur', 'focus']; + var type_array = ['mouseup', 'mouseover', 'mousedown', 'keydown', 'dblclick', 'blur', 'focus', 'input']; var logType_array = ['interval']; return !type_array.includes(log.type) && !logType_array.includes(log.logType); }); @@ -34,10 +34,10 @@ window.userale.filter(function (log) { /**Play around with the 'Mapping' API to add or modify existing fields in your logs!*/ /**the example below modifies fields attached to logs on the "Click Me" button on the Example page*/ -window.userale.map(function (log) { +window.userale.map(function (log, e) { var targetsForLabels = ["button#test_button"]; if (targetsForLabels.includes(log.target)) { - return Object.assign({}, log, { customLabel: "Click Me!" }); + return Object.assign({}, log, { customLabel: e.target.innerHTML }); } else { return log; } @@ -49,22 +49,22 @@ window.userale.map(function (log) { /*You can fully customize your custom logs and define any data schema that suits you*/ /**this example works with the "Test Field" form element on the Example Page*/ document.addEventListener('change', function(e) { - if (e.target.value === 'goodbye') { + if (e.target.value === 'log') { window.userale.log({ target: window.userale.getSelector(e.target), path: window.userale.buildPath(e), - pageUrl: 'userALEtest.com', - pageTitle: 'UserAleJS - Example Page', - type: 'change', + type: e.type, logType: 'custom', userAction: false, - details: 'disinterested user', + details: 'I can make this log look like anything I want', + customField1: 'foo', + customField2: 'bar', userId: window.userale.options().userId, toolVersion: window.userale.options().version, toolName: window.userale.options().toolName, useraleVersion: window.userale.options().useraleVersion, sessionID: window.userale.options().sessionID, - customLabel: "no follow up" + customLabel: "(custom) log Example!" }); } }); @@ -72,19 +72,35 @@ document.addEventListener('change', function(e) { /**Alternatively, you can use UserALE.js' own packaging function for HTML events to strive for standardization!*/ /**this example works with the "Test Field" form element on the Example Page*/ document.addEventListener('change', function(e){ - if (e.target.value === 'hello') { - window.userale.packageLog(e, function(){return "cool user!"}); + if (e.target.value === 'packageLog') { + window.userale.map(function (log) { + var targetsForLabels = ["packaged this log"]; + if (targetsForLabels.includes(log.details)) { + return Object.assign({}, log, { logType: 'custom', customLabel: 'packageLog Example' }); + } else { + return log; + } + }); + // todo figure out passing details output to packagelog window.userale.details(window.userale.options()); + window.userale.packageLog(e, events['change']); } else { return false } }); /**You can then use the 'Mapping' API function to modify custom logs created with the packageLog function*/ -window.userale.map(function (log) { - var targetsForLabels = ["cool user!"]; - if (targetsForLabels.includes(log.details)) { - return Object.assign({}, log, { logType: 'custom', customLabel: "follow up" }); + + +document.addEventListener('change', function(e) { + if (e.target.value === 'packageCustomLog') { + window.userale.packageCustomLog({ + customLabel: 'packageCustomLog Example!', + customField1: 'foo', + customField2: 'bar'}, + function(){return 'add additional details here!'}, + true + ); } else { - return log; + return false } }); diff --git a/example/index.html b/example/index.html index 5ca829a..9d42a2c 100644 --- a/example/index.html +++ b/example/index.html @@ -18,16 +18,16 @@ limitations under the License. <!-- Load UserALE.js and set logging parameters--> <script - src="file:///...Apache_Flagon/dev/incubator-flagon-useralejs/build/userale-2.0.2.min.js" + src="file:///Users/jpoore/Documents/Apache_Flagon/dev/incubator-flagon-useralejs/build/userale-2.0.2.min.js" data-url="http://localhost:8000/" data-user="example-user" - data-log-details="true" + data-log-details="false" data-version="2.0.2" data-tool="Apache UserALE.js Example" ></script> <!-- Load UserALE.js API calls to modify log stream --> <script - src="file:///...Apache_Flagon/dev/incubator-flagon-useralejs/example/aleAPI.js" + src="file:///Users/jpoore/Documents/Apache_Flagon/dev/incubator-flagon-useralejs/example/aleAPI.js" ></script> </head> <body> diff --git a/src/attachHandlers.js b/src/attachHandlers.js index f56aa2e..0afb8a2 100644 --- a/src/attachHandlers.js +++ b/src/attachHandlers.js @@ -40,7 +40,8 @@ function extractMouseEvent(e) { 'ctrl' : e.ctrlKey, 'alt' : e.altKey, 'shift' : e.shiftKey, - 'meta' : e.metaKey + 'meta' : e.metaKey, +// 'text' : e.target.innerHTML }; } diff --git a/src/getInitialSettings.js b/src/getInitialSettings.js index e96835a..fa89b45 100644 --- a/src/getInitialSettings.js +++ b/src/getInitialSettings.js @@ -35,7 +35,6 @@ export function getInitialSettings() { })(); var get = script ? script.getAttribute.bind(script) : function() { return null; }; - // @todo add authHeader setting settings.autostart = get('data-autostart') === 'false' ? false : true; settings.url = get('data-url') || 'http://localhost:8000'; settings.transmitInterval = +get('data-interval') || 5000; diff --git a/src/main.js b/src/main.js index d6cae6c..96b6c9b 100644 --- a/src/main.js +++ b/src/main.js @@ -29,6 +29,7 @@ export { setLogMapper as map, setLogFilter as filter, packageLog as packageLog, + packageCustomLog as packageCustomLog, getSelector as getSelector, buildPath as buildPath, } from './packageLogs.js'; diff --git a/src/packageLogs.js b/src/packageLogs.js index 3702b95..9395139 100644 --- a/src/packageLogs.js +++ b/src/packageLogs.js @@ -84,7 +84,6 @@ export function packageLog(e, detailFcn) { (e.timeStamp && e.timeStamp > 0) ? config.time(e.timeStamp) : Date.now() ); - // @todo add host IP in meta data properties var log = { 'target' : getSelector(e.target), 'path' : buildPath(e), @@ -119,6 +118,56 @@ export function packageLog(e, detailFcn) { } /** + * Packages the provided customLog to include standard meta data and appends it to the log container. + * @param {Object} customLog The behavior to be logged. + * @param {Function} detailFcn The function to extract additional log parameters from the event. + * @param {boolean} userAction Indicates user behavior (true) or system behavior (false) + * @return {boolean} Whether the event was logged. + */ +export function packageCustomLog(customLog, detailFcn, userAction) { + if (!config.on) { + return false; + } + + var details = null; + if (detailFcn) { + details = detailFcn(); + } + + var timeFields = extractTimeFields(Date.now()); + + var metaData = { + 'pageUrl': window.location.href, + 'pageTitle': document.title, + 'pageReferrer': document.referrer, + 'clientTime' : timeFields.milli, + 'microTime' : timeFields.micro, + 'logType': 'custom', + 'userAction' : userAction, + 'details' : details, + 'userId' : config.userId, + 'toolVersion' : config.version, + 'toolName' : config.toolName, + 'useraleVersion': config.useraleVersion, + 'sessionID': config.sessionID + }; + + var log = Object.assign(customLog, metaData); + + if ((typeof filterHandler === 'function') && !filterHandler(log)) { + return false; + } + + if (typeof mapHandler === 'function') { + log = mapHandler(log); + } + + logs.push(log); + + return true; +} + +/** * Extract the millisecond and microsecond portions of a timestamp. * @param {Number} timeStamp The timestamp to split into millisecond and microsecond fields. * @return {Object} An object containing the millisecond
