Debug.ts (2728B)
1 /** 2 * @license 3 * Copyright 2020 Google Inc. 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 import type Debug from 'debug'; 8 9 import {isNode} from '../environment.js'; 10 11 declare global { 12 const __PUPPETEER_DEBUG: string; 13 } 14 15 /** 16 * @internal 17 */ 18 let debugModule: typeof Debug | null = null; 19 /** 20 * @internal 21 */ 22 export async function importDebug(): Promise<typeof Debug> { 23 if (!debugModule) { 24 debugModule = (await import('debug')).default; 25 } 26 return debugModule; 27 } 28 29 /** 30 * A debug function that can be used in any environment. 31 * 32 * @remarks 33 * If used in Node, it falls back to the 34 * {@link https://www.npmjs.com/package/debug | debug module}. In the browser it 35 * uses `console.log`. 36 * 37 * In Node, use the `DEBUG` environment variable to control logging: 38 * 39 * ``` 40 * DEBUG=* // logs all channels 41 * DEBUG=foo // logs the `foo` channel 42 * DEBUG=foo* // logs any channels starting with `foo` 43 * ``` 44 * 45 * In the browser, set `window.__PUPPETEER_DEBUG` to a string: 46 * 47 * ``` 48 * window.__PUPPETEER_DEBUG='*'; // logs all channels 49 * window.__PUPPETEER_DEBUG='foo'; // logs the `foo` channel 50 * window.__PUPPETEER_DEBUG='foo*'; // logs any channels starting with `foo` 51 * ``` 52 * 53 * @example 54 * 55 * ``` 56 * const log = debug('Page'); 57 * 58 * log('new page created') 59 * // logs "Page: new page created" 60 * ``` 61 * 62 * @param prefix - this will be prefixed to each log. 63 * @returns a function that can be called to log to that debug channel. 64 * 65 * @internal 66 */ 67 export const debug = (prefix: string): ((...args: unknown[]) => void) => { 68 if (isNode) { 69 return async (...logArgs: unknown[]) => { 70 if (captureLogs) { 71 capturedLogs.push(prefix + logArgs); 72 } 73 (await importDebug())(prefix)(logArgs); 74 }; 75 } 76 77 return (...logArgs: unknown[]): void => { 78 const debugLevel = (globalThis as any).__PUPPETEER_DEBUG; 79 if (!debugLevel) { 80 return; 81 } 82 83 const everythingShouldBeLogged = debugLevel === '*'; 84 85 const prefixMatchesDebugLevel = 86 everythingShouldBeLogged || 87 /** 88 * If the debug level is `foo*`, that means we match any prefix that 89 * starts with `foo`. If the level is `foo`, we match only the prefix 90 * `foo`. 91 */ 92 (debugLevel.endsWith('*') 93 ? prefix.startsWith(debugLevel) 94 : prefix === debugLevel); 95 96 if (!prefixMatchesDebugLevel) { 97 return; 98 } 99 100 console.log(`${prefix}:`, ...logArgs); 101 }; 102 }; 103 104 /** 105 * @internal 106 */ 107 let capturedLogs: string[] = []; 108 /** 109 * @internal 110 */ 111 let captureLogs = false; 112 113 /** 114 * @internal 115 */ 116 export function setLogCapture(value: boolean): void { 117 capturedLogs = []; 118 captureLogs = value; 119 } 120 121 /** 122 * @internal 123 */ 124 export function getCapturedLogs(): string[] { 125 return capturedLogs; 126 }