blob: 481dd1f9778092a96a1f1b0909d8fc679f06665d [file] [log] [blame]
// 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 syslog messages.
*/
var androidlogSummary = {};
/**
* RegExp for android log line.
* @type {RegExp}
*/
androidlogSummary.CONNECTIVITY_SERVICE = / ConnectivityService: /;
/**
* Array of Objects holding regexs and handlers for Android subsections
*
* Each Regular expression includes a sample log line. The initial part of the
* log line sample is represented as [timestamp].
*
* @type {Object[]}
* @return {string} CSS class for log line
*/
androidlogSummary.taggedLines = {
'supplicant_disconnected': {
// Sample:
// [timestamp] wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED
// bssid=24:de:c6:e0:89:51 reason=3 locally_generated=1
re: /wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED/,
handler: function(processingState, result) {
logHelper.addNote(processingState.wifiStateMachine,
processingState.time,
result[0]);
return 'supplicant';
}
},
'wifistatemachine_setdetailed': {
// Sample:
// [timestamp] WifiStateMachine: setDetailed state, old =OBTAINING_IPADDR
// and new state=DISCONNECTED hidden=false
re: /WifiStateMachine: setDetailed state, old =(\w+) and new state=(\w+)/,
handler: function(processingState, result) {
var oldState = result[1];
var newState = result[2];
var stateTimestamp = processingState.time;
var states = processingState.wifiStateMachine.networkDetailedStates;
var newStateStart = {'x': stateTimestamp, 'y': newState};
var prevStateEnd = {'x': stateTimestamp, 'y': oldState};
if (states.length > 0) {
var lastUpdate = states[states.length - 1];
if (oldState != lastUpdate.y) {
console.log('warning: last update does not match previous state.' +
'Expected: ' + lastUpdate.y + ' Instead: ' + oldState);
}
if (lastUpdate.y == newState) {
// this state is already represented, return
return 'wsmState';
}
} else {
// Start time unknown: use update timestamp as start time.
var prevStateStart = {'x': stateTimestamp, 'y': oldState};
states.push(prevStateStart);
}
states.push(prevStateEnd);
states.push(newStateStart);
logHelper.addNote(processingState.wifiStateMachine,
stateTimestamp,
result[0]);
return 'wsmState';
}
},
'supplicant_state': {
// Sample:
// [timestamp] wpa_supplicant: wlan0: State: ASSOCIATED -> COMPLETED
re: /wpa_supplicant\[?.*\]?: .*: State: (.*) -> (.*)/,
handler: function(processingState, result) {
var wifiStateMachine = processingState.wifiStateMachine;
var oldState = result[1].toUpperCase();
var newState = result[2].toUpperCase();
var updateTimestamp = processingState.time;
var elapsedTime = Date.parse(updateTimestamp) -
wifiStateMachine.startTime;
var update = {oldState: oldState,
newState: newState,
time: elapsedTime};
logHelper.addSupplicantState(wifiStateMachine.supplicantStates, update);
logHelper.addNote(processingState.wifiStateMachine,
updateTimestamp,
result[0]);
return 'supplicant';
}
}
};
/**
* 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.
*
* @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.
*/
androidlogSummary.processLogLines = function(logLines, logSummary) {
/**
* 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 {String} time timestamp of current log line
* @param {String[]} results results from regex test
*/
function AndroidlogProcessingState(logSummary, time, results) {
this.logSummary = logSummary;
this.time = time;
this.results = results;
}
var logLineTime;
var logText = [];
var parsedLogLineTime;
var processingState = new AndroidlogProcessingState(logSummary, null, null);
var logType = 'android';
for (var i = 0; i < logLines.length; i++) {
console.log('processing log line: ' + logLines[i]);
logLineTime = logLines[i].match(logHelper.ANDROID_TIME_FORMAT);
if (logLineTime === null) {
console.log('not a valid time... skip the log line');
continue;
}
processingState.time = logLineTime[0];
parsedLogLineTime = Date.parse(processingState.time);
if (logSummary.logStartTime == -1) {
logSummary.logStartTime = parsedLogLineTime;
// This is the start of our log so we need to add the first
// WifiStateMachine instance.
processingState.wifiStateMachine =
new WifiStateMachine(1,
parsedLogLineTime,
logHelper.getOffsetMS(processingState.time));
logSummary.wifiStateMachines.push(processingState.wifiStateMachine);
}
if (parsedLogLineTime < logSummary.logEndTime) {
console.log('warning: log time has rolled back.');
} else {
logSummary.logEndTime = parsedLogLineTime;
}
var tempLogText = {text: logLines[i],
tag: null,
type: 'basic',
file: logType,
ts: parsedLogLineTime};
for (var taggedLine in androidlogSummary.taggedLines) {
var result = logLines[i].match(
androidlogSummary.taggedLines[taggedLine].re);
if (result !== null) {
tempLogText.type =
androidlogSummary.taggedLines[taggedLine].handler(processingState,
result);
// Since this line does have a match with the flagged log lines, create
// a tag that allows the summary notes to link to the displayed log.
tempLogText.tag = processingState.time;
break;
}
}
logText.push(tempLogText);
}
if (logSummary.wifiStateMachines.length > 0) {
logSummary.wifiStateMachines[logSummary.wifiStateMachines.length - 1]
.endTime = logSummary.logEndTime;
}
return logText;
};
/**
* This method processes each log line in the supplied String array to determine
* if the log is an android log.
*
* @param {String[]} logLines String array for lines in a log.
* @return {boolean} Returns true is the log is an android log, false otherwise.
*/
androidlogSummary.androidlogTypeCheck = function(logLines) {
for (var i = 0; i < logLines.length; i++) {
if (logHelper.ANDROID_MAIN_SECTION.test(logLines[i]) ||
logHelper.ANDROID_BUG_REPORT.test(logLines[i]) ||
androidlogSummary.CONNECTIVITY_SERVICE.test(logLines[i])) {
return true;
}
}
return false;
};