📄 log.js
字号:
// Add the "thread" if available, eg, what the native source of the JS thread // is, such as mouse events, timers, etc if (this.ns.EH && this.ns.EH._thread != null) { msg[2] = this.ns.EH._thread; msg[3] = this._semiColon; } if (priority != null) { msg[4] = this.getPriorityName(priority); msg[5] = this._semiColon; } msg[6] = category; msg[7] = this._semiColon; // allow a prefix to the message to be passed in, so we can do the concat if (msgPrefix) { msg[8] = msgPrefix msg[9] = this._semiColon; } msg[10] = message; var result = msg.join(isc._emptyString); // clear out the array used to construct the message msg.length = 0; return result; }, addLogMessage : function (priority, message, category, msgPrefix, timestamp) { this.addToMasterLog(this._makeLogMessage(priority, message, category, msgPrefix, timestamp)) // show alerts in addition for error and fatal level log messages if (priority != null && (priority == this.FATAL || priority == this.ERROR)) { alert(message); } }, // add a message to the master log // anyone who wants to know when messages are added should observe this method! addToMasterLog : function (message) {//!DONTOBFUSCATE// NOTE: we're not obfuscating so the "message" parameter will retain that name later // remember the message passed in this._messageCache[this._messageIndex] = message; // set up for the next message this._messageIndex++; // if we're beyond the appropriate number of messages to remember if (this._messageIndex > this._messageCount) { // roll over the messsageIndex to 0 this._messageIndex = 0; } }, // return the array of messages stored in the master log getMessages : function () { var cache = this._messageCache, index = this._messageIndex, count = this._messageCount ; return cache.slice(count-index,count).concat(cache.slice(0, index)); }, //> @classMethod Log.show() // Open the Developer Console. // <P> // The Developer Console should <b>always</b> be open while developing any ISC-enabled // application, because ISC logs many important errors and warnings to the Developer Console. // <P> // In Internet Explorer, the Developer Console is able to log a stack trace for every JS error, // including errors that occur in non-ISC code. // <P> // NOTE: if you have the Microsoft JavaScript Debugger installed, ISC will be unable to log // stack traces on JS errors until you go to Tools->Internet Options->Advanced Tab and check // "Disable script debugging". The ability to see stack traces in the Developer Console is // generally much more useful for debugging ISC-based applications than the generic Javascript // Debugging facilities. // // @group debug // @visibility external //< show : function (loading, logWindow, dontSaveState) { if (!this.logViewer) this.logViewer = isc.LogViewer.create(); this.logViewer.showLog(loading, logWindow, dontSaveState); }, //> @classMethod Log.clear() // Clear all currently displayed Log messages // @visibility external //< clear : function () { this._messageCache = []; this._messageIndex = 0; if (this.logViewer) this.logViewer.clear(); }, // update the form in the log viewer updateStats : function (stat) { if (this.logViewer) this.logViewer.updateStats(stat); }, // allow storing log messages before Log class has loaded (advanced internal usage) _logPrelogs : function () { var preLogs = isc._preLog; if (!preLogs) return; for (var i = 0; i < preLogs.length; i++) { var log = preLogs[i]; if (isc.isA.String(log)) this.logDebug(log); else this.logMessage(log.priority || isc.Log.INFO, log.message, log.category, log.timestamp); } isc._preLog = null; }, // Tracing and timing // -------------------------------------------------------------------------------------------- //> @classMethod Log.traceMethod() // // Observe a method on an object, logging a stack trace whenever the method is called. // <P> // Call a second time with identical arguments to disable tracing. // // @param object (object) object to observe // @param methodName (string) name of the method to observe // // @group debug // @visibility external //< traceMethod : function (obj, methodName, callOnly) { // Bail if the arguments aren't valid var object = this.validObservation(obj, methodName); if (!object) return; // Keep a list of what objects / methods we're logging traces for // Note: format is {objName:[methodName1, methodName2]} if (!this._traceRegistry) this._traceRegistry = {}; if (!this._traceRegistry[obj]) this._traceRegistry[obj] = []; // array of method names // observation can only be done by instances, so create an arbitrary instance to // observe with if (!this._observer) this._observer = isc.Class.create(); var observer = this._observer; // If this object is already being traced, stop observation if (observer.isObserving(object, methodName) && this._traceRegistry[obj].contains(methodName)) { observer.ignore(object, methodName); this.logWarn("MethodTimer: Stopped logging stack traces for " + methodName + " method on " + obj); // remove it from the registry this._traceRegistry[obj].remove(methodName); } else { var objName = object.ID ? object.ID : (object.Class ? object.Class : object), expression = "isc.Log.logWarn('" + objName + "." + methodName + "() - trace:' +"; if (callOnly) { expression += "'\\n' + isc.Log.getCallTrace(arguments))"; } else { expression += "isc.Log.getStackTrace())"; } this.logWarn("expression is: " + expression); observer.observe(object, methodName, expression); this.logWarn("MethodTimer: Logging traces whenever " + methodName + " method on " + obj + " is called"); // add it to the registry this._traceRegistry[obj].add(methodName); } }, traceCall : function (obj, methodName) { this.traceMethod(obj, methodName, true); }, //> @classMethod Log.timeMethod() // // Observe a method on an object, logging execution time whenever the method is called. // <P> // Call a second time with identical arguments to disable tracing. // // @param object (object) object to observe // @param methodName (string) name of the method to observe // // @group debug // @visibility external //< _methodPrefix:"$T_", timeMethod : function (obj, methodName, storeTotals, dontLog, causeGC) { // Bail if the arguments aren't valid var object = this.validObservation(obj, methodName); if (!object) return; // Keep a list of what objects / methods we're timing // Note: format is {objName:[methodName1, methodName2]} if (!this._timeRegistry) this._timeRegistry = {}; if (!this._timeRegistry[obj]) this._timeRegistry[obj] = []; // array of method names // already timing the method if (this._timeRegistry[obj].contains(methodName)) return; // Note - to time the method, we rename it, and replace it with a timer method (which will // return the same value var saveMethodName = isc.Log._methodPrefix + methodName, observedMethod = isc._obsPrefix + methodName, // Observation saves original method as _$method oldMethodName = (object[observedMethod] ? observedMethod : methodName) ; // If we're not timing the method: // If the method isn't being observed, we save the original method on the object as // (prefix + method) and replace it with a method that times and calls (prefix + method) // // If the method IS being observed, we do the same thing, except instead of saving and // replacing the current method, we save and replace (isc._obsPrefix + method), which is where the // original method's saved for observation. // // This way, we time only the original method, not the original method + its observer queue. // // This works even if we subsequently observe the method, because the method saved by the // observation mechanism (isc._obsPrefix + method) is left untouched if it already exists. object[saveMethodName] = object[oldMethodName]; object[oldMethodName] = isc.Log.makeTimerFunction( methodName, object, storeTotals, dontLog, causeGC ); this.logWarn("MethodTimer: Timing " + methodName + " method on " + obj); this._timeRegistry[obj].add(methodName); }, stopTimingMethod : function (obj, methodName) { // Bail if the arguments aren't valid var object = this.validObservation(obj, methodName); if (!object) return; // If we're already timing the method, stop timing it. if (this._timeRegistry[obj].contains(methodName)) { var saveMethodName = isc.Log._methodPrefix + methodName, // Observation saves original method as _$method observedMethod = isc._obsPrefix + methodName, oldMethodName = (object[observedMethod] ? observedMethod : methodName) if (!object[saveMethodName]) { // This should never happen but we'll just clean up by deleting the registry entry this.logWarn("Not timing method '" + methodName + "' on object '"+ obj +"'."); this._timeRegistry[obj].remove(methodName); return; } // Stop timing the method: object[oldMethodName] = object[saveMethodName]; delete object[saveMethodName]; this.logWarn("MethodTimer: " + methodName + " method on " + obj + " is no longer being timed"); this._timeRegistry[obj].remove(methodName); return; } }, // generate a function that calls the original message and logs timing data makeTimerFunction : function (methodName, object, storeTotals, dontLog, causeGC) { var method = object[methodName], fullMethodName = isc.Func.getName(method, true); var timerFunc = function (a,b,c,d,e,f,g,h,i,j,k) { // you can use this to take the GC-based variability out of a method being timed if (causeGC) isc.Log._causeGC(); var start = isc.timeStamp(); var returnValue = method.call(this, a,b,c,d,e,f,g,h,i,j,k); var total = (isc.timeStamp()-start); if (!dontLog) isc.Log._logTimerResult(this, fullMethodName, total); return returnValue; } timerFunc._fullName = (object.ID || object.Class || "") + "_" + methodName + "Timing"; timerFunc._isTimer = true; timerFunc._origMethodSlot = isc.Log._methodPrefix + methodName; return timerFunc; }, // logTimerResult: log the result of timing a method _timerMessage : [ "Timed ", , // methodName ": ", , // time "ms" ], _logTimerResult : function (object, methodName, callTime) { if (this.deferTimerLogs) return this._deferTimerLog(object, methodName, callTime); var template = isc.Log._timerMessage;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -