From b2c
Implements logging in B2C Commerce scripts using dw.system.Logger for debug output, error tracking, custom log files, categories, and levels (debug, info, warn, error, fatal).
npx claudepluginhub salesforcecommercecloud/b2c-developer-tooling --plugin b2cThis skill uses the workspace's default tool permissions.
This skill guides you through implementing logging in B2C Commerce using the Logger and Log classes.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
This skill guides you through implementing logging in B2C Commerce using the Logger and Log classes.
B2C Commerce provides a logging framework with:
| Feature | Description |
|---|---|
| Log Levels | debug, info, warn, error, fatal |
| Categories | Organize logs by functional area |
| Custom Files | Write to dedicated log files |
| NDC | Nested Diagnostic Context for tracing |
| BM Configuration | Enable/disable levels per category |
| Level | Method | Description | Default State |
|---|---|---|---|
debug | debug() | Detailed debugging information | Disabled (never on production) |
info | info() | General information | Disabled by default |
warn | warn() | Warning conditions | Always enabled |
error | error() | Error conditions | Always enabled |
fatal | fatal() | Critical failures | Always enabled, can send email |
The Logger class provides static methods for quick logging:
var Logger = require('dw/system/Logger');
// Simple messages
Logger.debug('Debug message');
Logger.info('Info message');
Logger.warn('Warning message');
Logger.error('Error message');
// Messages with parameters (Java MessageFormat syntax)
Logger.info('Processing order {0} for customer {1}', orderNo, customerEmail);
Logger.error('Failed to process {0}: {1}', productId, errorMessage);
The Log class provides instance-based logging with categories:
var Logger = require('dw/system/Logger');
// Get logger for a category
var log = Logger.getLogger('checkout');
log.debug('Cart contents: {0}', JSON.stringify(cart));
log.info('Checkout started for basket {0}', basketId);
log.warn('Inventory low for product {0}', productId);
log.error('Payment failed: {0}', errorMessage);
log.fatal('Critical checkout failure: {0}', errorMessage);
Categories help organize and filter log messages:
var Logger = require('dw/system/Logger');
// Different categories for different areas
var checkoutLog = Logger.getLogger('checkout');
var paymentLog = Logger.getLogger('payment');
var inventoryLog = Logger.getLogger('inventory');
var integrationLog = Logger.getLogger('integration');
// Use appropriate logger
checkoutLog.info('Order {0} submitted', orderNo);
paymentLog.info('Payment authorized: {0}', transactionId);
inventoryLog.warn('Stock level below threshold for {0}', productId);
integrationLog.error('API call failed: {0}', serviceName);
Categories are configured in Business Manager under Administration > Operations > Custom Log Settings.
Write to dedicated log files instead of the standard custom log files:
var Logger = require('dw/system/Logger');
// Get logger with custom file prefix
var orderExportLog = Logger.getLogger('orderexport', 'export');
var feedLog = Logger.getLogger('productfeed', 'feed');
// Messages go to custom-orderexport-*.log
orderExportLog.info('Exporting order {0}', orderNo);
// Messages go to custom-productfeed-*.log
feedLog.info('Processing product {0}', productId);
The fileNamePrefix parameter must follow these rules:
| Rule | Requirement |
|---|---|
| Length | 3-25 characters |
| Characters | a-z, A-Z, 0-9, -, _ |
| Start/End | Must start and end with alphanumeric |
| Not allowed | Cannot start or end with - or _ |
Custom log files follow this pattern:
custom-<prefix>-<hostname>-appserver-<date>.log
Example: custom-orderexport-blade0-1-appserver-20240115.log
Maximum 200 different log file names per day per appserver.
Check if a log level is enabled before expensive operations:
var Logger = require('dw/system/Logger');
var log = Logger.getLogger('myCategory');
// Check before expensive string building
if (log.isDebugEnabled()) {
log.debug('Full cart contents: {0}', JSON.stringify(cart));
}
// Check before expensive calculations
if (log.isInfoEnabled()) {
var stats = calculateDetailedStats(); // expensive
log.info('Statistics: {0}', JSON.stringify(stats));
}
// Available checks
log.isDebugEnabled(); // true if debug logging enabled
log.isInfoEnabled(); // true if info logging enabled
log.isWarnEnabled(); // true if warn logging enabled
log.isErrorEnabled(); // true if error logging enabled
var Logger = require('dw/system/Logger');
if (Logger.isDebugEnabled()) {
Logger.debug('Debug message');
}
Messages support Java MessageFormat syntax:
var Logger = require('dw/system/Logger');
var log = Logger.getLogger('order');
// Positional parameters
log.info('Order {0} has {1} items totaling {2}', orderNo, itemCount, total);
// Same parameter multiple times
log.info('Product {0}: {0} is out of stock', productId);
// Complex objects (use JSON.stringify for objects)
log.debug('Request: {0}', JSON.stringify(requestData));
NDC helps trace related log messages across a request:
var Logger = require('dw/system/Logger');
var Log = require('dw/system/Log');
var log = Logger.getLogger('checkout');
var ndc = Log.getNDC();
function processOrder(orderId) {
// Push context onto the stack
ndc.push('Order:' + orderId);
try {
log.info('Starting order processing');
processPayment();
processShipping();
log.info('Order processing complete');
} finally {
// Always pop context when leaving scope
ndc.pop();
}
}
function processPayment() {
ndc.push('Payment');
try {
log.info('Processing payment'); // NDC shows: Order:123 Payment
} finally {
ndc.pop();
}
}
| Method | Description |
|---|---|
push(message) | Add context to the stack |
pop() | Remove and return top context |
peek() | View top context without removing |
remove() | Clear entire context |
// Good: Organized by functional area
var log = Logger.getLogger('payment.processor');
var log = Logger.getLogger('inventory.sync');
var log = Logger.getLogger('order.export');
// Avoid: No category
Logger.info('Something happened');
// Good: Check before building expensive string
if (log.isDebugEnabled()) {
log.debug('Full response: {0}', JSON.stringify(largeObject));
}
// Avoid: Always building expensive strings
log.debug('Full response: {0}', JSON.stringify(largeObject));
// Good: Includes relevant context
log.error('Payment failed for order {0}, customer {1}: {2}',
orderNo, customerId, errorMessage);
// Avoid: Missing context
log.error('Payment failed');
// debug: Detailed technical information
log.debug('SQL query: {0}', query);
log.debug('API request body: {0}', JSON.stringify(body));
// info: Notable events
log.info('Order {0} placed successfully', orderNo);
log.info('Customer {0} logged in', customerId);
// warn: Potential issues
log.warn('Inventory low for product {0}: {1} remaining', productId, qty);
log.warn('Slow API response: {0}ms', responseTime);
// error: Failures that need attention
log.error('Payment declined for order {0}: {1}', orderNo, reason);
log.error('Failed to connect to service {0}: {1}', serviceName, error);
// fatal: Critical system failures
log.fatal('Database connection lost');
log.fatal('Critical configuration missing: {0}', configKey);
// Dedicated files for each integration
var erpLog = Logger.getLogger('erp-sync', 'erp');
var omsLog = Logger.getLogger('oms-export', 'oms');
var crmLog = Logger.getLogger('crm-sync', 'crm');
// Good: Mask sensitive data
log.info('Payment processed for card ending in {0}', cardNumber.slice(-4));
// Avoid: Logging sensitive data
log.info('Payment processed for card {0}', cardNumber);
Configure custom logging in Administration > Operations > Custom Log Settings:
| Setting | Description |
|---|---|
| Log to File | Enable file logging for each level |
| Receive Email | Email addresses for fatal notifications |
| Root Category | Default settings for all categories |
| Custom Categories | Override settings per category |
checkout, payment)Log entries follow this format:
[timestamp] [level] [category] message
Example:
[2024-01-15 10:30:45.123 GMT] [INFO] [checkout] Order ORD123 placed successfully
| Class | Description |
|---|---|
dw.system.Logger | Static logging methods and logger factory |
dw.system.Log | Logger instance with category support |
dw.system.LogNDC | Nested Diagnostic Context for tracing |