123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- /*
- *
- * 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 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 boolean
- if (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 args
- function logWithArgs(level, args) {
- args = [level].concat([].slice.call(args));
- logger.logLevel.apply(logger, args);
- }
- // return the correct formatString for an object
- function 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 parameters
- var 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 deviceready
- if (!DeviceReady && !UseConsole) {
- Queued.push([level, message]);
- return;
- }
- // Log using the native logger if that is enabled
- if (UseLogger) {
- exec(null, null, "Console", "logLevel", [level, message]);
- }
- // Log using the console if that is enabled
- if (UseConsole) {
- // make sure console is not using logger
- if (console.useLogger()) {
- throw new Error("console and logger are too intertwingly");
- }
- // log to the console
- switch (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 messages
- logger.__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 messages
- document.addEventListener("deviceready", logger.__onDeviceReady, false);
|