Merge fx-team into mozilla-central

This commit is contained in:
Gregory Szorc 2013-07-15 12:11:09 -07:00
Родитель fc156c847f 27896e25c7
Коммит 751089c21c
3 изменённых файлов: 224 добавлений и 24 удалений

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

@ -228,6 +228,12 @@ let StyleSheet = function(form, debuggee) {
this._client.addListener("propertyChange", this._onPropertyChange);
this._client.addListener("styleApplied", this._onStyleApplied);
// Backwards compatibility
this._client.addListener("sourceLoad-" + this._actor, this._onSourceLoad);
this._client.addListener("propertyChange-" + this._actor, this._onPropertyChange);
this._client.addListener("styleApplied-" + this._actor, this._onStyleApplied);
// set initial property values
for (let attr in form) {
this[attr] = form[attr];
@ -324,5 +330,9 @@ StyleSheet.prototype = {
this._client.removeListener("sourceLoad", this._onSourceLoad);
this._client.removeListener("propertyChange", this._onPropertyChange);
this._client.removeListener("styleApplied", this._onStyleApplied);
this._client.removeListener("sourceLoad-" + this._actor, this._onSourceLoad);
this._client.removeListener("propertyChange-" + this._actor, this._onPropertyChange);
this._client.removeListener("styleApplied-" + this._actor, this._onStyleApplied);
}
}

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

@ -36,6 +36,16 @@ this.Log4Moz = {
20: "DEBUG",
10: "TRACE",
0: "ALL"
},
Numbers: {
"FATAL": 70,
"ERROR": 60,
"WARN": 50,
"INFO": 40,
"CONFIG": 30,
"DEBUG": 20,
"TRACE": 10,
"ALL": 0,
}
},
@ -55,6 +65,7 @@ this.Log4Moz = {
Formatter: Formatter,
BasicFormatter: BasicFormatter,
StructuredFormatter: StructuredFormatter,
Appender: Appender,
DumpAppender: DumpAppender,
@ -109,10 +120,15 @@ this.Log4Moz = {
* LogMessage
* Encapsulates a single log event's data
*/
function LogMessage(loggerName, level, message){
function LogMessage(loggerName, level, message, params) {
this.loggerName = loggerName;
this.level = level;
this.message = message;
this.params = params;
// The _structured field will correspond to whether this message is to
// be interpreted as a structured message.
this._structured = this.params && this.params.action;
this.time = Date.now();
}
LogMessage.prototype = {
@ -123,8 +139,12 @@ LogMessage.prototype = {
},
toString: function LogMsg_toString(){
return "LogMessage [" + this.time + " " + this.level + " " +
this.message + "]";
let msg = "LogMessage [" + this.time + " " + this.level + " " +
this.message;
if (this.params) {
msg += " " + JSON.stringify(this.params);
}
return msg + "]"
}
};
@ -211,7 +231,39 @@ Logger.prototype = {
this.updateAppenders();
},
log: function Logger_log(level, string) {
/**
* Logs a structured message object.
*
* @param action
* (string) A message action, one of a set of actions known to the
* log consumer.
* @param params
* (object) Parameters to be included in the message.
* If _level is included as a key and the corresponding value
* is a number or known level name, the message will be logged
* at the indicated level.
*/
logStructured: function (action, params) {
if (!action) {
throw "An action is required when logging a structured message.";
}
if (!params) {
return this.log(this.level, undefined, {"action": action});
}
if (typeof params != "object") {
throw "The params argument is required to be an object.";
}
let level = params._level || this.level;
if ((typeof level == "string") && level in Log4Moz.Level.Numbers) {
level = Log4Moz.Level.Numbers[level];
}
params.action = action;
this.log(level, params._message, params);
},
log: function (level, string, params) {
if (this.level > level)
return;
@ -224,32 +276,32 @@ Logger.prototype = {
continue;
}
if (!message) {
message = new LogMessage(this._name, level, string);
message = new LogMessage(this._name, level, string, params);
}
appender.append(message);
}
},
fatal: function Logger_fatal(string) {
this.log(Log4Moz.Level.Fatal, string);
fatal: function (string, params) {
this.log(Log4Moz.Level.Fatal, string, params);
},
error: function Logger_error(string) {
this.log(Log4Moz.Level.Error, string);
error: function (string, params) {
this.log(Log4Moz.Level.Error, string, params);
},
warn: function Logger_warn(string) {
this.log(Log4Moz.Level.Warn, string);
warn: function (string, params) {
this.log(Log4Moz.Level.Warn, string, params);
},
info: function Logger_info(string) {
this.log(Log4Moz.Level.Info, string);
info: function (string, params) {
this.log(Log4Moz.Level.Info, string, params);
},
config: function Logger_config(string) {
this.log(Log4Moz.Level.Config, string);
config: function (string, params) {
this.log(Log4Moz.Level.Config, string, params);
},
debug: function Logger_debug(string) {
this.log(Log4Moz.Level.Debug, string);
debug: function (string, params) {
this.log(Log4Moz.Level.Debug, string, params);
},
trace: function Logger_trace(string) {
this.log(Log4Moz.Level.Trace, string);
trace: function (string, params) {
this.log(Log4Moz.Level.Trace, string, params);
}
};
@ -314,8 +366,8 @@ LoggerRepository.prototype = {
/*
* Formatters
* These massage a LogMessage into whatever output is desired
* Only the BasicFormatter is currently implemented
* These massage a LogMessage into whatever output is desired.
* BasicFormatter and StructuredFormatter are implemented here.
*/
// Abstract formatter
@ -324,7 +376,7 @@ Formatter.prototype = {
format: function Formatter_format(message) {}
};
// Basic formatter that doesn't do anything fancy
// Basic formatter that doesn't do anything fancy.
function BasicFormatter(dateFormat) {
if (dateFormat)
this.dateFormat = dateFormat;
@ -340,6 +392,36 @@ BasicFormatter.prototype = {
}
};
// Structured formatter that outputs JSON based on message data.
// This formatter will format unstructured messages by supplying
// default values.
function StructuredFormatter() { }
StructuredFormatter.prototype = {
__proto__: Formatter.prototype,
format: function (logMessage) {
let output = {
_time: logMessage.time,
_namespace: logMessage.loggerName,
_level: logMessage.levelDesc
};
for (let key in logMessage.params) {
output[key] = logMessage.params[key];
}
if (!output.action) {
output.action = "UNKNOWN";
}
if (!output._message && logMessage.message) {
output._message = logMessage.message;
}
return JSON.stringify(output);
}
}
/*
* Appenders
* These can be attached to Loggers to log to different places

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

@ -41,8 +41,9 @@ add_test(function test_Logger() {
log.debug("this should be logged but not appended.");
do_check_eq(appender.messages.length, 1);
do_check_true(appender.messages[0].indexOf("info test") > 0);
do_check_true(appender.messages[0].indexOf("INFO") > 0);
let msgRe = /\d+\ttest.logger\t\INFO\tinfo test/;
do_check_true(msgRe.test(appender.messages[0]));
run_next_test();
});
@ -69,6 +70,113 @@ add_test(function test_Logger_parent() {
run_next_test();
});
// A utility method for checking object equivalence.
// Fields with a reqular expression value in expected will be tested
// against the corresponding value in actual. Otherwise objects
// are expected to have the same keys and equal values.
function checkObjects(expected, actual) {
do_check_true(expected instanceof Object);
do_check_true(actual instanceof Object);
for (let key in expected) {
do_check_neq(actual[key], undefined);
if (expected[key] instanceof RegExp) {
do_check_true(expected[key].test(actual[key].toString()));
} else {
if (expected[key] instanceof Object) {
checkObjects(expected[key], actual[key]);
} else {
do_check_eq(expected[key], actual[key]);
}
}
}
for (let key in actual) {
do_check_neq(expected[key], undefined);
}
}
add_test(function test_StructuredLogCommands() {
let appender = new MockAppender(new Log4Moz.StructuredFormatter());
let logger = Log4Moz.repository.getLogger("test.StructuredOutput");
logger.addAppender(appender);
logger.level = Log4Moz.Level.Info;
logger.logStructured("test_message", {_message: "message string one"});
logger.logStructured("test_message", {_message: "message string two",
_level: "ERROR",
source_file: "test_log4moz.js"});
logger.logStructured("test_message");
logger.logStructured("test_message", {source_file: "test_log4moz.js",
message_position: 4});
let messageOne = {"_time": /\d+/,
"_namespace": "test.StructuredOutput",
"_level": "INFO",
"_message": "message string one",
"action": "test_message"};
let messageTwo = {"_time": /\d+/,
"_namespace": "test.StructuredOutput",
"_level": "ERROR",
"_message": "message string two",
"action": "test_message",
"source_file": "test_log4moz.js"};
let messageThree = {"_time": /\d+/,
"_namespace": "test.StructuredOutput",
"_level": "INFO",
"action": "test_message"};
let messageFour = {"_time": /\d+/,
"_namespace": "test.StructuredOutput",
"_level": "INFO",
"action": "test_message",
"source_file": "test_log4moz.js",
"message_position": 4};
checkObjects(messageOne, JSON.parse(appender.messages[0]));
checkObjects(messageTwo, JSON.parse(appender.messages[1]));
checkObjects(messageThree, JSON.parse(appender.messages[2]));
checkObjects(messageFour, JSON.parse(appender.messages[3]));
let errored = false;
try {
logger.logStructured("", {_message: "invalid message"});
} catch (e) {
errored = true;
do_check_eq(e, "An action is required when logging a structured message.");
} finally {
do_check_true(errored);
}
let errored = false;
try {
logger.logStructured("message_action", "invalid params");
} catch (e) {
errored = true;
do_check_eq(e, "The params argument is required to be an object.");
} finally {
do_check_true(errored);
}
// Logging with unstructured interface should produce the same messages
// as the structured interface for these cases.
let appender = new MockAppender(new Log4Moz.StructuredFormatter());
let logger = Log4Moz.repository.getLogger("test.StructuredOutput1");
messageOne._namespace = "test.StructuredOutput1";
messageTwo._namespace = "test.StructuredOutput1";
logger.addAppender(appender);
logger.level = Log4Moz.Level.All;
logger.info("message string one", {action: "test_message"});
logger.error("message string two", {action: "test_message",
source_file: "test_log4moz.js"});
checkObjects(messageOne, JSON.parse(appender.messages[0]));
checkObjects(messageTwo, JSON.parse(appender.messages[1]));
run_next_test();
});
add_test(function test_StorageStreamAppender() {
let appender = new Log4Moz.StorageStreamAppender(testFormatter);
do_check_eq(appender.getInputStream(), null);