| // Copyright 2010 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 This class sends logging messages over a message channel to a |
| * server on the main page that prints them using standard logging mechanisms. |
| * |
| */ |
| |
| goog.provide('goog.messaging.LoggerClient'); |
| |
| goog.require('goog.Disposable'); |
| goog.require('goog.debug'); |
| goog.require('goog.debug.LogManager'); |
| goog.require('goog.debug.Logger'); |
| |
| |
| |
| /** |
| * Creates a logger client that sends messages along a message channel for the |
| * remote end to log. The remote end of the channel should use a |
| * {goog.messaging.LoggerServer} with the same service name. |
| * |
| * @param {!goog.messaging.MessageChannel} channel The channel that on which to |
| * send the log messages. |
| * @param {string} serviceName The name of the logging service to use. |
| * @constructor |
| * @extends {goog.Disposable} |
| * @final |
| */ |
| goog.messaging.LoggerClient = function(channel, serviceName) { |
| if (goog.messaging.LoggerClient.instance_) { |
| return goog.messaging.LoggerClient.instance_; |
| } |
| |
| goog.messaging.LoggerClient.base(this, 'constructor'); |
| |
| /** |
| * The channel on which to send the log messages. |
| * @type {!goog.messaging.MessageChannel} |
| * @private |
| */ |
| this.channel_ = channel; |
| |
| /** |
| * The name of the logging service to use. |
| * @type {string} |
| * @private |
| */ |
| this.serviceName_ = serviceName; |
| |
| /** |
| * The bound handler function for handling log messages. This is kept in a |
| * variable so that it can be deregistered when the logger client is disposed. |
| * @type {Function} |
| * @private |
| */ |
| this.publishHandler_ = goog.bind(this.sendLog_, this); |
| goog.debug.LogManager.getRoot().addHandler(this.publishHandler_); |
| |
| goog.messaging.LoggerClient.instance_ = this; |
| }; |
| goog.inherits(goog.messaging.LoggerClient, goog.Disposable); |
| |
| |
| /** |
| * The singleton instance, if any. |
| * @type {goog.messaging.LoggerClient} |
| * @private |
| */ |
| goog.messaging.LoggerClient.instance_ = null; |
| |
| |
| /** |
| * Sends a log message through the channel. |
| * @param {!goog.debug.LogRecord} logRecord The log message. |
| * @private |
| */ |
| goog.messaging.LoggerClient.prototype.sendLog_ = function(logRecord) { |
| var name = logRecord.getLoggerName(); |
| var level = logRecord.getLevel(); |
| var msg = logRecord.getMessage(); |
| var originalException = logRecord.getException(); |
| |
| var exception; |
| if (originalException) { |
| var normalizedException = |
| goog.debug.normalizeErrorObject(originalException); |
| exception = { |
| 'name': normalizedException.name, |
| 'message': normalizedException.message, |
| 'lineNumber': normalizedException.lineNumber, |
| 'fileName': normalizedException.fileName, |
| // Normalized exceptions without a stack have 'stack' set to 'Not |
| // available', so we check for the existance of 'stack' on the original |
| // exception instead. |
| 'stack': originalException.stack || |
| goog.debug.getStacktrace(goog.debug.Logger.prototype.log) |
| }; |
| |
| if (goog.isObject(originalException)) { |
| // Add messageN to the exception in case it was added using |
| // goog.debug.enhanceError. |
| for (var i = 0; 'message' + i in originalException; i++) { |
| exception['message' + i] = String(originalException['message' + i]); |
| } |
| } |
| } |
| this.channel_.send(this.serviceName_, { |
| 'name': name, 'level': level.value, 'message': msg, 'exception': exception |
| }); |
| }; |
| |
| |
| /** @override */ |
| goog.messaging.LoggerClient.prototype.disposeInternal = function() { |
| goog.messaging.LoggerClient.base(this, 'disposeInternal'); |
| goog.debug.LogManager.getRoot().removeHandler(this.publishHandler_); |
| delete this.channel_; |
| goog.messaging.LoggerClient.instance_ = null; |
| }; |