Bug 1092074 - Make LogShake feature resilient to read/parse errors. r=gwagner

In the event of broken/unexpected things, we would like to have even a
partial log set dump. This happens for parsing properties values on
Kitkat builds: the current code does all the parsing itself, but the
format of storage of properties evolved with Kitkat base system, and
this makes LogParser to fail, as documented in bug 1079322. Even if we
miss some values, it can still be useful to have the other remaining
ones.
This commit is contained in:
Alexandre Lissy 2014-10-31 05:47:00 +01:00
Родитель f7b0bb3a9c
Коммит f159c5a041
2 изменённых файлов: 98 добавлений и 43 удалений

Просмотреть файл

@ -60,22 +60,6 @@ const CAPTURE_LOGS_START_EVENT = 'capture-logs-start';
const CAPTURE_LOGS_ERROR_EVENT = 'capture-logs-error';
const CAPTURE_LOGS_SUCCESS_EVENT = 'capture-logs-success';
// Map of files which have log-type information to their parsers
const LOGS_WITH_PARSERS = {
'/dev/__properties__': LogParser.prettyPrintPropertiesArray,
'/dev/log/main': LogParser.prettyPrintLogArray,
'/dev/log/system': LogParser.prettyPrintLogArray,
'/dev/log/radio': LogParser.prettyPrintLogArray,
'/dev/log/events': LogParser.prettyPrintLogArray,
'/proc/cmdline': LogParser.prettyPrintArray,
'/proc/kmsg': LogParser.prettyPrintArray,
'/proc/meminfo': LogParser.prettyPrintArray,
'/proc/uptime': LogParser.prettyPrintArray,
'/proc/version': LogParser.prettyPrintArray,
'/proc/vmallocinfo': LogParser.prettyPrintArray,
'/proc/vmstat': LogParser.prettyPrintArray
};
let LogShake = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
/**
@ -91,6 +75,24 @@ let LogShake = {
*/
captureRequested: false,
/**
* Map of files which have log-type information to their parsers
*/
LOGS_WITH_PARSERS: {
'/dev/__properties__': LogParser.prettyPrintPropertiesArray,
'/dev/log/main': LogParser.prettyPrintLogArray,
'/dev/log/system': LogParser.prettyPrintLogArray,
'/dev/log/radio': LogParser.prettyPrintLogArray,
'/dev/log/events': LogParser.prettyPrintLogArray,
'/proc/cmdline': LogParser.prettyPrintArray,
'/proc/kmsg': LogParser.prettyPrintArray,
'/proc/meminfo': LogParser.prettyPrintArray,
'/proc/uptime': LogParser.prettyPrintArray,
'/proc/version': LogParser.prettyPrintArray,
'/proc/vmallocinfo': LogParser.prettyPrintArray,
'/proc/vmstat': LogParser.prettyPrintArray
},
/**
* Start existing, observing motion events if the screen is turned on.
*/
@ -169,7 +171,7 @@ let LogShake = {
if (!this.captureRequested) {
this.captureRequested = true;
SystemAppProxy._sendCustomEvent(CAPTURE_LOGS_START_EVENT, {});
captureLogs().then(logResults => {
this.captureLogs().then(logResults => {
// On resolution send the success event to the requester
SystemAppProxy._sendCustomEvent(CAPTURE_LOGS_SUCCESS_EVENT, {
logFilenames: logResults.logFilenames,
@ -194,6 +196,42 @@ let LogShake = {
}
},
/**
* Captures and saves the current device logs, returning a promise that will
* resolve to an array of log filenames.
*/
captureLogs: function() {
let logArrays = this.readLogs();
return saveLogs(logArrays);
},
/**
* Read in all log files, returning their formatted contents
*/
readLogs: function() {
let logArrays = {};
for (let loc in this.LOGS_WITH_PARSERS) {
let logArray;
try {
logArray = LogCapture.readLogFile(loc);
if (!logArray) {
continue;
}
} catch (ex) {
Cu.reportError("Unable to LogCapture.readLogFile('" + loc + "'): " + ex);
continue;
}
try {
logArrays[loc] = this.LOGS_WITH_PARSERS[loc](logArray);
} catch (ex) {
Cu.reportError("Unable to parse content of '" + loc + "': " + ex);
continue;
}
}
return logArrays;
},
/**
* Stop logshake, removing all listeners
*/
@ -225,32 +263,6 @@ function getLogDirectory() {
return OS.Path.join('logs', timestamp);
}
/**
* Captures and saves the current device logs, returning a promise that will
* resolve to an array of log filenames.
*/
function captureLogs() {
let logArrays = readLogs();
return saveLogs(logArrays);
}
/**
* Read in all log files, returning their formatted contents
*/
function readLogs() {
let logArrays = {};
for (let loc in LOGS_WITH_PARSERS) {
let logArray = LogCapture.readLogFile(loc);
if (!logArray) {
continue;
}
let prettyLogArray = LOGS_WITH_PARSERS[loc](logArray);
logArrays[loc] = prettyLogArray;
}
return logArrays;
}
/**
* Save the formatted arrays of log files to an sdcard if available
*/

Просмотреть файл

@ -135,6 +135,49 @@ add_test(function test_do_nothing_when_screen_off() {
run_next_test();
});
add_test(function test_do_log_capture_resilient_readLogFile() {
// Enable LogShake
LogShake.init();
let readLocations = [];
LogCapture.readLogFile = function(loc) {
readLocations.push(loc);
throw new Error("Exception during readLogFile for: " + loc);
};
// Fire a devicemotion event that is of shake magnitude
sendDeviceMotionEvent(9001, 9001, 9001);
ok(readLocations.length > 0,
'LogShake should attempt to read at least one log');
LogShake.uninit();
run_next_test();
});
add_test(function test_do_log_capture_resilient_parseLog() {
// Enable LogShake
LogShake.init();
let readLocations = [];
LogCapture.readLogFile = function(loc) {
readLocations.push(loc);
LogShake.LOGS_WITH_PARSERS[loc] = function() {
throw new Error("Exception during LogParser for: " + loc);
};
return null;
};
// Fire a devicemotion event that is of shake magnitude
sendDeviceMotionEvent(9001, 9001, 9001);
ok(readLocations.length > 0,
'LogShake should attempt to read at least one log');
LogShake.uninit();
run_next_test();
});
function run_test() {
debug('Starting');
run_next_test();