- Added changes to javascript for new logging api
- Changed demo page to reflect logger api and added new modules
- Cleaned up config files
diff --git a/client/www/draper.activity_logger-2.1.1.js b/client/www/draper.activity_logger-2.1.1.js
index 5c5ae32..16fb3b0 100644
--- a/client/www/draper.activity_logger-2.1.1.js
+++ b/client/www/draper.activity_logger-2.1.1.js
@@ -32,53 +32,64 @@
draperLog.WF_TRANSFORM = 6;
- // User intent enumeration. This allows the developer to select a finite list
- // of intents the user maybe doing in order to log the event properly.
- draperLog.LOGGING_INTENT = {
+ // User activity enumeration. This allows the developer to select a finite list
+ // of activities the user maybe doing in order to log the event properly.
+ draperLog.LOGGING_ACTIVITY = {
ADD : "add",
REMOVE : "remove",
CREATE : "create",
DELETE : "delete",
SELECT : "select",
+ DESELECT : "deselect",
ENTER : "enter",
LEAVE : "leave",
- EXEC : "execute",
- EXPLORE : "explore",
INSPECT : "inspect",
+ ALTER : "alter",
+ HIDE : "hide",
+ SHOW : "show",
};
- // User Action: This allows the developer to select a finite actions the
- // developer is performing within the application.
- draperLog.LOGGING_ACTION = {
- SCROLL : "scroll",
- KEYPRESS : "keypress",
- TYPE : "type",
- SELECT : "click",
- ZOOM : "zoom",
- HOVER : "hover",
- DROP : "drop",
- DRAG : "drag",
- CLICK : "click",
- DBLCLK : "dblclk",
- };
+ draperLog.LOGGING_COMPONENT = {
+ BUTTON : "button",
+ CANVAS : "canvas",
+ CHECKBOX : "checkbox",
+ COMBOBOX : "combobox",
+ DATAGRID : "datagrid",
+ DIALOGBOX : "dialog_box",
+ DROPDOWNLIST : "dropdownlist",
+ FRAME : "frame",
+ ICON : "icon",
+ INFOBAR : "infobar",
+ LABEL : "label",
+ LINK : "link",
+ LISTBOX : "listbox",
+ MAP : "map",
+ MENU : "menu",
+ MODALWINDOW : "modalwindow",
+ PALETTEWINDOW : "palettewindow",
+ PANEL : "panel",
+ PROGRESSBAR : "progressbar",
+ RADIOBUTTON : "radiobutton",
+ SLIDER : "slider",
+ SPINNER : "spinner",
+ STATUSBAR : "statusbar",
+ TAB : "tab",
+ TABLE : "table",
+ TAG : "tag",
+ TEXTBOX : "textbox",
+ THROBBER : "throbber",
+ TOAST : "toast",
+ TOOLBAR : "toolbar",
+ TOOLTIP : "tooltip",
+ TREEVIEW : "treeview",
+ WINDOW : "window",
+ WORKSPACE : "workspace",
- // draperLog.LOGGING_COMPONENT = {
- // WINDOW : "window",
- // FRAME : "frame",
- // MAP : "map",
- // CANVAS : "canvas",
- // BUTTON : "button",
- // RADIO_BUTTON : "radio_btn",
- // CHECKBOX : "checkbox",
- // TEXTBOX : "textbox",
- // LIST : "list",
- // TABLE : "table",
-
- // // Other is used in conjunction with softwareMetadata in order
- // // to provide a component in which is not currently listed within
- // // the COMPONENT list.
- // OTHER : "other",
- // }
+ // Other is used in conjunction with softwareMetadata in order
+ // to provide a component in which is not currently listed within
+ // the COMPONENT list.
+ OTHER : "other"
+ }
/**
@@ -89,14 +100,14 @@
*
* @method registerActivityLogger
* @param {String} url the url of Draper's Logging Server
- * @param {String} componentName the name of this component
- * @param {String} componentVersion the version of this component
+ * @param {String} toolName the name of the tool being logged.
+ * @param {String} toolVersion the version of this component
*/
- draperLog.registerActivityLogger = function(url, componentName, componentVersion) {
+ draperLog.registerActivityLogger = function(url, toolName, toolVersion) {
draperLog.url = url;
- draperLog.componentName = componentName;
- draperLog.componentVersion = componentVersion;
+ draperLog.toolName = toolName;
+ draperLog.toolVersion = toolVersion;
// get session id from url
function getParameterByName(name) {
@@ -110,7 +121,7 @@
draperLog.clientHostname = getParameterByName('client');
if (!draperLog.sessionID) {
- draperLog.sessionID = draperLog.componentName.slice(0,3) + new Date().getTime();
+ draperLog.sessionID = draperLog.toolName.slice(0,3) + new Date().getTime();
}
if (!draperLog.clientHostname) {
@@ -123,7 +134,7 @@
msg: url
});
- // Felipe: Commented this out currently so we don't have a mix of logs being
+ // Commented this out currently so we don't have a mix of logs being
// sent to the log server.
//classListener();
@@ -145,14 +156,13 @@
// callback which logs the closing and sends the buffer.
window.onbeforeunload = function(e){
draperLog.logUserActivity(
- draperLog.LOGGING_INTENT.REMOVE,
+ draperLog.LOGGING_ACTIVITY.REMOVE, // Logging Action
+ "", // Logging Support Element
+ { id: "draper_browser", // Logging Target Component
+ type: draperLog.LOGGING_COMPONENT.WINDOW,
+ gid: ""},
+ []); // Logging Tags
- // This could be a number of ways
- // in which this could be closed.
- draperLog.LOGGING_ACTION.CLICK,
-
- // The type of object that is being used.
- "draper_browser");
// Since the window is closing and the script will be forced closed,
// ensure the buffer is being sent to the server.
@@ -161,105 +171,232 @@
msg: ''});
};
+ window.onload = function(e){
+ draperLog.logUserActivity(
+ draperLog.LOGGING_ACTIVITY.CREATE, // Logging Action
+ "", // Logging Support Element
+ { id: "draper_browser", // Logging Target Component
+ type: draperLog.LOGGING_COMPONENT.WINDOW,
+ gid: ""},
+ []); // Logging Tags
+ };
+
// Log the activity when the user gains focus on the web browser
// window. In order to do this, we register an onFocus callback function
// which will log the gained focus of the element.
window.onfocus = function(e) {
- console.log(e.detail);
draperLog.logUserActivity(
- draperLog.LOGGING_INTENT.ENTER,
-
- // This could be a number of ways the window
- // focus was gained
- draperLog.LOGGING_ACTION.CLICK,
-
- // The type of object that is being used.
- "draper_browser");
+ draperLog.LOGGING_ACTIVITY.SELECT, // Logging Action
+ "", // Logging Support Element
+ { id: "draper_browser", // Logging Target Component
+ type: draperLog.LOGGING_COMPONENT.WINDOW,
+ gid: ""},
+ []); // Logging Tags
+
};
// Log the activity when the user leaves focus on the web browser
// window. In order to do this, we register an onBlur callback function
// which will log the lost focus
window.onblur = function(e) {
- console.log(e.detail);
draperLog.logUserActivity(
- draperLog.LOGGING_INTENT.LEAVE,
-
- // This could be a number of ways the window
- // focus was gained
- draperLog.LOGGING_ACTION.CLICK,
-
- // The type of object that is being used.
- "draper_browser");
+ draperLog.LOGGING_ACTIVITY.DESELECT, // Logging Action
+ "", // Logging Support Element
+ { id: "draper_browser", // Logging Target Component
+ type: draperLog.LOGGING_COMPONENT.WINDOW,
+ gid: ""},
+ []); // Logging Tags
+
};
return draperLog;
};
+
+ /**
+ * @brief Checks to see if input parameters are valid
+ * @details Checks to see if input parameters are valid. Goes through
+ * each parameter and checks the type of variable it is.
+ *
+ * @param activity Activity parameter which should be a string parameter
+ * @param objectInfo Object Information which should be a string parameter
+ * @param componentInfo Component Info which should be a complex object param
+ * @param Tags Tags parameter should be an array of strings
+ * @return [description]
+ */
+ function _CheckParams(activity, objectInfo, componentInfo, tags)
+ {
+ // Validate that the component object is a valid type of parameter
+ // defined by the developer
+ if( (!_IsValidComponent(componentInfo)) ||
+ (typeof(activity) != "string") ||
+ (typeof(objectInfo) != "string") ||
+ (!(tags instanceof Array)))
+ {
+ return false;
+ }
+
+ // If the code hits here, we have valid parameters being passed into the
+ // logging activity.
+ return true;
+
+ /**
+ * @brief Checks and validates that the component field is a valid file
+ * the right parameters.
+ * @details Checks and validates that the component field is a valid file
+ * the right parameters. Checks the component object on whether it is an
+ * object, has the right parameters, and parameter types.
+ *
+ * @param componentInfo - Component object that contains information
+ * about the target component
+ * @return True if valid, False if not
+ */
+ function _IsValidComponent(componentInfo)
+ {
+ // Check to see if the parameter is an object
+ if ( (typeof(componentInfo) != 'object') ||
+ (!("id" in componentInfo)) ||
+ (!("type" in componentInfo)) ||
+ (!("gid" in componentInfo)))
+ return false;
+ return true;
+ }
+ }
+
+ /**
+ * @brief Construct log constructs the base information about a log.
+ * @details Construct log constructs the base information about a log. The
+ * information generated is based on the log event itself and not the
+ * surrounding meta data around it (version, etc..)
+ *
+ * @param Activity The activity that is being logged. This is based on a list of
+ * logging activities defined above.
+ * @param ObjectInfo The object info is a freeform string that is used to describe the
+ * item that is being alter on within the component. For example, a row in a table.
+ * @param Component Info - A Structured object that contains meta data about
+ * the component being logged. This object contains the "id", "type", and group id
+ * ("gid") of the component
+ * @param tags - An array of string tags to help describe the functionality of
+ * the component.
+ * @return msg - An object that contains the structured logging information.
+ */
+ function constructLog(activity, objectInfo, componentInfo, tags)
+ {
+ // Validate the parameters that are being passed in by
+ // the developer. Ensure the fields are proper before
+ // continuing further.
+ if (!_CheckParams(activity, objectInfo, componentInfo, tags))
+ return null;
+
+ // Construct the initial log message with the information provided by the user.
+ // This will allow us to see what is being logged by the developer.
+ var msg = {
+ type: 'INVALID',
+ parms: {
+ activity: activity,
+ objectInfo: objectInfo,
+ component: componentInfo,
+ tags: []
+ }
+ };
+
+ // Append the tags to the tags field within the component object.
+ // We loop through and do this to ensure all the elements within
+ // the array are strings
+ for (var e in tags){
+ if(typeof(tags[e]) == 'string')
+ msg.parms.tags.push(tags[e]);
+ }
+
+ // Return the constructed log to the caller.
+ return msg;
+ }
+
/**
* Create USER activity message.
- *
- * @method logUserActivity
- * @param {LOGGING_INTENT} userIntent a description of the natural activity that is being performed.
- * @param {LOGGING_ACTION} userActivity a more user input specific action the user is doing.
- * @param {JSON} componentInfo is a more generalized component information. This will contain
- * a specific component type and component ID
- * @param {JSON} softwareMetadata any arbitrary JSON that may support this activity
*/
- draperLog.logUserActivity = function (userIntent, userActivity, componentId, softwareMetadata)
+ draperLog.logUserActivity = function (activity, objectInfo, componentInfo, tags)
{
- if(!muteUserActivityLogging) {
- // Construct the initial log message with the information provided by the user.
- // This will allow us to see what is being logged by the developer.
- var msg = {
- type: 'USERACTION',
- parms: {
- desc: userIntent,
- activity: userActivity,
- wf_state: {},
- wf_version: workflowCodingVersion,
- component: componentId,
- },
- meta: softwareMetadata
- };
- sendMessage(msg);
+ if(muteUserActivityLogging) {
+ return;
+ }
- if (logToConsole) {
- if (testing) {
- console.log('DRAPER LOG: (TESTING) Logging UserActivity', msg.parms);
- } else {
- console.log('DRAPER LOG: Logging UserActivity', msg.parms);
+ // Construct the log with the current parameters for a new log.
+ // Check to see if the function return null. If so, the parameters
+ // were not proper
+ var msg = constructLog(activity, objectInfo, componentInfo, tags);
+ if (msg == null)
+ {
+ if(logToConsole){
+ if(testing)
+ console.error("ActivityLogger: Invalid Parameter(s). Log skipped.");
+ else
+ console.error("(TESTING): ActivityLogger: Invalid Parameter(s). Log skipped.");
+ }
+ return;
}
- }
+
+ // Add User Log Specific Data to the log. This will allow us to
+ // distinguish between user log and system log.
+ msg.type = "USERACTION";
+
+ // Send the logging message to the server. This function will
+ // append the top level meta data to the log and send it to the
+ // server.
+ sendMessage(msg);
+
+ // Check to see if the developer set the debugging "testing" and
+ // "logToConsole" variables
+ if (logToConsole) {
+ if (testing) {
+ console.log('DRAPER LOG: (TESTING) Logging User Activity', msg.parms);
+ } else {
+ console.log('DRAPER LOG: Logging User Activity', msg.parms);
+ }
}
+
};
/**
* Create SYSTEM activity message.
- *
- * @method logSystemActivity
- * @param {String} actionDescription a description of the activity in natural language.
- * @param {JSON} softwareMetadata any arbitrary JSON that may support this activity
*/
- draperLog.logSystemActivity = function (actionDescription, softwareMetadata) {
+ draperLog.logSystemActivity = function (activity, objectInfo, componentInfo, tags) {
- if(!muteSystemActivityLogging) {
- var msg = {
- type: 'SYSACTION',
- parms: {
- desc: actionDescription,
- },
- meta: softwareMetadata
- };
- sendMessage(msg);
+ if(muteSystemActivityLogging)
+ return;
- if (logToConsole) {
- if (testing) {
- console.log('DRAPER LOG: (TESTING) Logging SystemActivity', msg.parms);
- } else {
- console.log('DRAPER LOG: Logging SystemActivity', msg.parms);
+ // Construct the log with the current parameters for a new log.
+ // Check to see if the function return null. If so, the parameters
+ // were not proper
+ var msg = constructLog(activity, objectInfo, componentInfo, tags);
+ if (msg == null)
+ {
+ if(logToConsole){
+ if(testing)
+ console.error("ActivityLogger: Invalid Parameter(s). Log skipped.");
+ else
+ console.error("(TESTING): ActivityLogger: Invalid Parameter(s). Log skipped.");
+ }
+ return;
}
- }
+
+ // Add User Log Specific Data to the log. This will allow us to
+ // distinguish between user log and system log.
+ msg.type = "SYSACTION";
+
+ // Send the logging message to the server. This function will
+ // append the top level meta data to the log and send it to the
+ // server.
+ sendMessage(msg);
+
+ // Check to see if the developer set the debugging "testing" and
+ // "logToConsole" variables
+ if (logToConsole) {
+ if (testing) {
+ console.log('DRAPER LOG: (TESTING) Logging System Activity', msg.parms);
+ } else {
+ console.log('DRAPER LOG: Logging System Activity', msg.parms);
+ }
}
};
@@ -273,7 +410,8 @@
function sendMessage(msg) {
msg.timestamp = new Date().toJSON();
msg.client = draperLog.clientHostname;
- msg.component = {name: draperLog.componentName, version: draperLog.componentVersion};
+ msg.component = { name: draperLog.toolName,
+ version: draperLog.toolVersion};
msg.sessionID = draperLog.sessionID;
msg.impLanguage = 'JavaScript';
msg.apiVersion = draperLog.version;
@@ -346,25 +484,24 @@
* DOM Listener for specific events.
*
*/
- function classListener() {
+ // function classListener() {
+ // $(document).ready(function() {
+ // $(".draper").each(function(i,d){
+ // $(d).on("click", function(a){
+ // draperLog.logUserActivity('User clicked element',
+ // $(this).data('activity'),
+ // $(this).data('wf'));
+ // });
+ // });
- $(document).ready(function() {
- $(".draper").each(function(i,d){
- $(d).on("click", function(a){
- draperLog.logUserActivity('User clicked element',
- $(this).data('activity'),
- $(this).data('wf'));
- });
- });
-
- $(window).scroll(function() {
- clearTimeout($.data(this, 'scrollTimer'));
- $.data(this, 'scrollTimer', setTimeout(function() {
- draperLog.logUserActivity('User scrolled window', 'scroll', 3);
- }, 500));
- });
- });
- }
+ // $(window).scroll(function() {
+ // clearTimeout($.data(this, 'scrollTimer'));
+ // $.data(this, 'scrollTimer', setTimeout(function() {
+ // draperLog.logUserActivity('User scrolled window', 'scroll', 3);
+ // }, 500));
+ // });
+ // });
+ // }
/**
* @brief [brief description]
@@ -373,23 +510,23 @@
* @param elem [description]
* @param msg [description]
*/
- draperLog.tag = function(elem, msg) {
- $.each(msg.events, function(i, d) {
- if (d === 'scroll') {
- console.log('found scroll');
- $(elem).scroll(function() {
- clearTimeout($.data(this, 'scrollTimer'));
- $.data(this, 'scrollTimer', setTimeout(function() {
- draperLog.logUserActivity('User scrolled window', 'scroll', 3);
- }, 500));
- });
- }else{
- $(elem).on(d, function() {
- draperLog.logUserActivity(msg.desc, msg.activity, msg.wf_state);
- });
- }
- });
- };
+ // draperLog.tag = function(elem, msg) {
+ // $.each(msg.events, function(i, d) {
+ // if (d === 'scroll') {
+ // console.log('found scroll');
+ // $(elem).scroll(function() {
+ // clearTimeout($.data(this, 'scrollTimer'));
+ // $.data(this, 'scrollTimer', setTimeout(function() {
+ // draperLog.logUserActivity('User scrolled window', 'scroll', 3);
+ // }, 500));
+ // });
+ // }else{
+ // $(elem).on(d, function() {
+ // draperLog.logUserActivity(msg.desc, msg.activity, msg.wf_state);
+ // });
+ // }
+ // });
+ // };
// Return the activity logger object in which is created. With this,
// object functions and variable are created to keep this a separate instance
diff --git a/client/www/index.html b/client/www/index.html
index 955a782..27abda4 100644
--- a/client/www/index.html
+++ b/client/www/index.html
@@ -14,22 +14,69 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>
<body>
+ <h1>Component #1:</h1>
<div id="canvas"></div>
<div id="help-info">
<p>Mouse over elements to simulate user actions.</p>
<p>You should be able to see these coming through real time on the Kibana server.</p>
<p>Also, if you open the JavaScript console, you should see the logs going out.</p>
</div>
+ <h1>Component #2:</h1>
+ <form border="1px">
+ TestField #1 : <input type="text" id="textfield1"><br><br>
+ TestField #2 : <input type="text" id="textfield2"><br><br>
+ TestField #3 : <input type="text" id="textfield3"><br><br>
+ TestField #4 : <input type="text" id="textfield4"><br><br>
+ </form>
+
<script>
- var activies = [
- 'activiy-A',
- 'activiy-B',
- 'activiy-C',
- 'activiy-D',
- 'activiy-E',
- 'activiy-F',
- 'activiy-G'
- ]
+ var isClick = false;
+ document.addEventListener("mousedown", function() { isClick = true; });
+ document.addEventListener("keydown", function() { isClick = false; });
+
+ // Handle the change event for a specific Text Field in order for us to log
+ // the change of the Text Field.
+ function onChangeTextFields(e){
+ ac.logUserActivity(ac.LOGGING_ACTIVITY.ALTER, "",
+ {id: e.srcElement.id,
+ type: ac.LOGGING_COMPONENT.TEXTBOX,
+ gid: "textbox_group"},
+ ["textbox", "type", "input"]);
+ };
+
+ // Handle the focus event of the Text Field in the order to log the event to the
+ // logging server.
+ function onFocusTextFields(e){
+ ac.logUserActivity(ac.LOGGING_ACTIVITY.SELECT, "",
+ {id: e.srcElement.id,
+ type: ac.LOGGING_COMPONENT.TEXTBOX,
+ gid: "textbox_group"},
+ ["textbox", "type", "input"]);
+ };
+
+ // Handle the blur event of the Text Field in the order to log the event to the
+ // logging server.
+ function onBlurTextFields(e){
+ ac.logUserActivity(ac.LOGGING_ACTIVITY.SELECT, "",
+ {id: e.srcElement.id,
+ type: ac.LOGGING_COMPONENT.TEXTBOX,
+ gid: "textbox_group"},
+ ["textbox", "type", "input"]);
+ }
+
+ // Loop through and register the functions to the events for each of the
+ // text fields.
+ var fields = ["textfield1", "textfield2", "textfield3", "textfield4"];
+ for (i=0; i < fields.length; i++){
+ el = document.getElementById(fields[i]);
+ el.addEventListener("change", onChangeTextFields);
+ el.addEventListener("focus", onFocusTextFields);
+ el.addEventListener("blur", onBlurTextFields);
+ };
+
+ // Generate the 2D color graph in order to provide the
+ // example case of hovering and clicking on elements in order
+ // the system to log events to the user.
var colors = d3.scale.category10()
var svg = d3.select('#canvas').append('svg')
.attr({'w': 200, 'h': 200});
@@ -50,17 +97,17 @@
// Generate the OnMouseOver logging events for the SVG elements
// that are generated by the for loop of SVG elements.
.on('mouseover', function(d) {
- ac.logUserActivity(ac.LOGGING_INTENT.EXPLORE,
- ac.LOGGING_ACTION.HOVER,
- "svg" + d);
+ ac.logUserActivity(ac.LOGGING_ACTIVITY.INSPECT, "rect",
+ {id: "svg" + d, type: ac.LOGGING_COMPONENT.CANVAS, gid: "colorgrid"},
+ ["visual", "inspect_demo", "hover", "click"]);
})
// Generate the Click logging events for the SVG elements
// that are generated by the for loop of SVG elements.
.on('click', function(d) {
- ac.logUserActivity(ac.LOGGING_INTENT.INSPECT,
- ac.LOGGING_ACTION.CLICK,
- "svg" + d);
+ ac.logUserActivity(ac.LOGGING_ACTIVITY.SELECT, "rect",
+ {id: "svg" + d, type: ac.LOGGING_COMPONENT.CANVAS, gid: "colorgrid"},
+ ["visual", "inspect_demo", "hover", "click"]);
})
@@ -76,11 +123,6 @@
"v0.1"
);
- // ac.logUserActivity(
- // 'User hovered over element to read popup', // description
- // 'hover_start', // activity_code
- // ac.WF_EXPLORE // workflow State
- // );
</script>
</body>
</html>
diff --git a/dashboard/files/test.conf b/dashboard/files/test.conf
index 5e51b17..a9397ee 100644
--- a/dashboard/files/test.conf
+++ b/dashboard/files/test.conf
@@ -2,26 +2,16 @@
file {
path => "/home/vagrant/xdata_log"
start_position => beginning
+ codec => "json"
}
-}
-filter {
- json{
- source => "message"
-# target => "tweet"
- }
+
+ unix {
+ path => "/var/log/xdata-unix"
+ codec => "json"
+ }
+
}
-#filter {
-# if [path] =~ "access" {
-# mutate { replace => { "type" => "apache_access" } }
-# grok {
-# match => { "message" => "%{COMBINEDAPACHELOG}" }
-# }
-# }
-# date {
-# match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
-# }
-#}
output {
elasticsearch {
diff --git a/dashboard/files/xdata.conf b/dashboard/files/xdata.conf
index 5b89488..e460a38 100644
--- a/dashboard/files/xdata.conf
+++ b/dashboard/files/xdata.conf
@@ -1,16 +1,11 @@
input {
file {
+ codec => "json"
path => "/var/log/xdata/xdata.log"
start_position => beginning
}
}
-filter {
- json{
- source => "message"
- }
-}
-
output {
elasticsearch {
index => xdata