/*\ title: $:/core/modules/utils/logger.js type: application/javascript module-type: utils A basic logging implementation \*/ (function(){ /*jslint node: true, browser: true */ /*global $tw: false */ "use strict"; var ALERT_TAG = "$:/tags/Alert"; /* Make a new logger componentName: logger name, eg: "filesystem" as found in: $:/plugins/tiddlywiki/filesystem/filesystemadaptor.js Options: - colour ... default colour used to style text output - enable ... default: true - logger is enabled - save ... default: true - message will be saved to buffer - saveLimit ... default 100kByte - limit buffer size */ function Logger(componentName,options) { options = options || {}; this.componentName = componentName || ""; this.colour = options.colour || "white"; this.enable = "enable" in options ? options.enable : true; this.save = "save" in options ? options.save : true; this.saveLimit = options.saveLimit || 100 * 1024; this.saveBufferLogger = this; this.buffer = ""; this.alertCount = 0; } Logger.prototype.setSaveBuffer = function(logger) { this.saveBufferLogger = logger; }; Logger.prototype.writeToBuffer = function(/* args */) { var self = this; this.saveBufferLogger.buffer += $tw.utils.formatDateString(new Date(),"YYYY-0MM-0DD 0hh:0mm:0ss.0XXX") + " #"; $tw.utils.each(Array.prototype.slice.call(arguments,0),function(arg,index) { self.saveBufferLogger.buffer += " " + arg.join(" - "); }); this.saveBufferLogger.buffer += "\n"; this.saveBufferLogger.buffer = this.saveBufferLogger.buffer.slice(-this.saveBufferLogger.saveLimit); }; /* Log a message */ Logger.prototype.log = function(/* args */) { if(this.enable) { if(this.saveBufferLogger.save) { this.writeToBuffer(Array.prototype.slice.call(arguments,0)); } if(console !== undefined && console.log !== undefined) { var logMessage = [$tw.utils.terminalColour(this.colour) + this.componentName + ":"].concat(Array.prototype.slice.call(arguments,0)); logMessage[logMessage.length-1] += $tw.utils.terminalColour(); return Function.apply.call(console.log, console, logMessage); } } }; /* Log an "error" message to console.error so it also gets a red colour in browsers */ Logger.prototype.error = function(/* args */) { if(this.enable) { if(this.saveBufferLogger.save) { this.writeToBuffer(Array.prototype.slice.call(arguments,0)); } if(console !== undefined && console.error !== undefined) { var logMessage = [$tw.utils.terminalColour("red") + this.componentName + ":"].concat(Array.prototype.slice.call(arguments,0)); logMessage[logMessage.length-1] += $tw.utils.terminalColour(); return Function.apply.call(console.error, console, logMessage); } } }; /* Log an "info" message to console.info so it also gets an (i) info icon in front */ Logger.prototype.info = function(/* args */) { if(this.enable) { if(this.saveBufferLogger.save) { this.writeToBuffer(Array.prototype.slice.call(arguments,0)); } if(console !== undefined && console.info !== undefined) { var logMessage = [$tw.utils.terminalColour(this.colour) + this.componentName + ":"].concat(Array.prototype.slice.call(arguments,0)); logMessage[logMessage.length-1] += $tw.utils.terminalColour(); return Function.apply.call(console.info, console, logMessage); } } }; /* Log an "warning" message to console.info so it also gets an (!) warning icon in front */ Logger.prototype.warn = function(/* args */) { if(this.enable) { if(this.saveBufferLogger.save) { this.writeToBuffer(Array.prototype.slice.call(arguments,0)); } if(console !== undefined && console.warn !== undefined) { var logMessage = [$tw.utils.terminalColour("orange") + this.componentName + ":"].concat(Array.prototype.slice.call(arguments,0)); logMessage[logMessage.length-1] += $tw.utils.terminalColour(); return Function.apply.call(console.warn, console, logMessage); } } }; /* Read the message buffer */ Logger.prototype.getBuffer = function() { return this.saveBufferLogger.buffer; }; /* Clear the message buffer */ Logger.prototype.clearBuffer = function() { this.saveBufferLogger.buffer = ""; }; /* Log a structure as a table */ Logger.prototype.table = function(value) { (console.table || console.log)(value); }; /* Alert a message */ Logger.prototype.alert = function(/* args */) { if(this.enable) { // Prepare the text of the alert var text = Array.prototype.join.call(arguments," "); // Create alert tiddlers in the browser if($tw.browser) { // Check if there is an existing alert with the same text and the same component var existingAlerts = $tw.wiki.getTiddlersWithTag(ALERT_TAG), alertFields, existingCount, self = this; $tw.utils.each(existingAlerts,function(title) { var tiddler = $tw.wiki.getTiddler(title); if(tiddler.fields.text === text && tiddler.fields.component === self.componentName && tiddler.fields.modified && (!alertFields || tiddler.fields.modified < alertFields.modified)) { alertFields = $tw.utils.extend({},tiddler.fields); } }); if(alertFields) { existingCount = alertFields.count || 1; } else { alertFields = { title: $tw.wiki.generateNewTitle("$:/temp/alerts/alert",{prefix: ""}), text: text, tags: [ALERT_TAG], component: this.componentName }; existingCount = 0; this.alertCount += 1; } alertFields.modified = new Date(); if(++existingCount > 1) { alertFields.count = existingCount; } else { alertFields.count = undefined; } $tw.wiki.addTiddler(new $tw.Tiddler(alertFields)); // Log the alert as well this.log.apply(this,Array.prototype.slice.call(arguments,0)); } else { // Print an orange message to the console if not in the browser console.error("\x1b[1;33m" + text + "\x1b[0m"); } } }; /* Clear outstanding alerts */ Logger.prototype.clearAlerts = function() { var self = this; if($tw.browser && this.alertCount > 0) { $tw.utils.each($tw.wiki.getTiddlersWithTag(ALERT_TAG),function(title) { var tiddler = $tw.wiki.getTiddler(title); if(tiddler.fields.component === self.componentName) { $tw.wiki.deleteTiddler(title); } }); this.alertCount = 0; } }; exports.Logger = Logger; })();