Blame | Last modification | View Log | RSS feed
/*** Licensed to the Apache Software Foundation (ASF) under one* or more contributor license agreements. See the NOTICE file* distributed with this work for additional information* regarding copyright ownership. The ASF licenses this file* to you under the Apache License, Version 2.0 (the* "License"); you may not use this file except in compliance* with the License. You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing,* software distributed under the License is distributed on an* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY* KIND, either express or implied. See the License for the* specific language governing permissions and limitations* under the License.**///------------------------------------------------------------------------------// The logger module exports the following properties/functions://// LOG - constant for the level LOG// ERROR - constant for the level ERROR// WARN - constant for the level WARN// INFO - constant for the level INFO// DEBUG - constant for the level DEBUG// logLevel() - returns current log level// logLevel(value) - sets and returns a new log level// useConsole() - returns whether logger is using console// useConsole(value) - sets and returns whether logger is using console// log(message,...) - logs a message at level LOG// error(message,...) - logs a message at level ERROR// warn(message,...) - logs a message at level WARN// info(message,...) - logs a message at level INFO// debug(message,...) - logs a message at level DEBUG// logLevel(level,message,...) - logs a message specified level////------------------------------------------------------------------------------var logger = exports;var exec = require('cordova/exec');var utils = require('cordova/utils');var UseConsole = false;var UseLogger = true;var Queued = [];var DeviceReady = false;var CurrentLevel;var originalConsole = console;/*** Logging levels*/var Levels = ["LOG","ERROR","WARN","INFO","DEBUG"];/** add the logging levels to the logger object and* to a separate levelsMap object for testing*/var LevelsMap = {};for (var i=0; i<Levels.length; i++) {var level = Levels[i];LevelsMap[level] = i;logger[level] = level;}CurrentLevel = LevelsMap.WARN;/*** Getter/Setter for the logging level** Returns the current logging level.** When a value is passed, sets the logging level to that value.* The values should be one of the following constants:* logger.LOG* logger.ERROR* logger.WARN* logger.INFO* logger.DEBUG** The value used determines which messages get printed. The logging* values above are in order, and only messages logged at the logging* level or above will actually be displayed to the user. E.g., the* default level is WARN, so only messages logged with LOG, ERROR, or* WARN will be displayed; INFO and DEBUG messages will be ignored.*/logger.level = function (value) {if (arguments.length) {if (LevelsMap[value] === null) {throw new Error("invalid logging level: " + value);}CurrentLevel = LevelsMap[value];}return Levels[CurrentLevel];};/*** Getter/Setter for the useConsole functionality** When useConsole is true, the logger will log via the* browser 'console' object.*/logger.useConsole = function (value) {if (arguments.length) UseConsole = !!value;if (UseConsole) {if (typeof console == "undefined") {throw new Error("global console object is not defined");}if (typeof console.log != "function") {throw new Error("global console object does not have a log function");}if (typeof console.useLogger == "function") {if (console.useLogger()) {throw new Error("console and logger are too intertwingly");}}}return UseConsole;};/*** Getter/Setter for the useLogger functionality** When useLogger is true, the logger will log via the* native Logger plugin.*/logger.useLogger = function (value) {// Enforce booleanif (arguments.length) UseLogger = !!value;return UseLogger;};/*** Logs a message at the LOG level.** Parameters passed after message are used applied to* the message with utils.format()*/logger.log = function(message) { logWithArgs("LOG", arguments); };/*** Logs a message at the ERROR level.** Parameters passed after message are used applied to* the message with utils.format()*/logger.error = function(message) { logWithArgs("ERROR", arguments); };/*** Logs a message at the WARN level.** Parameters passed after message are used applied to* the message with utils.format()*/logger.warn = function(message) { logWithArgs("WARN", arguments); };/*** Logs a message at the INFO level.** Parameters passed after message are used applied to* the message with utils.format()*/logger.info = function(message) { logWithArgs("INFO", arguments); };/*** Logs a message at the DEBUG level.** Parameters passed after message are used applied to* the message with utils.format()*/logger.debug = function(message) { logWithArgs("DEBUG", arguments); };// log at the specified level with argsfunction logWithArgs(level, args) {args = [level].concat([].slice.call(args));logger.logLevel.apply(logger, args);}// return the correct formatString for an objectfunction formatStringForMessage(message) {return (typeof message === "string") ? "" : "%o";}/*** Logs a message at the specified level.** Parameters passed after message are used applied to* the message with utils.format()*/logger.logLevel = function(level /* , ... */) {// format the message with the parametersvar formatArgs = [].slice.call(arguments, 1);var fmtString = formatStringForMessage(formatArgs[0]);if (fmtString.length > 0){formatArgs.unshift(fmtString); // add formatString}var message = logger.format.apply(logger.format, formatArgs);if (LevelsMap[level] === null) {throw new Error("invalid logging level: " + level);}if (LevelsMap[level] > CurrentLevel) return;// queue the message if not yet at devicereadyif (!DeviceReady && !UseConsole) {Queued.push([level, message]);return;}// Log using the native logger if that is enabledif (UseLogger) {exec(null, null, "Console", "logLevel", [level, message]);}// Log using the console if that is enabledif (UseConsole) {// make sure console is not using loggerif (console.useLogger()) {throw new Error("console and logger are too intertwingly");}// log to the consoleswitch (level) {case logger.LOG: originalConsole.log(message); break;case logger.ERROR: originalConsole.log("ERROR: " + message); break;case logger.WARN: originalConsole.log("WARN: " + message); break;case logger.INFO: originalConsole.log("INFO: " + message); break;case logger.DEBUG: originalConsole.log("DEBUG: " + message); break;}}};/*** Formats a string and arguments following it ala console.log()** Any remaining arguments will be appended to the formatted string.** for rationale, see FireBug's Console API:* http://getfirebug.com/wiki/index.php/Console_API*/logger.format = function(formatString, args) {return __format(arguments[0], [].slice.call(arguments,1)).join(' ');};//------------------------------------------------------------------------------/*** Formats a string and arguments following it ala vsprintf()** format chars:* %j - format arg as JSON* %o - format arg as JSON* %c - format arg as ''* %% - replace with '%'* any other char following % will format it's* arg via toString().** Returns an array containing the formatted string and any remaining* arguments.*/function __format(formatString, args) {if (formatString === null || formatString === undefined) return [""];if (arguments.length == 1) return [formatString.toString()];if (typeof formatString != "string")formatString = formatString.toString();var pattern = /(.*?)%(.)(.*)/;var rest = formatString;var result = [];while (args.length) {var match = pattern.exec(rest);if (!match) break;var arg = args.shift();rest = match[3];result.push(match[1]);if (match[2] == '%') {result.push('%');args.unshift(arg);continue;}result.push(__formatted(arg, match[2]));}result.push(rest);var remainingArgs = [].slice.call(args);remainingArgs.unshift(result.join(''));return remainingArgs;}function __formatted(object, formatChar) {try {switch(formatChar) {case 'j':case 'o': return JSON.stringify(object);case 'c': return '';}}catch (e) {return "error JSON.stringify()ing argument: " + e;}if ((object === null) || (object === undefined)) {return Object.prototype.toString.call(object);}return object.toString();}//------------------------------------------------------------------------------// when deviceready fires, log queued messageslogger.__onDeviceReady = function() {if (DeviceReady) return;DeviceReady = true;for (var i=0; i<Queued.length; i++) {var messageArgs = Queued[i];logger.logLevel(messageArgs[0], messageArgs[1]);}Queued = null;};// add a deviceready event to log queued messagesdocument.addEventListener("deviceready", logger.__onDeviceReady, false);