Back to Blog
JavaScriptConsoleDebuggingDevTools

JavaScript Console Methods

Master JavaScript console methods for debugging. From basic logging to tables to performance timing.

B
Bootspring Team
Engineering
April 15, 2020
5 min read

The console API offers powerful debugging tools beyond console.log. Here's the full toolkit.

Basic Logging#

1// Log levels 2console.log('General output'); 3console.info('Informational message'); 4console.warn('Warning message'); 5console.error('Error message'); 6console.debug('Debug message'); // May be hidden by default 7 8// Multiple arguments 9console.log('User:', user, 'Action:', action); 10 11// String substitution 12console.log('Hello, %s!', 'World'); // String 13console.log('Count: %d', 42); // Integer 14console.log('Value: %f', 3.14159); // Float 15console.log('Object: %o', { a: 1 }); // Object 16console.log('DOM: %O', document.body); // DOM element 17console.log('Styled: %c Bold', 'font-weight: bold'); // CSS 18 19// Template literals (preferred) 20console.log(`User: ${user.name}, Age: ${user.age}`);

Styling Output#

1// CSS styling 2console.log( 3 '%c Big Red Text', 4 'color: red; font-size: 24px; font-weight: bold;' 5); 6 7// Multiple styles 8console.log( 9 '%c Success %c Warning %c Error', 10 'color: green; background: #e8f5e9; padding: 2px 6px;', 11 'color: orange; background: #fff3e0; padding: 2px 6px;', 12 'color: red; background: #ffebee; padding: 2px 6px;' 13); 14 15// Custom logger 16const styled = { 17 success: (msg) => console.log(`%c ✓ ${msg}`, 'color: green'), 18 error: (msg) => console.log(`%c ✗ ${msg}`, 'color: red'), 19 info: (msg) => console.log(`%c ℹ ${msg}`, 'color: blue'), 20}; 21 22styled.success('Operation completed'); 23styled.error('Something went wrong'); 24styled.info('Processing...');

Tables#

1// Array of objects 2const users = [ 3 { name: 'Alice', age: 25, role: 'Admin' }, 4 { name: 'Bob', age: 30, role: 'User' }, 5 { name: 'Carol', age: 28, role: 'Editor' }, 6]; 7 8console.table(users); 9// Displays formatted table 10 11// Select columns 12console.table(users, ['name', 'role']); 13// Shows only name and role columns 14 15// Object 16const config = { 17 apiUrl: 'https://api.example.com', 18 timeout: 5000, 19 debug: true, 20}; 21 22console.table(config); 23 24// Nested data 25const data = { 26 users: { count: 100, active: 80 }, 27 posts: { count: 500, published: 450 }, 28}; 29 30console.table(data);

Grouping#

1// Basic grouping 2console.group('User Details'); 3console.log('Name: Alice'); 4console.log('Age: 25'); 5console.log('Role: Admin'); 6console.groupEnd(); 7 8// Collapsed group 9console.groupCollapsed('API Response'); 10console.log('Status: 200'); 11console.log('Data:', responseData); 12console.groupEnd(); 13 14// Nested groups 15console.group('Request'); 16console.log('URL:', url); 17console.group('Headers'); 18console.log('Content-Type:', 'application/json'); 19console.log('Authorization:', 'Bearer ...'); 20console.groupEnd(); 21console.group('Body'); 22console.log('Payload:', payload); 23console.groupEnd(); 24console.groupEnd(); 25 26// Dynamic grouping 27function logRequest(req) { 28 console.group(`${req.method} ${req.url}`); 29 console.log('Headers:', req.headers); 30 console.log('Body:', req.body); 31 console.groupEnd(); 32}

Counting#

1// Count occurrences 2console.count('click'); // click: 1 3console.count('click'); // click: 2 4console.count('click'); // click: 3 5 6// Different labels 7console.count('button-a'); // button-a: 1 8console.count('button-b'); // button-b: 1 9console.count('button-a'); // button-a: 2 10 11// Reset count 12console.countReset('click'); 13console.count('click'); // click: 1 14 15// Practical usage 16function handleClick(buttonId) { 17 console.count(`clicks-${buttonId}`); 18 // ... handle click 19} 20 21// Count in loops 22items.forEach(item => { 23 if (item.isValid) { 24 console.count('valid'); 25 } else { 26 console.count('invalid'); 27 } 28});

Timing#

1// Basic timing 2console.time('operation'); 3// ... perform operation 4console.timeEnd('operation'); 5// operation: 123.456ms 6 7// Time log (doesn't end timer) 8console.time('process'); 9doStep1(); 10console.timeLog('process', 'Step 1 complete'); 11doStep2(); 12console.timeLog('process', 'Step 2 complete'); 13doStep3(); 14console.timeEnd('process'); 15// process: 50ms Step 1 complete 16// process: 120ms Step 2 complete 17// process: 200ms 18 19// Multiple timers 20console.time('total'); 21console.time('fetch'); 22const data = await fetch(url); 23console.timeEnd('fetch'); 24 25console.time('process'); 26processData(data); 27console.timeEnd('process'); 28 29console.timeEnd('total'); 30 31// Performance comparison 32function measurePerformance(fn, label) { 33 console.time(label); 34 const result = fn(); 35 console.timeEnd(label); 36 return result; 37}

Assertions#

1// Assert - logs only if condition is false 2console.assert(1 === 1, 'This will not appear'); 3console.assert(1 === 2, 'Math is broken!'); 4// Assertion failed: Math is broken! 5 6// With objects 7const user = { name: 'Alice', role: 'guest' }; 8console.assert( 9 user.role === 'admin', 10 'Expected admin user', 11 user 12); 13 14// Validation 15function validateConfig(config) { 16 console.assert(config.apiKey, 'Missing API key'); 17 console.assert(config.timeout > 0, 'Invalid timeout'); 18 console.assert(Array.isArray(config.endpoints), 'Endpoints must be array'); 19}

Stack Traces#

1// Print stack trace 2function functionA() { 3 functionB(); 4} 5 6function functionB() { 7 functionC(); 8} 9 10function functionC() { 11 console.trace('Stack trace'); 12} 13 14functionA(); 15// Stack trace 16// at functionC (...) 17// at functionB (...) 18// at functionA (...) 19 20// Debug deep call stacks 21function processItem(item) { 22 if (!item.valid) { 23 console.trace('Invalid item found'); 24 } 25}

Clearing and Profiling#

1// Clear console 2console.clear(); 3 4// Profiling (browser-specific) 5console.profile('My Profile'); 6// ... code to profile 7console.profileEnd('My Profile'); 8 9// Memory (browser-specific) 10console.memory; 11 12// Directory listing 13const obj = { a: 1, b: { c: 2 } }; 14console.dir(obj, { depth: null }); // Full depth 15 16// DOM element as object 17console.dir(document.body); 18 19// XML/HTML display 20console.dirxml(document.body);

Custom Logger#

1// Production-safe logger 2const logger = { 3 _isEnabled: process.env.NODE_ENV !== 'production', 4 5 log(...args) { 6 if (this._isEnabled) { 7 console.log('[LOG]', ...args); 8 } 9 }, 10 11 info(...args) { 12 if (this._isEnabled) { 13 console.info('[INFO]', ...args); 14 } 15 }, 16 17 warn(...args) { 18 console.warn('[WARN]', ...args); // Always show warnings 19 }, 20 21 error(...args) { 22 console.error('[ERROR]', ...args); // Always show errors 23 }, 24 25 group(label, fn) { 26 if (this._isEnabled) { 27 console.group(label); 28 fn(); 29 console.groupEnd(); 30 } else { 31 fn(); 32 } 33 }, 34 35 table(data) { 36 if (this._isEnabled) { 37 console.table(data); 38 } 39 }, 40 41 time(label) { 42 if (this._isEnabled) { 43 console.time(label); 44 } 45 }, 46 47 timeEnd(label) { 48 if (this._isEnabled) { 49 console.timeEnd(label); 50 } 51 }, 52}; 53 54// Level-based logger 55class Logger { 56 static LEVELS = { DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3 }; 57 58 constructor(level = 'INFO') { 59 this.level = Logger.LEVELS[level]; 60 } 61 62 debug(...args) { 63 if (this.level <= Logger.LEVELS.DEBUG) { 64 console.debug('[DEBUG]', ...args); 65 } 66 } 67 68 info(...args) { 69 if (this.level <= Logger.LEVELS.INFO) { 70 console.info('[INFO]', ...args); 71 } 72 } 73 74 warn(...args) { 75 if (this.level <= Logger.LEVELS.WARN) { 76 console.warn('[WARN]', ...args); 77 } 78 } 79 80 error(...args) { 81 if (this.level <= Logger.LEVELS.ERROR) { 82 console.error('[ERROR]', ...args); 83 } 84 } 85}

Best Practices#

Development: ✓ Use appropriate log levels ✓ Group related logs ✓ Add context to messages ✓ Use console.table for data Debugging: ✓ Use console.trace for call stacks ✓ Use console.time for performance ✓ Use console.assert for validation ✓ Use console.count for frequency Production: ✓ Remove or disable debug logs ✓ Keep error logging ✓ Use proper logging service ✓ Don't log sensitive data Avoid: ✗ Leaving debug logs in production ✗ Logging sensitive information ✗ Over-logging (performance impact) ✗ Using console.log for everything

Conclusion#

The console API provides powerful debugging tools beyond basic logging. Use tables for data visualization, groups for organization, timing for performance measurement, and assertions for validation. Create custom loggers for production-safe logging with appropriate levels.

Share this article

Help spread the word about Bootspring