| // Copyright 2006 The Closure Library Authors. All Rights Reserved. |
| // |
| // Licensed 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. |
| |
| /** |
| * @fileoverview Definition of various formatters for logging. Please minimize |
| * dependencies this file has on other closure classes as any dependency it |
| * takes won't be able to use the logging infrastructure. |
| * |
| */ |
| |
| goog.provide('goog.debug.Formatter'); |
| goog.provide('goog.debug.HtmlFormatter'); |
| goog.provide('goog.debug.TextFormatter'); |
| |
| goog.require('goog.debug'); |
| goog.require('goog.debug.Logger'); |
| goog.require('goog.debug.RelativeTimeProvider'); |
| goog.require('goog.html.SafeHtml'); |
| |
| |
| |
| /** |
| * Base class for Formatters. A Formatter is used to format a LogRecord into |
| * something that can be displayed to the user. |
| * |
| * @param {string=} opt_prefix The prefix to place before text records. |
| * @constructor |
| */ |
| goog.debug.Formatter = function(opt_prefix) { |
| this.prefix_ = opt_prefix || ''; |
| |
| /** |
| * A provider that returns the relative start time. |
| * @type {goog.debug.RelativeTimeProvider} |
| * @private |
| */ |
| this.startTimeProvider_ = |
| goog.debug.RelativeTimeProvider.getDefaultInstance(); |
| }; |
| |
| |
| /** |
| * Whether to append newlines to the end of formatted log records. |
| * @type {boolean} |
| */ |
| goog.debug.Formatter.prototype.appendNewline = true; |
| |
| |
| /** |
| * Whether to show absolute time in the DebugWindow. |
| * @type {boolean} |
| */ |
| goog.debug.Formatter.prototype.showAbsoluteTime = true; |
| |
| |
| /** |
| * Whether to show relative time in the DebugWindow. |
| * @type {boolean} |
| */ |
| goog.debug.Formatter.prototype.showRelativeTime = true; |
| |
| |
| /** |
| * Whether to show the logger name in the DebugWindow. |
| * @type {boolean} |
| */ |
| goog.debug.Formatter.prototype.showLoggerName = true; |
| |
| |
| /** |
| * Whether to show the logger exception text. |
| * @type {boolean} |
| */ |
| goog.debug.Formatter.prototype.showExceptionText = false; |
| |
| |
| /** |
| * Whether to show the severity level. |
| * @type {boolean} |
| */ |
| goog.debug.Formatter.prototype.showSeverityLevel = false; |
| |
| |
| /** |
| * Formats a record. |
| * @param {goog.debug.LogRecord} logRecord the logRecord to format. |
| * @return {string} The formatted string. |
| */ |
| goog.debug.Formatter.prototype.formatRecord = goog.abstractMethod; |
| |
| |
| /** |
| * Formats a record as SafeHtml. |
| * @param {goog.debug.LogRecord} logRecord the logRecord to format. |
| * @return {!goog.html.SafeHtml} The formatted string as SafeHtml. |
| */ |
| goog.debug.Formatter.prototype.formatRecordAsHtml = goog.abstractMethod; |
| |
| |
| /** |
| * Sets the start time provider. By default, this is the default instance |
| * but can be changed. |
| * @param {goog.debug.RelativeTimeProvider} provider The provider to use. |
| */ |
| goog.debug.Formatter.prototype.setStartTimeProvider = function(provider) { |
| this.startTimeProvider_ = provider; |
| }; |
| |
| |
| /** |
| * Returns the start time provider. By default, this is the default instance |
| * but can be changed. |
| * @return {goog.debug.RelativeTimeProvider} The start time provider. |
| */ |
| goog.debug.Formatter.prototype.getStartTimeProvider = function() { |
| return this.startTimeProvider_; |
| }; |
| |
| |
| /** |
| * Resets the start relative time. |
| */ |
| goog.debug.Formatter.prototype.resetRelativeTimeStart = function() { |
| this.startTimeProvider_.reset(); |
| }; |
| |
| |
| /** |
| * Returns a string for the time/date of the LogRecord. |
| * @param {goog.debug.LogRecord} logRecord The record to get a time stamp for. |
| * @return {string} A string representation of the time/date of the LogRecord. |
| * @private |
| */ |
| goog.debug.Formatter.getDateTimeStamp_ = function(logRecord) { |
| var time = new Date(logRecord.getMillis()); |
| return goog.debug.Formatter.getTwoDigitString_((time.getFullYear() - 2000)) + |
| goog.debug.Formatter.getTwoDigitString_((time.getMonth() + 1)) + |
| goog.debug.Formatter.getTwoDigitString_(time.getDate()) + ' ' + |
| goog.debug.Formatter.getTwoDigitString_(time.getHours()) + ':' + |
| goog.debug.Formatter.getTwoDigitString_(time.getMinutes()) + ':' + |
| goog.debug.Formatter.getTwoDigitString_(time.getSeconds()) + '.' + |
| goog.debug.Formatter.getTwoDigitString_( |
| Math.floor(time.getMilliseconds() / 10)); |
| }; |
| |
| |
| /** |
| * Returns the number as a two-digit string, meaning it prepends a 0 if the |
| * number if less than 10. |
| * @param {number} n The number to format. |
| * @return {string} A two-digit string representation of {@code n}. |
| * @private |
| */ |
| goog.debug.Formatter.getTwoDigitString_ = function(n) { |
| if (n < 10) { |
| return '0' + n; |
| } |
| return String(n); |
| }; |
| |
| |
| /** |
| * Returns a string for the number of seconds relative to the start time. |
| * Prepads with spaces so that anything less than 1000 seconds takes up the |
| * same number of characters for better formatting. |
| * @param {goog.debug.LogRecord} logRecord The log to compare time to. |
| * @param {number} relativeTimeStart The start time to compare to. |
| * @return {string} The number of seconds of the LogRecord relative to the |
| * start time. |
| * @private |
| */ |
| goog.debug.Formatter.getRelativeTime_ = function(logRecord, |
| relativeTimeStart) { |
| var ms = logRecord.getMillis() - relativeTimeStart; |
| var sec = ms / 1000; |
| var str = sec.toFixed(3); |
| |
| var spacesToPrepend = 0; |
| if (sec < 1) { |
| spacesToPrepend = 2; |
| } else { |
| while (sec < 100) { |
| spacesToPrepend++; |
| sec *= 10; |
| } |
| } |
| while (spacesToPrepend-- > 0) { |
| str = ' ' + str; |
| } |
| return str; |
| }; |
| |
| |
| |
| /** |
| * Formatter that returns formatted html. See formatRecord for the classes |
| * it uses for various types of formatted output. |
| * |
| * @param {string=} opt_prefix The prefix to place before text records. |
| * @constructor |
| * @extends {goog.debug.Formatter} |
| */ |
| goog.debug.HtmlFormatter = function(opt_prefix) { |
| goog.debug.Formatter.call(this, opt_prefix); |
| }; |
| goog.inherits(goog.debug.HtmlFormatter, goog.debug.Formatter); |
| |
| |
| /** |
| * Whether to show the logger exception text |
| * @type {boolean} |
| * @override |
| */ |
| goog.debug.HtmlFormatter.prototype.showExceptionText = true; |
| |
| |
| /** |
| * Formats a record |
| * @param {goog.debug.LogRecord} logRecord the logRecord to format. |
| * @return {string} The formatted string as html. |
| * @override |
| */ |
| goog.debug.HtmlFormatter.prototype.formatRecord = function(logRecord) { |
| if (!logRecord) { |
| return ''; |
| } |
| // OK not to use goog.html.SafeHtml.unwrap() here. |
| return this.formatRecordAsHtml(logRecord).getTypedStringValue(); |
| }; |
| |
| |
| /** |
| * Formats a record. |
| * @param {goog.debug.LogRecord} logRecord the logRecord to format. |
| * @return {!goog.html.SafeHtml} The formatted string as SafeHtml. |
| * @override |
| */ |
| goog.debug.HtmlFormatter.prototype.formatRecordAsHtml = function(logRecord) { |
| if (!logRecord) { |
| return goog.html.SafeHtml.EMPTY; |
| } |
| |
| var className; |
| switch (logRecord.getLevel().value) { |
| case goog.debug.Logger.Level.SHOUT.value: |
| className = 'dbg-sh'; |
| break; |
| case goog.debug.Logger.Level.SEVERE.value: |
| className = 'dbg-sev'; |
| break; |
| case goog.debug.Logger.Level.WARNING.value: |
| className = 'dbg-w'; |
| break; |
| case goog.debug.Logger.Level.INFO.value: |
| className = 'dbg-i'; |
| break; |
| case goog.debug.Logger.Level.FINE.value: |
| default: |
| className = 'dbg-f'; |
| break; |
| } |
| |
| // HTML for user defined prefix, time, logger name, and severity. |
| var sb = []; |
| sb.push(this.prefix_, ' '); |
| if (this.showAbsoluteTime) { |
| sb.push('[', goog.debug.Formatter.getDateTimeStamp_(logRecord), '] '); |
| } |
| if (this.showRelativeTime) { |
| sb.push('[', |
| goog.debug.Formatter.getRelativeTime_( |
| logRecord, this.startTimeProvider_.get()), |
| 's] '); |
| } |
| if (this.showLoggerName) { |
| sb.push('[', logRecord.getLoggerName(), '] '); |
| } |
| if (this.showSeverityLevel) { |
| sb.push('[', logRecord.getLevel().name, '] '); |
| } |
| var fullPrefixHtml = |
| goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces(sb.join('')); |
| |
| // HTML for exception text and log record. |
| var exceptionHtml = goog.html.SafeHtml.EMPTY; |
| if (this.showExceptionText && logRecord.getException()) { |
| exceptionHtml = goog.html.SafeHtml.concat( |
| goog.html.SafeHtml.create('br'), |
| goog.debug.exposeExceptionAsHtml(logRecord.getException())); |
| } |
| var logRecordHtml = goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces( |
| logRecord.getMessage()); |
| var recordAndExceptionHtml = goog.html.SafeHtml.create( |
| 'span', |
| {'class': className}, |
| goog.html.SafeHtml.concat(logRecordHtml, exceptionHtml)); |
| |
| |
| // Combine both pieces of HTML and, if needed, append a final newline. |
| var html; |
| if (this.appendNewline) { |
| html = goog.html.SafeHtml.concat(fullPrefixHtml, recordAndExceptionHtml, |
| goog.html.SafeHtml.create('br')); |
| } else { |
| html = goog.html.SafeHtml.concat(fullPrefixHtml, recordAndExceptionHtml); |
| } |
| return html; |
| }; |
| |
| |
| |
| /** |
| * Formatter that returns formatted plain text |
| * |
| * @param {string=} opt_prefix The prefix to place before text records. |
| * @constructor |
| * @extends {goog.debug.Formatter} |
| * @final |
| */ |
| goog.debug.TextFormatter = function(opt_prefix) { |
| goog.debug.Formatter.call(this, opt_prefix); |
| }; |
| goog.inherits(goog.debug.TextFormatter, goog.debug.Formatter); |
| |
| |
| /** |
| * Formats a record as text |
| * @param {goog.debug.LogRecord} logRecord the logRecord to format. |
| * @return {string} The formatted string. |
| * @override |
| */ |
| goog.debug.TextFormatter.prototype.formatRecord = function(logRecord) { |
| var sb = []; |
| sb.push(this.prefix_, ' '); |
| if (this.showAbsoluteTime) { |
| sb.push('[', goog.debug.Formatter.getDateTimeStamp_(logRecord), '] '); |
| } |
| if (this.showRelativeTime) { |
| sb.push('[', goog.debug.Formatter.getRelativeTime_(logRecord, |
| this.startTimeProvider_.get()), 's] '); |
| } |
| |
| if (this.showLoggerName) { |
| sb.push('[', logRecord.getLoggerName(), '] '); |
| } |
| if (this.showSeverityLevel) { |
| sb.push('[', logRecord.getLevel().name, '] '); |
| } |
| sb.push(logRecord.getMessage()); |
| if (this.showExceptionText) { |
| var exception = logRecord.getException(); |
| if (exception) { |
| var exceptionText = exception instanceof Error ? |
| exception.message : |
| exception.toString(); |
| sb.push('\n', exceptionText); |
| } |
| } |
| if (this.appendNewline) { |
| sb.push('\n'); |
| } |
| return sb.join(''); |
| }; |
| |
| |
| /** |
| * Formats a record as text |
| * @param {goog.debug.LogRecord} logRecord the logRecord to format. |
| * @return {!goog.html.SafeHtml} The formatted string as SafeHtml. This is |
| * just an HTML-escaped version of the text obtained from formatRecord(). |
| * @override |
| */ |
| goog.debug.TextFormatter.prototype.formatRecordAsHtml = function(logRecord) { |
| return goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces( |
| goog.debug.TextFormatter.prototype.formatRecord(logRecord)); |
| }; |