Navigation Menu

Skip to content
This repository has been archived by the owner on Oct 18, 2018. It is now read-only.

Commit

Permalink
Allows user to specify where logs go (#119)
Browse files Browse the repository at this point in the history
  • Loading branch information
dglol authored and whimboo committed Apr 4, 2012
1 parent 3e1d0b5 commit eeae109
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 58 deletions.
2 changes: 2 additions & 0 deletions extension/lib/config.js
Expand Up @@ -4,6 +4,7 @@

"use strict";


const self = require('self');
const xulapp = require('xul-app');

Expand All @@ -13,6 +14,7 @@ const xulapp = require('xul-app');
*/
const PREFERENCES = {
// Extension related preferences
log_directory: 'extensions.' + self.id + '.log.directory',
memory_poll_interval: 'extensions.' + self.id + '.memory.interval',
modified_prefs: 'extensions.' + self.id + '.modifiedPrefs',

Expand Down
2 changes: 1 addition & 1 deletion extension/lib/garbage-collector.js
Expand Up @@ -4,7 +4,7 @@

"use strict";

// We have to declare it ourselves because the SDK doens't export it correctly
// We have to declare it ourselves because the SDK doesn't export it correctly
const Cu = Components.utils;


Expand Down
55 changes: 43 additions & 12 deletions extension/lib/logger.js
Expand Up @@ -2,21 +2,27 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

Components.utils.import("resource://gre/modules/NetUtil.jsm");
// We have to declare it ourselves because the SDK doesn't export it correctly
const Cu = Components.utils;

Cu.import('resource://gre/modules/Services.jsm');
Cu.import("resource://gre/modules/NetUtil.jsm");

const { Cc, Ci } = require("chrome");
const unload = require("api-utils/unload");

const PERMS_DIRECTORY = parseInt("0777", 8);
const PERMS_FILE = parseInt("0666", 8);
const PERMS_DIRECTORY = parseInt("0755", 8);
const PERMS_FILE = parseInt("0655", 8);

function Logger(aOptions) {
aOptions = aOptions || {};
this._dir = aOptions.dir;
this._dir = null;
this._file = null;
this._active = false;
this._firstLog = false;

this.dir = aOptions.dir;

unload.ensure(this, 'unload');

// Converter to create input streams out of strings
Expand All @@ -41,6 +47,36 @@ Logger.prototype = {
else {
this.stop();
}
},

get dir() {
return this._dir;
},

set dir(aValue) {
try {
// Check if the value is an instance of nsILocalFile
aValue.QueryInterface(Ci.nsILocalFile);
this._dir = aValue;
}
catch (e) {
// Otherwise we also support a path
if (typeof(aValue) === 'string') {
let dir = Cc['@mozilla.org/file/local;1']
.createInstance(Ci.nsILocalFile);
dir.initWithPath(aValue);
this._dir = dir;
}
else {
throw new TypeError('A directory can only be a string of the path ' +
'or a nsILocalFile');
}
}

// Create the directory if it does not already exist
if (!this._dir.exists()) {
this._dir.create(Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
}
}
};

Expand All @@ -49,12 +85,7 @@ Logger.prototype.unload = function Logger_unload() {
};

Logger.prototype.prepareFile = function Logger_prepareFile() {
if (!this._dir.exists())
this._dir.create(Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
else if (!this._dir.isDirectory())
throw new Error(this._dir.path + " is not a directory.");

var file = this._dir.clone();
var file = this.dir.clone();
file.append(Date.now() + ".log");

this._file = file;
Expand All @@ -69,10 +100,10 @@ Logger.prototype.start = function Logger_start() {
}
};

Logger.prototype.stop = function Logger_stop() {
Logger.prototype.stop = function Logger_stop(aCallback) {
if (this.active) {
this._active = false;
this._writeAsync(']');
this._writeAsync(']', aCallback);
}
};

Expand Down
40 changes: 26 additions & 14 deletions extension/lib/main.js
Expand Up @@ -4,26 +4,23 @@

"use strict";


// We have to declare it ourselves because the SDK doens't export it correctly
// We have to declare it ourselves because the SDK doesn't export it correctly
const Cu = Components.utils;


Cu.import('resource://gre/modules/Services.jsm');

const { Cc, Ci } = require("chrome");
const events = require("events");
const prefs = require("api-utils/preferences-service");
const self = require("self");
const simple_prefs = require("simple-prefs");
const widgets = require("widget");

var { Cc, Ci } = require("chrome");
var events = require("events");
var prefs = require("api-utils/preferences-service");
var self = require("self");
var widgets = require("widget");

var config = require("config");
var garbage_collector = require("garbage-collector");
var { Logger } = require("logger");
const config = require("config");
const garbage_collector = require("garbage-collector");
const { Logger } = require("logger");
var memory = require("memory");


var gData = {
current: {},
previous: {}
Expand All @@ -32,6 +29,17 @@ var gData = {

exports.main = function (options, callbacks) {

// Get the file directory from the prefs,
// and fallback on the profile directory if not specified
var dir = prefs.get(config.preferences.log_directory, "");

if (!dir) {
dir = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
dir.append(self.name);

prefs.set(config.preferences.log_directory, dir.path);
}

// Create logger instance
var dir = Services.dirsvc.get("ProfD", Ci.nsIFile);
dir.append(self.name);
Expand All @@ -54,7 +62,7 @@ exports.main = function (options, callbacks) {
// Show the memchaser directory.
let nsLocalFile = Components.Constructor("@mozilla.org/file/local;1",
"nsILocalFile", "initWithPath");
new nsLocalFile(dir.path).reveal();
new nsLocalFile(logger.dir.path).reveal();
break;
case "logger_status":
logger.active = !logger.active;
Expand Down Expand Up @@ -126,6 +134,10 @@ exports.main = function (options, callbacks) {
widget.port.emit('update_cycle_collector', gData);
logger.log(config.application.topic_cc_statistics, aData);
});

simple_prefs.on('log.directory', function (aData) {
logger.dir = prefs.get(config.preferences.log_directory);
});
}


Expand Down
2 changes: 1 addition & 1 deletion extension/lib/memory.js
Expand Up @@ -4,7 +4,7 @@

"use strict";

// We have to declare it ourselves because the SDK doens't export it correctly
// We have to declare it ourselves because the SDK doesn't export it correctly
const Cu = Components.utils;


Expand Down
6 changes: 6 additions & 0 deletions extension/package.json
Expand Up @@ -16,5 +16,11 @@
"title": "Poll interval for memory information (ms)",
"type": "integer",
"value": 2000
},
{
"name": "log.directory",
"title": "The directory where logs are stored",
"type": "directory",
"value": ""
}]
}
108 changes: 78 additions & 30 deletions extension/test/test-logger.js
Expand Up @@ -3,7 +3,41 @@ Components.utils.import('resource://gre/modules/Services.jsm');
const { Cc, Ci } = require("chrome");
const { Logger } = require("memchaser/logger")

const dir = Services.dirsvc.get("TmpD", Ci.nsIFile);
const dir = Services.dirsvc.get("TmpD", Ci.nsILocalFile);

var verifyAsyncOutput = function (test, logger, testFunc) {
var message = '';

return function (status) {
var line = {}, hasMore;

try {
// open an input stream from file
var istream = Cc["@mozilla.org/network/file-input-stream;1"].
createInstance(Ci.nsIFileInputStream);
istream.init(logger.file, 0x01, parseInt("0444",8), 0);
istream.QueryInterface(Ci.nsILineInputStream);

// read lines into array
do {
hasMore = istream.readLine(line);
message += line.value;
} while (hasMore);
}
finally {
istream.close();
message = JSON.parse(message);

if (typeof(testFunc) === 'function') {
testFunc(message);
}

logger._file.remove(false);
test.assert(!logger._file.exists(), "Clean-up; delete test file");
test.done();
}
};
}

exports.test_default_to_not_logging = function (test) {
var logger = new Logger({ dir: dir });
Expand Down Expand Up @@ -32,43 +66,57 @@ exports.test_start_stop_logging = function (test) {

exports.test_log_and_callback = function (test) {
var logger = new Logger({ dir: dir });
var message = '';

function verifyOutput(status) {
var line = {}, hasMore;
try {
// open an input stream from file
var istream = Cc["@mozilla.org/network/file-input-stream;1"].
createInstance(Ci.nsIFileInputStream);
istream.init(logger.file, 0x01, parseInt("0444",8), 0);
istream.QueryInterface(Ci.nsILineInputStream);
logger.start();
logger.log('test', { x: 50 });
logger.log('test', { x: 60 });
logger.log('test', { x: 70 });
logger.stop(verifyAsyncOutput(test, logger, function (message) {
test.assertEqual(message.length, 3);
test.assertEqual(message[0].data.x, 50);
test.assertEqual(message[1].data.x, 60);
test.assertEqual(message[2].data.x, 70);
}));

// read lines into array
do {
hasMore = istream.readLine(line);
message += line.value;
} while (hasMore);
}
finally {
istream.close();
message = JSON.parse(message);
test.waitUntilDone(2000);
}

test.assertEqual(message.length, 3);
test.assertEqual(message[0].data.x, 50);
test.assertEqual(message[1].data.x, 60);
test.assertEqual(message[2].data.x, 70);
exports.test_start_directory_change_nsIFile = function (test) {
var logger = new Logger({ dir: dir });
var newDir = dir.clone();
newDir.append('newdir');

logger._file.remove(false);
test.assert(!logger._file.exists(), "Clean-up; delete test file");
test.done();
}
}
logger.dir = newDir;
logger.start();
logger.log('test', { x: 50 });
logger.log('test', { x: 60 });
logger.log('test', { x: 70 });
logger.stop(verifyAsyncOutput(test, logger, function (message) {
test.assertEqual(message.length, 3);
test.assertEqual(message[0].data.x, 50);
test.assertEqual(message[1].data.x, 60);
test.assertEqual(message[2].data.x, 70);
}));

test.waitUntilDone(2000);
}

exports.test_start_directory_change_string = function (test) {
var logger = new Logger({ dir: dir });
var newDir = dir.clone();
newDir.append('newdir');

logger.dir = newDir.path;
logger.start();
logger.log('test', { x: 50 });
logger.log('test', { x: 60 });
logger.log('test', { x: 70 }, verifyOutput);
logger.stop();
logger.log('test', { x: 70 });
logger.stop(verifyAsyncOutput(test, logger, function (message) {
test.assertEqual(message.length, 3);
test.assertEqual(message[0].data.x, 50);
test.assertEqual(message[1].data.x, 60);
test.assertEqual(message[2].data.x, 70);
}));

test.waitUntilDone(2000);
}

0 comments on commit eeae109

Please sign in to comment.