mirror of
				https://github.com/videojs/video.js.git
				synced 2025-10-31 00:08:01 +02:00 
			
		
		
		
	feat: add support for debug logging (#4780)
Adds support for `debug` as an available logging method under `videojs.log` Changes the default log level from `all` to `info`
This commit is contained in:
		
				
					committed by
					
						 Gary Katsevman
						Gary Katsevman
					
				
			
			
				
	
			
			
			
						parent
						
							4dd41f0332
						
					
				
				
					commit
					ba0f20ec35
				
			| @@ -12,22 +12,23 @@ | ||||
|  | ||||
| ## Logging | ||||
|  | ||||
| Video.js includes `videojs.log`, a lightweight wrapper around a subset of [the `console` API][console]. The available methods are `videojs.log`, `videojs.log.warn`, and `videojs.log.error`. | ||||
| Video.js includes `videojs.log`, a lightweight wrapper around a subset of [the `console` API][console]. The available methods are `videojs.log`, `videojs.log.debug`, `videojs.log.warn`, and `videojs.log.error`. | ||||
|  | ||||
| ### API Overview | ||||
|  | ||||
| Most of these methods should be fairly self-explanatory, but for complete details, see [the API docs][api]. | ||||
|  | ||||
| | Method                          | Alias Of        | Matching Level(s) | | ||||
| | ------------------------------- | --------------- | ----------------- | | ||||
| | `videojs.log()`                 | `console.log`   | all               | | ||||
| | `videojs.log.warn()`            | `console.warn`  | all, warn         | | ||||
| | `videojs.log.error()`           | `console.error` | all, warn, error  | | ||||
| | `videojs.log.level()`           | n/a             | n/a               | | ||||
| | `videojs.log.history()`         | n/a             | n/a               | | ||||
| | `videojs.log.history.clear()`   | n/a             | n/a               | | ||||
| | `videojs.log.history.disable()` | n/a             | n/a               | | ||||
| | `videojs.log.history.enable()`  | n/a             | n/a               | | ||||
| | Method                          | Alias Of         | Matching Level(s)              | | ||||
| | ------------------------------- | ---------------- | ------------------------------ | | ||||
| | `videojs.log()`                 | `console.log`    | all, debug, info               | | ||||
| | `videojs.log.debug()            | `console.debug`  | all, debug                     | | ||||
| | `videojs.log.warn()`            | `console.warn`   | all, debug, info, warn         | | ||||
| | `videojs.log.error()`           | `console.error`  | all, debug, info, warn, error  | | ||||
| | `videojs.log.level()`           | n/a              | n/a                            | | ||||
| | `videojs.log.history()`         | n/a              | n/a                            | | ||||
| | `videojs.log.history.clear()`   | n/a              | n/a                            | | ||||
| | `videojs.log.history.disable()` | n/a              | n/a                            | | ||||
| | `videojs.log.history.enable()`  | n/a              | n/a                            | | ||||
|  | ||||
| For descriptions of these features, please refer to the sections below. | ||||
|  | ||||
| @@ -62,7 +63,7 @@ Unlike the `console`, `videojs.log` includes the concept of logging levels. Thes | ||||
| Levels are exposed through the `videojs.log.level` method. This method acts as both a getter and setter for the current logging level. With no arguments, it returns the current logging level: | ||||
|  | ||||
| ```js | ||||
| videojs.log.level(); // "all" | ||||
| videojs.log.level(); // "info" | ||||
| ``` | ||||
|  | ||||
| By passing a string, the logging level can be changed to one of the available logging levels: | ||||
| @@ -76,10 +77,16 @@ videojs.log.error('foo'); // logs "foo" as an error | ||||
|  | ||||
| ### Available Log Levels | ||||
|  | ||||
| * **all** (default): enables all logging methods | ||||
| * **info** (default): only show `log`, `log.warn`, and `log.error` messages | ||||
| * **all**: enables all logging methods | ||||
| * **error**: only show `log.error` messages | ||||
| * **off**: disable all logging methods | ||||
| * **warn**: only show `log.warn` _and_ `log.error` messages | ||||
| * **debug**: show `log`, `log.debug`, `log.warn`, and `log.error` messages | ||||
|  | ||||
| ### Debug Logging | ||||
|  | ||||
| Although the log levels attempt to match their `window.console` counterparts, `window.console.debug` is not available on all platforms. As such, it will use the closest comparable method, falling back from `window.console.debug` to `window.console.info` to `window.console.log`, and ultimately to nothing if none of those methods are available. | ||||
|  | ||||
| ### History | ||||
|  | ||||
|   | ||||
| @@ -9,7 +9,7 @@ import {isObject} from './obj'; | ||||
| let log; | ||||
|  | ||||
| // This is the private tracking variable for logging level. | ||||
| let level = 'all'; | ||||
| let level = 'info'; | ||||
|  | ||||
| // This is the private tracking variable for the logging history. | ||||
| let history = []; | ||||
| @@ -48,11 +48,20 @@ export const logByType = (type, args, stringify = !!IE_VERSION && IE_VERSION < 1 | ||||
|  | ||||
|   // If there's no console then don't try to output messages, but they will | ||||
|   // still be stored in history. | ||||
|   // | ||||
|   if (!window.console) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // Was setting these once outside of this function, but containing them | ||||
|   // in the function makes it easier to test cases where console doesn't exist | ||||
|   // when the module is executed. | ||||
|   const fn = window.console && window.console[type]; | ||||
|   let fn = window.console[type]; | ||||
|  | ||||
|   if (!fn && type === 'debug') { | ||||
|     // Certain browsers don't have support for console.debug. For those, we | ||||
|     // should default to the closest comparable log. | ||||
|     fn = window.console.info || window.console.log; | ||||
|   } | ||||
|  | ||||
|   // Bail out if there's no console or if this type is not allowed by the | ||||
|   // current logging level. | ||||
| @@ -108,18 +117,22 @@ log = function(...args) { | ||||
|  * | ||||
|  * - `off`: Matches no calls. Any value that can be cast to `false` will have | ||||
|  *   this effect. The most restrictive. | ||||
|  * - `all` (default): Matches only Video.js-provided functions (`log`, | ||||
|  * - `all`: Matches only Video.js-provided functions (`debug`, `log`, | ||||
|  *   `log.warn`, and `log.error`). | ||||
|  * - `debug`: Matches `log.debug`, `log`, `log.warn`, and `log.error` calls. | ||||
|  * - `info` (default): Matches `log`, `log.warn`, and `log.error` calls. | ||||
|  * - `warn`: Matches `log.warn` and `log.error` calls. | ||||
|  * - `error`: Matches only `log.error` calls. | ||||
|  * | ||||
|  * @type {Object} | ||||
|  */ | ||||
| log.levels = { | ||||
|   all: 'log|warn|error', | ||||
|   error: 'error', | ||||
|   all: 'debug|log|warn|error', | ||||
|   off: '', | ||||
|   debug: 'debug|log|warn|error', | ||||
|   info: 'log|warn|error', | ||||
|   warn: 'warn|error', | ||||
|   error: 'error', | ||||
|   DEFAULT: level | ||||
| }; | ||||
|  | ||||
| @@ -200,4 +213,13 @@ log.error = (...args) => logByType('error', args); | ||||
|  */ | ||||
| log.warn = (...args) => logByType('warn', args); | ||||
|  | ||||
| /** | ||||
|  * Logs debug messages. Similar to `console.debug`, but may also act as a comparable | ||||
|  * log if `console.debug` is not available | ||||
|  * | ||||
|  * @param {Mixed[]} args | ||||
|  *        One or more messages or objects that should be logged as debug. | ||||
|  */ | ||||
| log.debug = (...args) => logByType('debug', args); | ||||
|  | ||||
| export default log; | ||||
|   | ||||
| @@ -18,6 +18,8 @@ QUnit.module('utils/log', { | ||||
|     // | ||||
|     // Instead we'll temporarily replace them with no-op functions | ||||
|     window.console = { | ||||
|       debug: sinon.spy(), | ||||
|       info: sinon.spy(), | ||||
|       log: sinon.spy(), | ||||
|       warn: sinon.spy(), | ||||
|       error: sinon.spy() | ||||
| @@ -47,6 +49,7 @@ QUnit.test('logging functions should work', function(assert) { | ||||
|   log.history.clear(); | ||||
|  | ||||
|   log('log1', 'log2'); | ||||
|   log.debug('debug1', 'debug2'); | ||||
|   log.warn('warn1', 'warn2'); | ||||
|   log.error('error1', 'error2'); | ||||
|  | ||||
| @@ -56,6 +59,9 @@ QUnit.test('logging functions should work', function(assert) { | ||||
|     getConsoleArgs('VIDEOJS:', 'log1', 'log2') | ||||
|   ); | ||||
|  | ||||
|   // debug isn't enabled by default | ||||
|   assert.notOk(window.console.debug.called, 'debug was not called'); | ||||
|  | ||||
|   assert.ok(window.console.warn.called, 'warn was called'); | ||||
|   assert.deepEqual( | ||||
|     window.console.warn.firstCall.args, | ||||
| @@ -70,10 +76,20 @@ QUnit.test('logging functions should work', function(assert) { | ||||
|  | ||||
|   const history = log.history(); | ||||
|  | ||||
|   assert.equal(history.length, 3, 'there should be three messages in the log history'); | ||||
|   assert.deepEqual(history[0], ['log1', 'log2'], 'history recorded the correct arguments'); | ||||
|   assert.deepEqual(history[1], ['WARN:', 'warn1', 'warn2'], 'history recorded the correct arguments'); | ||||
|   assert.deepEqual(history[2], ['ERROR:', 'error1', 'error2'], 'history recorded the correct arguments'); | ||||
|   assert.equal(history.length, 4, 'there should be four messages in the log history'); | ||||
|   assert.deepEqual(history[0], | ||||
|                    ['log1', 'log2'], | ||||
|                    'history recorded the correct arguments'); | ||||
|   // although not enabled by default, history should still maintain the record | ||||
|   assert.deepEqual(history[1], | ||||
|                    ['DEBUG:', 'debug1', 'debug2'], | ||||
|                    'history recorded the correct arguments'); | ||||
|   assert.deepEqual(history[2], | ||||
|                    ['WARN:', 'warn1', 'warn2'], | ||||
|                    'history recorded the correct arguments'); | ||||
|   assert.deepEqual(history[3], | ||||
|                    ['ERROR:', 'error1', 'error2'], | ||||
|                    'history recorded the correct arguments'); | ||||
| }); | ||||
|  | ||||
| QUnit.test('in IE pre-11 (or when requested) objects and arrays are stringified', function(assert) { | ||||
| @@ -160,3 +176,65 @@ QUnit.test('history can be enabled/disabled', function(assert) { | ||||
|  | ||||
|   assert.strictEqual(history.length, 3, 'history was tracked'); | ||||
| }); | ||||
|  | ||||
| QUnit.test('supports debug logging', function(assert) { | ||||
|   // Need to reset history here because there are extra messages logged | ||||
|   // when running via Karma. | ||||
|   log.history.clear(); | ||||
|  | ||||
|   log.level('debug'); | ||||
|  | ||||
|   log('log1', 'log2'); | ||||
|   log.debug('debug1', 'debug2'); | ||||
|   log.warn('warn1', 'warn2'); | ||||
|   log.error('error1', 'error2'); | ||||
|  | ||||
|   assert.ok(window.console.log.called, 'console.log was called'); | ||||
|   assert.ok(window.console.debug.called, 'console.debug was called'); | ||||
|   assert.ok(window.console.warn.called, 'console.warn was called'); | ||||
|   assert.ok(window.console.error.called, 'console.error called'); | ||||
|  | ||||
|   const history = log.history(); | ||||
|  | ||||
|   assert.equal(history.length, 4, 'four messages in history'); | ||||
|   assert.deepEqual(history[0], ['log1', 'log2'], 'history is maintained'); | ||||
|   assert.deepEqual(history[1], ['DEBUG:', 'debug1', 'debug2'], 'history is maintained'); | ||||
|   assert.deepEqual(history[2], ['WARN:', 'warn1', 'warn2'], 'history is maintained'); | ||||
|   assert.deepEqual(history[3], ['ERROR:', 'error1', 'error2'], 'history is maintained'); | ||||
| }); | ||||
|  | ||||
| QUnit.test('falls back to info and log when debug is not supported', function(assert) { | ||||
|   // Need to reset history here because there are extra messages logged | ||||
|   // when running via Karma. | ||||
|   log.history.clear(); | ||||
|  | ||||
|   log.level('debug'); | ||||
|  | ||||
|   window.console.debug = null; | ||||
|   logByType('debug', ['debug1', 'debug2']); | ||||
|  | ||||
|   assert.ok(window.console.info.called, 'info was called'); | ||||
|   assert.notOk(window.console.log.called, 'log was not called'); | ||||
|   assert.notOk(window.console.warn.called, 'warn was not called'); | ||||
|   assert.notOk(window.console.error.called, 'error was not called'); | ||||
|   assert.deepEqual(window.console.info.firstCall.args, | ||||
|                    ['VIDEOJS:', 'DEBUG:', 'debug1', 'debug2'], | ||||
|                    'logged the right message'); | ||||
|  | ||||
|   window.console.info = null; | ||||
|   logByType('debug', ['debug3', 'debug4']); | ||||
|  | ||||
|   assert.ok(window.console.log.called, 'log was called'); | ||||
|   assert.notOk(window.console.warn.called, 'warn was not called'); | ||||
|   assert.notOk(window.console.error.called, 'error was not called'); | ||||
|   assert.deepEqual(window.console.log.firstCall.args, | ||||
|                    ['VIDEOJS:', 'DEBUG:', 'debug3', 'debug4'], | ||||
|                    'logged the right message'); | ||||
|  | ||||
|   // when no comparable level logs are available, there should not be any logging | ||||
|   window.console.log = null; | ||||
|   logByType('debug', ['debug5', 'debug6']); | ||||
|  | ||||
|   assert.notOk(window.console.warn.called, 'warn was not called'); | ||||
|   assert.notOk(window.console.error.called, 'error was not called'); | ||||
| }); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user