apps: refactor regular expressions
Refactor code to utilize regular expressions to replace string
manipulation. This will improve performance by reducing the amount of
log line parsing.
BUG=chromium:466247
TEST=ran "grunt test" and manually checked multiple shill logs
Change-Id: I977d03843e1dfaef1434a11a1953587dd1f21b6d
diff --git a/Gruntfile.js b/Gruntfile.js
index 13bb24f..7a99778 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -25,6 +25,7 @@
'./process_log.js',
'./log_helper.js',
'./manager.js',
+ './netlog_summary.js',
'./service.js',
'./syslog_summary.js'
],
diff --git a/log_helper.js b/log_helper.js
index b0b63e3..d29a468 100644
--- a/log_helper.js
+++ b/log_helper.js
@@ -35,182 +35,13 @@
/**
-* RegExp for log timestamp.
-* @type {RegExp}
-*/
+ * RegExp for log timestamp.
+ * @type {RegExp}
+ */
logHelper.TIME_FORMAT =
/\d{4}-\d+-\d+T\d{2}:\d{2}:\d{2}.\d{6}(-|\+)\d{2}:\d{2}/;
/**
-* RegExp for new manager.
-* @type {RegExp}
-*/
-logHelper.NEW_MANAGER = /Manager started./;
-
-/**
- * RegExp for service state change.
- * @type {RegExp}
- **/
-logHelper.SERVICE_STATE = /Service \d+ updated; state:/;
-
-/**
- * RegExp for service state change.
- * @type {RegExp}
- **/
-logHelper.SERVICE_STATE_HINT = /Service \d+: state \D* -> /;
-
-/**
- * RegExp for service destroyed message.
- * @type {RegExp}
- */
-logHelper.SERVICE_DESTROYED = /destroyed/;
-
-/**
- * RegExp for service connect message.
- * @type {RegExp}
- */
-logHelper.SERVICE_CONNECT = /Connect to/;
-
-/**
- * RegExp for link monitor update.
- * @type {RegExp}
- */
-logHelper.LINK_MONITOR = /link_monitor/;
-
-/**
- * RegExp for traffic monitor update.
- * @type {RegExp}
- */
-logHelper.TRAFFIC_MONITOR = /traffic_monitor/;
-
-/**
- * RegExp for suppressed autoconnect message.
- * @type {RegExp}
- */
-logHelper.SUPRESSED = /Suppressed /;
-
-/**
- * RegExp for imminent suspend message.
- * @type {RegExp}
- */
-logHelper.SUSPEND_IMMINENT = / SuspendImminent/;
-
-/**
- * RegExp for suspend done message.
- * @type {RegExp}
- */
-logHelper.SUSPEND_DONE = / SuspendDone/;
-
-/**
-* RegExp for imminent dark suspend message.
-* @type {RegExp}
-*/
-logHelper.DARK_SUSPEND_IMMINENT = / DarkSuspendImminent/;
-
-/**
-* RegExp for dark suspend done message.
-* @type {RegExp}
-*/
-logHelper.DARK_SUSPEND_DONE = / ReportSuspendReadinessInternal.*dark=true/;
-
-
-/**
- * RegExp for state change completed message.
- * @type {RegExp}
- */
-logHelper.COMPLETED = / completed -> completed/;
-
-/**
- * RegExp for scan request message.
- * @type {RegExp}
- */
-logHelper.SCAN = /.*Scan \[.* from .*/;
-
-/**
- * RegExp for ScanDone message
- * @type {RegExp}
- */
-logHelper.SCANDONE = / ScanDone/;
-
-/**
- * RegExp for update from IP config message.
- * @type {RegExp}
- */
-logHelper.UPDATE_FROM_IP_CONFIG = /UpdateFromIPConfig/;
-
-/**
- * RegExp for device updated message.
- * @type {RegExp}
- */
-logHelper.DEVICE_UPDATED = /.*Device.*updated:.*/;
-
-/**
- * RegExp for profile change message.
- * @type {RegExp}
- */
-logHelper.PROFILE_INTERNAL = /.*ProfileInternal.*/;
-
-/**
- * RegExp for device updated message.
- * @type {RegExp}
- */
-logHelper.AP_SCAN = /AP scan/;
-
-/**
- * RegExp for auth_timed_out message.
- * @type {RegExp}
- */
-logHelper.AUTH_TIMED_OUT = /AUTH_TIMED_OUT/;
-
-/**
- * RegExp for added bssid message.
- * @type {RegExp}
- */
-logHelper.ADDED_BSSID = /Added BSSID/;
-
-/**
- * RegExp for disconnection event message.
- * @type {RegExp}
- */
-logHelper.EVENT_DISCONNECTED = /CTRL-EVENT-DISCONNECTED/;
-
-/**
- * RegExp for WPA received packet message.
- * @type {RegExp}
- */
-logHelper.WPA_RX = /WPA: RX/;
-
-/**
- * RegExp for WPA send packet message.
- * @type {RegExp}
- */
-logHelper.WPA_TX = /WPA: Sending/;
-
-/**
- * RegExp for WPA group rekeying message.
- * @type {RegExp}
- */
-logHelper.WPA_GROUP_REKEY = /WPA: Group rekeying/;
-
-/**
- * RegExp for skip roam message.
- * @type {RegExp}
- */
-logHelper.SKIP_ROAM = /Skip roam/;
-
-/**
- * RegExp for connectivity test message.
- * @type {RegExp}
- */
-logHelper.CONNECTIVITY_TEST = /ConnectivityTest/;
-
-/**
- * RegExp for DEAUTH events.
- * @type {RegExp}
- */
-logHelper.DEAUTH_EVENT_TEST = /Event DEAUTH/;
-
-/**
* Method to format an elapsed time in ms to HH:MM:SS.
*
* @param {Number} elapsedMS elapsed ms to format.
@@ -242,24 +73,6 @@
};
/**
- * Helper method checking if a given service state is active.
- *
- * @param {String} state Service state to check.
- * @return {boolean} returns true if the state is considered active
- */
-logHelper.isActive = function(state) {
- if (state == 'Associating' ||
- state == 'Configuring' ||
- state == 'Connected' ||
- state == 'Online' ||
- state == 'Portal' ||
- state == 'Failure') {
- return true;
- }
- return false;
-};
-
-/**
* Array of Objects holding regexs and handlers for system_log subsections
* @type {Object[]}
* @return {int} returns new index into supplied String[]
@@ -288,22 +101,6 @@
};
/**
- * This method processes each log line in the supplied String array to determine
- * if the log is a netlog.
- *
- * @param {String[]} logLines String array for lines in a log.
- * @return {boolean} Returns true is the log is a netlog, false otherwise.
- */
-logHelper.netlogTypeCheck = function(logLines) {
- for (var i = 0; i < logLines.length; i++) {
- if (logHelper.SERVICE_STATE.test(logLines[i])) {
- return true;
- }
- }
- return false;
-};
-
-/**
* Helper method checking what type of log is being processed.
*
* @param {String[]} logLines String array for lines in a log.
@@ -327,7 +124,7 @@
}
if (logHolder.fileType == 'unknown') {
- if (logHelper.netlogTypeCheck(logLines)) {
+ if (netlogSummary.netlogTypeCheck(logLines)) {
// supplied file is netlog
logHolder.fileType = 'netlog';
logHolder.netlog = logLines;
diff --git a/log_summary.js b/log_summary.js
index 5e0ce55..47bcac7 100644
--- a/log_summary.js
+++ b/log_summary.js
@@ -16,302 +16,6 @@
}
/**
- * This method processes each log line in the supplied String array. Each log
- * line is checked to see if matches one of the regular expressions from the
- * logHelper. Each flagged log line is then processed and adds state to the
- * associated manager or service. If the method does not find an appropriate
- * start for the net.log portion of the log, it will make a second pass and
- * attempt to parse the entire file as a net.log file.
- *
- * @param {String[]} logLines String array for lines in a log.
- * @return {Object[]} Returns an Object[] of text and anchor labels if the log
- * was processed, null if the log is not a recognized format.
- */
-LogSummary.prototype.processLogLines = function(logLines) {
- var logStart = -1;
- var netlog = false;
- var currentManager = null;
- var time;
- var secondPass = false;
- var logText = [];
- var timeCheck;
- while (secondPass == netlog) {
- for (var i = 0; i < logLines.length; i++) {
- time = null;
- if (!netlog && logHelper.NET_LOG_START.test(logLines[i])) {
- console.log('this is the start of our log!');
- netlog = true;
- } else if (netlog && logHelper.MULTILINE_LOG_END.test(logLines[i])) {
- if (this.managers.length == 0) {
- console.log('Valid netlog not found.');
- return null;
- }
- console.log('this is the end of our log...');
- netlog = false;
- this.managers[this.managers.length - 1].endTime = this.logEndTime;
- return logText;
- }
- if (netlog) {
- // do we have a start time?
- time = logLines[i].match(logHelper.TIME_FORMAT);
- if (time == null) {
- continue;
- }
- timeCheck = Date.parse(time[0]);
- if (logStart == -1 && time != null) {
- logStart = time[0];
- this.logStartTime = timeCheck;
- this.prevLogLineTime = this.logStartTime;
- if (this.managers.length == 0) {
- //need to add default manager
- currentManager = new Manager(1, this.logStartTime);
- this.managers.push(currentManager);
- }
- }
- if (timeCheck < this.logEndTime) {
- console.log('warning: log time has rolled back, check timezone');
- } else {
- this.logEndTime = timeCheck;
- this.prevLogLineTime = timeCheck;
- }
- console.log('log_line: ' + logLines[i]);
- var tempLogText = {text: logLines[i],
- tag: time[0],
- type: 'basic',
- file: 'netlog',
- ts: timeCheck};
- if (logHelper.NEW_MANAGER.test(logLines[i]) && time[0] != logStart) {
- if (time != null) {
- var new_manager = new Manager(currentManager.id + 1,
- Date.parse(time[0]));
- this.managers[this.managers.length - 1].endTime =
- this.prevLogLineTime;
- this.managers.push(new_manager);
- currentManager = new_manager;
- console.log('added a new manager!', this.managers);
- } else {
- console.log('time == null');
- }
- } else if (logHelper.SERVICE_STATE.test(logLines[i])) {
- var id = logLines[i].slice(logLines[i].indexOf('Service ') + 8,
- logLines[i].indexOf(' updated; '));
- var state = logLines[i].slice(logLines[i].indexOf('state: ') + 7,
- logLines[i].indexOf(' failure'));
- var failure =
- logLines[i].slice(logLines[i].indexOf(' failure') + 9).trim();
- if (failure == 'Unknown') {
- failure = null;
- }
- console.log('*****Service state update!');
- console.log('service [' + id + '][' + state + ']');
- console.log('managers.length: ' + this.managers.length);
- console.log('managers: ', this.managers);
- console.log('failure: ' + failure);
- var currentService = currentManager.getService(id);
- var update = {state: state, time: time[0]};
- if (failure) {
- update.failure = failure;
- }
- currentService.addUpdate(update);
- console.log(currentService);
- if (currentService.isActive) {
- tempLogText.type = 'serviceStateActive';
- } else {
- tempLogText.type = 'serviceState';
- }
- } else if (logHelper.SERVICE_STATE_HINT.test(logLines[i])) {
- var id = logLines[i].slice(logLines[i].indexOf('Service ') + 8,
- logLines[i].indexOf(': state '));
- var serviceCheck = currentManager.getService(id);
- if (!serviceCheck.getCurrentUpdate()) {
- var state = logLines[i].slice(logLines[i].indexOf('state ') + 6,
- logLines[i].indexOf(' -> '));
- var update = {state: state, time: null};
- serviceCheck.addUpdate(update);
- }
- } else if (logHelper.SERVICE_DESTROYED.test(logLines[i])) {
- var id = logLines[i].slice(logLines[i].indexOf('Service ') + 8,
- logLines[i].indexOf(' destroyed.'));
- var current_service = currentManager.getService(id);
- var current_update = current_service.getCurrentUpdate();
- if (current_update != null) {
- addNote(current_update, time[0], 'destroyed');
- } else {
- addNote(current_service, time[0], 'destroyed');
- }
- tempLogText.type = 'faint';
- } else if (logHelper.SERVICE_CONNECT.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('Connect to')));
- } else if (logHelper.LINK_MONITOR.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- 'Link Monitor: ' +
- logLines[i].slice(logLines[i].indexOf('Link')));
- } else if (logHelper.TRAFFIC_MONITOR.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- 'Traffic Monitor: ' +
- logLines[i].slice(logLines[i].indexOf(')] ') + 3));
- /** temporarily commented out to reduce clutter in current display
- *} else if (logHelper.SUPRESSED.test(logLines[i])) {
- * addNote(currentManager,
- * time[0],
- * logLines[i].slice(logLines[i].indexOf(' Suppressed ')));
- */
- } else if (logHelper.SUSPEND_IMMINENT.test(logLines[i])) {
- var message =
- logLines[i].slice(logLines[i].indexOf('SuspendImminent'));
- addNote(currentManager, time[0], message);
- tempLogText.type = 'suspend';
- var active_service = currentManager.getActiveService();
- if (active_service) {
- var current_update = active_service.getCurrentUpdate();
- addNote(current_update, time[0], message);
- }
- currentManager
- .addEventDetail('suspend',
- false,
- Date.parse(time[0]) - currentManager.startTime);
- } else if (logHelper.SUSPEND_DONE.test(logLines[i])) {
- var message =
- logLines[i].slice(logLines[i].indexOf('SuspendDone'));
- addNote(currentManager, time[0], message);
- tempLogText.type = 'suspend';
- var active_service = currentManager.getActiveService();
- if (active_service) {
- var current_update = active_service.getCurrentUpdate();
- addNote(current_update, time[0], message);
- }
- currentManager
- .addEventDetail('suspend',
- true,
- Date.parse(time[0]) - currentManager.startTime);
- } else if (logHelper.DARK_SUSPEND_IMMINENT.test(logLines[i])) {
- var message =
- logLines[i].slice(logLines[i].indexOf('DarkSuspendImminent'));
- addNote(currentManager, time[0], message);
- tempLogText.type = 'suspend';
- var active_service = currentManager.getActiveService();
- if (active_service) {
- var current_update = active_service.getCurrentUpdate();
- addNote(current_update, time[0], message);
- }
- currentManager
- .addEventDetail('darksuspend',
- false,
- Date.parse(time[0]) - currentManager.startTime);
- } else if (logHelper.DARK_SUSPEND_DONE.test(logLines[i])) {
- var message =
- logLines[i].slice(logLines[i].indexOf(' ReportSuspend'));
- addNote(currentManager, time[0], message);
- tempLogText.type = 'suspend';
- var active_service = currentManager.getActiveService();
- if (active_service) {
- var current_update = active_service.getCurrentUpdate();
- addNote(current_update, time[0], message);
- }
- currentManager
- .addEventDetail('darksuspend',
- true,
- Date.parse(time[0]) - currentManager.startTime);
- } else if (logHelper.COMPLETED.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('WiFi')));
- } else if (logHelper.UPDATE_FROM_IP_CONFIG.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('UpdateFromIPConfig')));
- } else if (logHelper.DEVICE_UPDATED.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('Device')));
- } else if (logHelper.PROFILE_INTERNAL.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('\)\] ') + 3));
- } else if (logHelper.SCAN.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('Scan')));
- currentManager.scans++;
- currentManager
- .addEventDetail('scan',
- false,
- Date.parse(time[0]) - currentManager.startTime);
- } else if (logHelper.SCANDONE.test(logLines[i])) {
- currentManager
- .addEventDetail('scan',
- true,
- Date.parse(time[0]) - currentManager.startTime);
- } else if (logHelper.AP_SCAN.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('\]: ') + 3));
- currentManager.scans++;
- } else if (logHelper.AUTH_TIMED_OUT.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('Event ')));
- } else if (logHelper.ADDED_BSSID.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('Added ')));
- } else if (logHelper.EVENT_DISCONNECTED.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('\]: ') + 3));
- } else if (logHelper.WPA_RX.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('\]: ') + 3));
- } else if (logHelper.WPA_TX.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('\]: ') + 3));
- } else if (logHelper.WPA_GROUP_REKEY.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('\]: ') + 3));
- } else if (logHelper.SKIP_ROAM.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('\]: ') + 3));
- } else if (logHelper.CONNECTIVITY_TEST.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('\)\] ') + 3));
- } else if (logHelper.DEAUTH_EVENT_TEST.test(logLines[i])) {
- addNote(currentManager,
- time[0],
- logLines[i].slice(logLines[i].indexOf('\]: ') + 3));
- } else {
- tempLogText.tag = null;
- }
- logText.push(tempLogText);
- }
- }
- if (logStart == -1) {
- if (secondPass) {
- // already tried a second pass.
- return null;
- }
- secondPass = true;
- netlog = true;
- } else {
- // we did find the start of a log, might have been on second pass
- if (secondPass) {
- console.log('this is the end of our log...');
- this.managers[this.managers.length - 1].endTime = this.logEndTime;
- return logText;
- }
- }
- }
-};
-
-/**
* Helper method to add flagged messages to an object.
*
* @param {Object} noteHolder Object to get the new note.
diff --git a/netlog_summary.js b/netlog_summary.js
new file mode 100644
index 0000000..534f286
--- /dev/null
+++ b/netlog_summary.js
@@ -0,0 +1,486 @@
+// Copyright 2015 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+'use strict';
+
+/**
+ * @fileoverview Class to hold methods for processing netlog messages.
+ */
+
+var netlogSummary = {};
+
+/**
+ * Object used for passing state between main processing loop and
+ * regeular expression handler functions.
+ * @constructor
+ * @type {Object}
+ * @param {LogSummary} logSummary object holding log state after processing
+ * @param {Manager} currentManager object of the current manager in log
+ * @param {String} time timestamp of current log line
+ * @param {String[]} results results from regex test
+ */
+function ProcessingState(logSummary, currentManager, time, results) {
+ this.logSummary = logSummary;
+ this.currentManager = currentManager;
+ this.time = time;
+ this.results = results;
+}
+
+/**
+ * Array of Objects holding regexs and handlers for netlog subsections
+ * @type {Object[]}
+ * @return {string} handler functions return log line tag label
+ */
+netlogSummary.taggedLines = {
+ 'new_manager': {
+ re: /Manager started./,
+ handler: function(processingState, result) {
+ var logSummary = processingState.logSummary;
+ var currentManager = processingState.currentManager;
+ if (processingState.time != null) {
+ var new_manager;
+ if (!currentManager) {
+ new_manager = new Manager(1, Date.parse(processingState.time[0]));
+ } else {
+ new_manager = new Manager(processingState.currentManager.id + 1,
+ Date.parse(processingState.time[0]));
+ logSummary.managers[logSummary.managers.length - 1].endTime =
+ logSummary.prevLogLineTime;
+ }
+ logSummary.managers.push(new_manager);
+ processingState.currentManager = new_manager;
+ console.log('added a new manager!', logSummary.managers);
+ } else {
+ console.log('time == null');
+ }
+ return 'basic';
+ }
+ },
+ 'service_state': {
+ re: /Service (\d+) updated; state:* (\w+) failure:* (\D+)/,
+ handler: function(processingState, result) {
+ var logSummary = processingState.logSummary;
+ var id = result[1];
+ var state = result[2];
+ var failure = result[3];
+ if (failure == 'Unknown') {
+ failure = null;
+ }
+ console.log('*****Service state update!');
+ console.log('service [' + id + '][' + state + ']');
+ console.log('managers.length: ' + logSummary.managers.length);
+ console.log('managers: ', logSummary.managers);
+ console.log('failure: ' + failure);
+ var currentService = processingState.currentManager.getService(id);
+ var update = {state: state, time: processingState.time[0]};
+ if (failure) {
+ update.failure = failure;
+ }
+ currentService.addUpdate(update);
+ console.log(currentService);
+ if (currentService.isActive) {
+ return 'serviceStateActive';
+ }
+ return 'serviceState';
+ }
+ },
+ 'service_state_hint': {
+ re: /Service (\d+): state (\w+) -> (\w+)/,
+ handler: function(processingState, result) {
+ var id = result[1];
+ var state = result[2];
+ console.log('service state hint!!!');
+ var serviceCheck = processingState.currentManager.getService(id);
+ if (!serviceCheck.getCurrentUpdate()) {
+ var update = {state: state, time: null};
+ serviceCheck.addUpdate(update);
+ }
+ return 'basic';
+ }
+ },
+ 'service_destroyed': {
+ re: /Service (\d+) destroyed/,
+ handler: function(processingState, result) {
+ var id = result[1];
+ var current_service = processingState.currentManager.getService(id);
+ var current_update = current_service.getCurrentUpdate();
+ if (current_update != null) {
+ addNote(current_update, processingState.time[0], 'destroyed');
+ } else {
+ addNote(current_service, processingState.time[0], 'destroyed');
+ }
+ return 'faint';
+ }
+ },
+ 'service_connect': {
+ re: /Connect to service (\d+): \D+/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[0]);
+ return 'basic';
+ }
+ },
+ 'link_monitor': {
+ re: /link_monitor\S+ (.*$)/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ 'Link Monitor: ' + result[0]);
+ return 'basic';
+ }
+ },
+ 'traffic_monitor': {
+ re: /traffic_monitor\S+ (.*$)/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ 'Traffic Monitor: ' + result[1]);
+ return 'basic';
+ }
+ },
+ 'suspend_imminent': {
+ re: /shill.* SuspendImminent(.*$)/,
+ handler: function(processingState, result) {
+ var time = processingState.time;
+ var currentManager = processingState.currentManager;
+ addNote(currentManager, time[0], 'SuspendImminent');
+ var active_service = currentManager.getActiveService();
+ if (active_service) {
+ var current_update = active_service.getCurrentUpdate();
+ addNote(current_update, time[0], 'SuspendImminent');
+ }
+ currentManager
+ .addEventDetail('suspend',
+ false,
+ Date.parse(time[0]) - currentManager.startTime);
+ return 'suspend';
+ }
+ },
+ 'suspend_done': {
+ re: /shill.* SuspendDone(.*$)/,
+ handler: function(processingState, result) {
+ var time = processingState.time;
+ var currentManager = processingState.currentManager;
+ addNote(currentManager, time[0], 'SuspendDone');
+ var active_service = currentManager.getActiveService();
+ if (active_service) {
+ var current_update = active_service.getCurrentUpdate();
+ addNote(current_update, time[0], 'SuspendDone');
+ }
+ currentManager
+ .addEventDetail('suspend',
+ true,
+ Date.parse(time[0]) - currentManager.startTime);
+ return 'suspend';
+ }
+ },
+ 'dark_suspend_imminent': {
+ re: / DarkSuspendImminent(.*$)/,
+ handler: function(processingState, result) {
+ var time = processingState.time;
+ var currentManager = processingState.currentManager;
+ addNote(currentManager, time[0], result[0]);
+ var active_service = currentManager.getActiveService();
+ if (active_service) {
+ var current_update = active_service.getCurrentUpdate();
+ addNote(current_update, time[0], result[0]);
+ }
+ currentManager
+ .addEventDetail('darksuspend',
+ false,
+ Date.parse(time[0]) - currentManager.startTime);
+ return 'suspend';
+ }
+ },
+ 'dark_suspend_done': {
+ re: /shill.* ReportSuspendReadinessInternal.*dark=true\)/,
+ handler: function(processingState, result) {
+ var time = processingState.time;
+ var currentManager = processingState.currentManager;
+ addNote(currentManager, time[0], 'DarkSuspendDone');
+ var active_service = currentManager.getActiveService();
+ if (active_service) {
+ var current_update = active_service.getCurrentUpdate();
+ addNote(current_update, time[0], 'DarkSuspendDone');
+ }
+ currentManager
+ .addEventDetail('darksuspend',
+ true,
+ Date.parse(time[0]) - currentManager.startTime);
+ return 'suspend';
+ }
+ },
+ 'completed': {
+ re: / WiFi \w+ StateChanged completed -> completed/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[0]);
+ return 'basic';
+ }
+ },
+ 'update_from_ip_config': {
+ re: /UpdateFromIPConfig.*/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[0]);
+ return 'basic';
+ }
+ },
+ 'device_updated': {
+ re: /Device.*updated:.*/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[0]);
+ return 'basic';
+ }
+ },
+ 'profile_internal': {
+ re: /\)\] (.*ProfileInternal.*)/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[1]);
+ return 'basic';
+ }
+ },
+ 'scan': {
+ re: / Scan \[.* from .*/,
+ handler: function(processingState, result) {
+ var currentManager = processingState.currentManager;
+ var time = processingState.time;
+ addNote(currentManager, time[0], result[0]);
+ currentManager.scans++;
+ currentManager
+ .addEventDetail('scan',
+ false,
+ Date.parse(time[0]) - currentManager.startTime);
+ return 'basic';
+ }
+ },
+ 'scandone': {
+ re: / ScanDone/,
+ handler: function(processingState, result) {
+ var currentManager = processingState.currentManager;
+ var time = processingState.time;
+ currentManager
+ .addEventDetail('scan',
+ true,
+ Date.parse(time[0]) - currentManager.startTime);
+ return 'basic';
+ }
+ },
+ 'ap_scan': {
+ re: /\]: (.*AP scan.*)/,
+ handler: function(processingState, result) {
+ var currentManager = processingState.currentManager;
+ var time = processingState.time;
+ addNote(currentManager, time[0], result[1]);
+ currentManager.scans++;
+ return 'basic';
+ }
+ },
+ 'auth_timed_out': {
+ re: /Event.*AUTH_TIMED_OUT.*/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[0]);
+ return 'basic';
+ }
+ },
+ 'added_bssid': {
+ re: /Added BSSID.*/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[0]);
+ return 'basic';
+ }
+ },
+ 'event_disconnected': {
+ re: /\]: (.*CTRL-EVENT-DISCONNECTED.*)/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[1]);
+ return 'basic';
+ }
+ },
+ 'wpa_rx': {
+ re: /\]: (.*WPA: RX.*)/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[1]);
+ return 'basic';
+ }
+ },
+ 'wpa_tx': {
+ re: /\]: (.*WPA: Sending.*)/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[1]);
+ return 'basic';
+ }
+ },
+ 'wpa_group_rekey': {
+ re: /\]: (.*WPA: Group rekeying.*)/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[1]);
+ return 'basic';
+ }
+ },
+ 'skip_roam': {
+ re: /\]: (.*Skip roam.*)/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[1]);
+ return 'basic';
+ }
+ },
+ 'connectivity_test': {
+ re: /\)\] (.*ConnectivityTest.*)/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[1]);
+ return 'basic';
+ }
+ },
+ 'deauth_event': {
+ re: /\]: (.*Event DEAUTH.*)/,
+ handler: function(processingState, result) {
+ addNote(processingState.currentManager,
+ processingState.time[0],
+ result[1]);
+ return 'basic';
+ }
+ }
+};
+
+
+
+/**
+ * Helper method checking if a given service state is active.
+ *
+ * @param {String} state Service state to check.
+ * @return {boolean} returns true if the state is considered active
+ */
+netlogSummary.isActive = function(state) {
+ if (state == 'Associating' ||
+ state == 'Configuring' ||
+ state == 'Connected' ||
+ state == 'Online' ||
+ state == 'Portal' ||
+ state == 'Failure') {
+ return true;
+ }
+ return false;
+};
+
+/**
+ * This method processes each log line in the supplied String array. Each log
+ * line is checked to see if matches one of the regular expressions from the
+ * logHelper. Each flagged log line is then processed and adds state to the
+ * associated manager or service. If the method does not find an appropriate
+ * start for the net.log portion of the log, it will make a second pass and
+ * attempt to parse the entire file as a net.log file.
+ *
+ * @param {String[]} logLines String array for lines in a log.
+ * @param {LogSummary} logSummary Object to hold processed log state.
+ * @return {Object[]} Returns an Object[] of text and anchor labels if the log
+ * was processed, null if the log is not a recognized format.
+ */
+netlogSummary.processLogLines = function(logLines, logSummary) {
+ var logStart = -1;
+ var time;
+ var logText = [];
+ var timeCheck;
+ var result = null;
+ var processingState = new ProcessingState(logSummary, null, time, null);
+
+ for (var i = 0; i < logLines.length; i++) {
+ // do we have a start time?
+ time = logLines[i].match(logHelper.TIME_FORMAT);
+ processingState.time = time;
+ if (time == null) {
+ continue;
+ }
+ timeCheck = Date.parse(time[0]);
+ if (logStart == -1 && time != null) {
+ logStart = time[0];
+ logSummary.logStartTime = timeCheck;
+ logSummary.prevLogLineTime = logSummary.logStartTime;
+ if (logSummary.managers.length == 0 &&
+ !logLines[i].match(netlogSummary.taggedLines['new_manager'].re)) {
+ //need to add default manager
+ processingState.currentManager =
+ new Manager(1, logSummary.logStartTime);
+ logSummary.managers.push(processingState.currentManager);
+ }
+ }
+ if (timeCheck < logSummary.logEndTime) {
+ console.log('warning: log time has rolled back, check timezone');
+ } else {
+ logSummary.logEndTime = timeCheck;
+ logSummary.prevLogLineTime = timeCheck;
+ }
+ console.log('log_line: ' + logLines[i]);
+ var tempLogText = {text: logLines[i],
+ tag: time[0],
+ type: 'basic',
+ file: 'netlog',
+ ts: timeCheck};
+ result = null;
+ for (var taggedLine in netlogSummary.taggedLines) {
+ var result = logLines[i].match(netlogSummary.taggedLines[taggedLine].re);
+ if (result != null) {
+ tempLogText.type =
+ netlogSummary.taggedLines[taggedLine].handler(processingState,
+ result);
+ break;
+ }
+ }
+ if (!result) {
+ tempLogText.tag = null;
+ }
+
+ logText.push(tempLogText);
+ }
+
+ if (logSummary.managers.length == 0) {
+ console.log('Valid netlog not found.');
+ return null;
+ }
+
+ console.log('this is the end of our log...');
+ logSummary.managers[logSummary.managers.length - 1].endTime =
+ logSummary.logEndTime;
+
+ return logText;
+};
+
+/**
+ * This method processes each log line in the supplied String array to determine
+ * if the log is a netlog.
+ *
+ * @param {String[]} logLines String array for lines in a log.
+ * @return {boolean} Returns true is the log is a netlog, false otherwise.
+ */
+netlogSummary.netlogTypeCheck = function(logLines) {
+ for (var i = 0; i < logLines.length; i++) {
+ if (netlogSummary.taggedLines['service_state'].re.test(logLines[i])) {
+ return true;
+ }
+ }
+ return false;
+};
+
diff --git a/process_log.js b/process_log.js
index cebf133..0adb3d0 100644
--- a/process_log.js
+++ b/process_log.js
@@ -56,7 +56,8 @@
}
if (logHolder.netlog) {
- logHolder.netlog = logSummary.processLogLines(logHolder.netlog);
+ logHolder.netlog = netlogSummary.processLogLines(logHolder.netlog,
+ logSummary);
}
if (logHolder.syslog) {
diff --git a/service.js b/service.js
index 7f10cf6..bccac68 100644
--- a/service.js
+++ b/service.js
@@ -32,7 +32,7 @@
return;
}
- if (logHelper.isActive(update.state)) {
+ if (netlogSummary.isActive(update.state)) {
this.isActive = true;
}
if (this.states.length > 0) {
diff --git a/service_states.html b/service_states.html
index 3a5f8ce..d5fbead 100644
--- a/service_states.html
+++ b/service_states.html
@@ -9,6 +9,7 @@
<script src="log_helper.js"></script>
<script src="log_summary.js"></script>
<script src="manager.js"></script>
+ <script src="netlog_summary.js"></script>
<script src="service.js"></script>
<script src="process_log.js"></script>
<script src="syslog_summary.js"></script>
diff --git a/syslog_summary.js b/syslog_summary.js
index 5e844a4..26ead6d 100644
--- a/syslog_summary.js
+++ b/syslog_summary.js
@@ -15,7 +15,6 @@
*/
syslogSummary.KERNEL_INFO = / kernel: \[/;
-
/**
* This method processes each log line in the supplied String array. Each log
* line is checked to see if matches one of the regular expressions from the
diff --git a/test/spec/LogHelperSpec.js b/test/spec/LogHelperSpec.js
index 9769931..e966aac 100644
--- a/test/spec/LogHelperSpec.js
+++ b/test/spec/LogHelperSpec.js
@@ -19,15 +19,52 @@
expect(logHelper.formatElapsedMS('10000000')).toEqual('02:46:40.000');
});
- it('should return true for active states and false for others', function() {
- expect(logHelper.isActive('Unknown')).toBe(false);
- expect(logHelper.isActive('Idle')).toBe(false);
- expect(logHelper.isActive('Associating')).toBe(true);
- expect(logHelper.isActive('Configuring')).toBe(true);
- expect(logHelper.isActive('Connected')).toBe(true);
- expect(logHelper.isActive('Portal')).toBe(true);
- expect(logHelper.isActive('Failure')).toBe(true);
- expect(logHelper.isActive('Online')).toBe(true);
+ it('should detect syslogs', function() {
+ var time1 = '2015-01-06T23:33:03.478905-08:00';
+ var time2 = '2015-01-06T23:33:06.680764-08:00';
+ var time3 = '2015-01-06T23:33:06.681832-08:00';
+
+ var basicLog = [
+ time1 + ' wpa_supplicant[863]: nl80211: Scan trigger',
+ time2 + ' wpa_supplicant[863]: nl80211: Event message available',
+ time3 + ' wpa_supplicant[863]: nl80211: New scan results available'
+ ];
+ var log;
+ var logLines = [
+ '---------- END ----------',
+ '',
+ 'netlog=<multiline>',
+ '---------- START ----------'
+ ];
+ log = logLines.concat(basicLog);
+ log.push('---------- END ----------');
+ var logHolder = logHelper.detectFileType(log);
+ expect(logHolder.fileType).toEqual('system_log');
});
+
+ it('should detect netlogs', function() {
+ var time1 = '2015-01-06T23:33:03.478905-08:00';
+ var time2 = '2015-01-06T23:33:06.680764-08:00';
+ var time3 = '2015-01-06T23:33:06.681832-08:00';
+
+ var basicLog = [
+ time1 + ' Service 0 updated; state: Associating failure Unknown',
+ time2 + ' Service 0: state Idle -> Associating',
+ time3 + ' wpa_supplicant[863]: nl80211: New scan results available'
+ ];
+ var logHolder = logHelper.detectFileType(basicLog);
+ expect(logHolder.fileType).toEqual('netlog');
+ });
+
+ it('should detect an unknown file type', function() {
+ var randomFile = [
+ 'This is not a real log',
+ 'It should not be processed',
+ ' wpa_supplicant[863]: nl80211: New scan results available'
+ ];
+ var logHolder = logHelper.detectFileType(randomFile);
+ expect(logHolder.fileType).toEqual('unknown');
+ });
+
});
diff --git a/test/spec/LogSummarySpec.js b/test/spec/NetlogSummarySpec.js
similarity index 70%
rename from test/spec/LogSummarySpec.js
rename to test/spec/NetlogSummarySpec.js
index fc70073..5d4a622 100644
--- a/test/spec/LogSummarySpec.js
+++ b/test/spec/NetlogSummarySpec.js
@@ -3,10 +3,10 @@
// found in the LICENSE file.
/**
- * @fileoverview Jasmine test file for log_summary.js.
+ * @fileoverview Jasmine test file for netlog_summary.js.
*/
-describe('LogSummary', function() {
+describe('NetlogSummary', function() {
var logSummary;
var basicLog;
var time1;
@@ -27,34 +27,29 @@
});
+ it('should return true for active states and false for others', function() {
+ expect(netlogSummary.isActive('Unknown')).toBe(false);
+ expect(netlogSummary.isActive('Idle')).toBe(false);
+ expect(netlogSummary.isActive('Associating')).toBe(true);
+ expect(netlogSummary.isActive('Configuring')).toBe(true);
+ expect(netlogSummary.isActive('Connected')).toBe(true);
+ expect(netlogSummary.isActive('Portal')).toBe(true);
+ expect(netlogSummary.isActive('Failure')).toBe(true);
+ expect(netlogSummary.isActive('Online')).toBe(true);
+ });
+
it('should gracefully handle empty files', function() {
var empty = [];
- expect(logSummary.processLogLines(empty)).toBe(null);
+ expect(netlogSummary.processLogLines(empty, logSummary)).toBe(null);
});
it('should gracefully handle unrelated files', function() {
var text = ['a', 'b'];
- expect(logSummary.processLogLines(text)).toBe(null);
+ expect(netlogSummary.processLogLines(text, logSummary)).toBe(null);
});
it('should handle net.log files directly', function() {
- var logText = logSummary.processLogLines(basicLog);
- expect(logSummary.logStartTime).toEqual(Date.parse(time1));
- expect(logSummary.logEndTime).toEqual(Date.parse(time3));
- expect(logSummary.managers.length).toBe(1);
- });
-
- it('should handle system logs that include a shill log section', function() {
- var log;
- var logLines = [
- '---------- END ----------',
- '',
- 'netlog=<multiline>',
- '---------- START ----------'
- ];
- log = logLines.concat(basicLog);
- log.push('---------- END ----------');
- var logText = logSummary.processLogLines(log);
+ var logText = netlogSummary.processLogLines(basicLog, logSummary);
expect(logSummary.logStartTime).toEqual(Date.parse(time1));
expect(logSummary.logEndTime).toEqual(Date.parse(time3));
expect(logSummary.managers.length).toBe(1);
@@ -64,7 +59,7 @@
var log;
var logLines = ['licant[781]: wlan0: skip - SSID mismatch'];
log = logLines.concat(basicLog);
- var logText = logSummary.processLogLines(log);
+ var logText = netlogSummary.processLogLines(log, logSummary);
expect(logSummary.logStartTime).toEqual(Date.parse(time1));
expect(logSummary.logEndTime).toEqual(Date.parse(time3));
expect(logSummary.managers.length).toBe(1);
@@ -76,7 +71,7 @@
time2 + ' shill[1066]: [INFO:manager.cc(204)] Manager started.',
time3 + ' shill[937]: [INFO:manager.cc(204)] Manager started.'
];
- var logText = logSummary.processLogLines(log);
+ var logText = netlogSummary.processLogLines(log, logSummary);
expect(logSummary.logStartTime).toEqual(Date.parse(time1));
expect(logSummary.logEndTime).toEqual(Date.parse(time3));
expect(logSummary.managers.length).toBe(3);
@@ -87,21 +82,21 @@
time1 + ' shill[1066]: [INFO:manager.cc(204)] Manager started.',
time2 + ' shill[937]: [INFO:manager.cc(204)] Manager started.'
];
- var logText = logSummary.processLogLines(log);
+ var logText = netlogSummary.processLogLines(log, logSummary);
expect(logSummary.logStartTime).toEqual(Date.parse(time1));
expect(logSummary.logEndTime).toEqual(Date.parse(time2));
expect(logSummary.managers.length).toBe(2);
});
it('should properly set the log end time', function() {
- var logText = logSummary.processLogLines(basicLog);
+ var logText = netlogSummary.processLogLines(basicLog, logSummary);
expect(logSummary.logStartTime).toEqual(Date.parse(time1));
expect(logSummary.logEndTime).toEqual(Date.parse(time3));
});
it('should properly handle a single line log', function() {
var log = [time1 + ' wpa_supplicant[863]: nl80211: Scan trigger'];
- var logText = logSummary.processLogLines(log);
+ var logText = netlogSummary.processLogLines(log, logSummary);
expect(logSummary.logStartTime).toEqual(Date.parse(time1));
expect(logSummary.logEndTime).toEqual(Date.parse(time1));
});