/* * * 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 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