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)
MethodDescriptionAlways Logs?
debug(namespace, ...args)Log with prefixNo
debug.log(namespace, ...args)Same as aboveNo
debug.warn(namespace, ...args)Warning with prefixNo
debug.error(namespace, ...args)Error with prefixYes
debug.group(namespace, label)Start collapsible groupNo
debug.groupEnd()End groupNo
debug.time(namespace, label)Start timerNo
debug.timeEnd(namespace, label)End timer, show durationNo
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:

NamespaceUsed By
AnalyticsAnalytics service
cartCart controller
analytics-trackAnalytics track controller
searchSearch controller
consentConsent 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