Skip to content

Debug Logging Utility

A global debug logging utility that provides consistent, namespace-prefixed logging across all JavaScript controllers and services. Automatically enabled in Rails development environment.

app/javascript/utils/debug.js
import { debug } from '../utils/debug'
// Simple logging with namespace prefix
debug('cart', 'Cart - Product Added', { sku: 'SS-01', price: 15 })
// Output in dev: [cart] Cart - Product Added {sku: 'SS-01', price: 15}
// Output in prod: (nothing - debug disabled)
Method Description Always Logs?
debug(namespace, ...args) Log with prefix No
debug.log(namespace, ...args) Same as above No
debug.warn(namespace, ...args) Warning with prefix No
debug.error(namespace, ...args) Error with prefix Yes
debug.group(namespace, label) Start collapsible group No
debug.groupEnd() End group No
debug.time(namespace, label) Start timer No
debug.timeEnd(namespace, label) End timer, show duration No
import { debug } from '../utils/debug'
export default class extends Controller {
connect() {
debug('mycontroller', 'connected', this.element)
}
async fetchData() {
debug.time('mycontroller', 'fetch')
debug.group('mycontroller', 'Fetching data')
debug('mycontroller', 'URL:', this.urlValue)
debug('mycontroller', 'Params:', this.paramsValue)
debug.groupEnd()
try {
const response = await fetch(this.urlValue)
debug('mycontroller', 'Response:', response.status)
debug.timeEnd('mycontroller', 'fetch')
} catch (error) {
debug.error('mycontroller', 'Fetch failed:', error) // Always logs
}
}
}

The debug utility is attached to window.debug for runtime control:

// Check if debug is enabled
debug.isEnabled // true in development, false in production
// Force enable (useful in production for debugging)
debug.enable()
// Output: [debug] Debug logging enabled
// Force disable
debug.disable()

Debug mode is automatically enabled based on the Rails environment:

// Enabled when:
window.env === 'development'

This uses the window.env variable set by initWindowGlobals() from the page config.

The Analytics service uses this debug utility. You can toggle analytics debug logging:

// These are equivalent:
debug.enable()
Analytics._debug = true
// Check status:
Analytics._debug // Returns debug.isEnabled

Use consistent namespace prefixes for easy filtering in DevTools:

Namespace Used By
Analytics Analytics service
cart Cart controller
analytics-track Analytics track controller
search Search controller
consent Consent manager

In Chrome/Firefox DevTools Console, you can filter by namespace:

  1. Open Console
  2. Type in filter box: [cart] or [Analytics]
  3. Only matching logs are shown
  1. Always use a namespace - Makes filtering easy
  2. Keep namespaces short - cart not cart-controller
  3. Use lowercase - cart, search, consent
  4. Group related logs - Use debug.group() for multi-step operations
  5. Time async operations - Use debug.time()/debug.timeEnd()
  6. Errors always log - Use debug.error() for critical issues
  • In production (window.env !== 'development'), all debug calls are no-ops
  • No string concatenation or object serialization occurs
  • Zero performance impact when disabled