1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 * Intercept and record various classes of log messages. By default, such
8 * messages will be reported by Chrome Developer Tools as coming from this
9 * file, making source-line hyperlinks useless. To fix this click the "gear"
10 * icon in Developer Tools, click "Manage framework blocking..." under
11 * "Sources" and add console_wrapper.js as a "Blackbox" component.
15 /** @suppress {duplicate} */
16 var remoting
= remoting
|| {};
24 remoting
.ConsoleWrapper = function() {
25 console
.assert(instance_
== null,
26 'Duplicate remoting.ConsoleWrapper constructor.');
27 /** @private {number} The number of log entries to save. */
28 this.historyMaxSize_
= 0;
29 /** @private {Array<remoting.ConsoleWrapper.LogEntry>} */
31 /** @private {Object<function(*)>} */
32 this.savedMethods_
= {};
36 * Activate the console wrapper for the specified log types.
38 * @param {number} historyMaxSize The number of log entries to keep.
39 * @param {...remoting.ConsoleWrapper.LogType} var_logTypes The log types to
41 * @suppress {reportUnknownTypes}
43 remoting
.ConsoleWrapper
.prototype.activate
=
44 function(historyMaxSize
, var_logTypes
) {
45 this.historyMaxSize_
= historyMaxSize
;
47 // Restore previous wrappers.
48 for (var key
in remoting
.ConsoleWrapper
.LogType
) {
49 var type
= remoting
.ConsoleWrapper
.LogType
[key
];
50 if (this.savedMethods_
[type
]) {
51 console
[type
] = this.savedMethods_
[type
];
52 delete this.savedMethods_
[type
];
55 // Activate new wrappers
56 for (var i
= 1; i
< arguments
.length
; ++i
) {
57 var type
= arguments
[i
];
58 this.savedMethods_
[type
] = console
[type
];
59 console
[arguments
[i
]] = this.recordAndLog_
.bind(this, arguments
[i
]);
64 * Deactivate the console wrapper for all log types.
66 remoting
.ConsoleWrapper
.prototype.deactivate = function() {
71 * @return {Array<remoting.ConsoleWrapper.LogEntry>} The most recent log
72 * entries as configured by activate().
74 remoting
.ConsoleWrapper
.prototype.getHistory = function() {
79 * @param {remoting.ConsoleWrapper.LogType} type The type of log.
80 * @param {...*} var_args The items to log.
82 * @suppress {reportUnknownTypes}
84 remoting
.ConsoleWrapper
.prototype.recordAndLog_
=
85 function(type
, var_args
) {
86 // Construct a new arguments array by removing the first argument.
87 var args
= Array
.prototype.slice
.call(arguments
, 1);
88 // Find the caller, ignoring the top-most stack frame.
89 var caller
= new base
.Callstack().callstack
[1];
90 var location
= 'unknown';
92 location
= caller
.file
+ ':' + caller
.line
;
95 if (this.historyMaxSize_
> 0) {
98 message
: JSON
.stringify(args
),
100 timestamp
: new Date()
102 // Only save assertions if they fail.
103 if (log
.type
!= 'assert' || !args
[0]) {
104 this.history_
.push(log
);
105 if (this.history_
.length
> this.historyMaxSize_
) {
106 this.history_
.shift();
110 // Log the message, appending the caller.
111 // TODO(jamiewalch): Make the caller gray so that it's less intrusive. This
112 // can be done using a %c formatter in the first argument, but care needs to
113 // be taken to support the multi-argument case.
115 this.savedMethods_
[type
].apply(console
, args
);
119 * @type {remoting.ConsoleWrapper}
121 var instance_
= null;
124 * @return {remoting.ConsoleWrapper} The singleton ConsoleWrapper.
126 remoting
.ConsoleWrapper
.getInstance = function() {
128 instance_
= new remoting
.ConsoleWrapper();
136 * @typedef {{type: string, message: string, caller: string, timestamp: Date}}
138 remoting
.ConsoleWrapper
.LogEntry
;
141 * @enum {string} The log types that can be intercepted. These must match the
142 * names of the corresponding console methods.
144 remoting
.ConsoleWrapper
.LogType
= {