b2c-logging
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLogging Skill
日志实现技能
This skill guides you through implementing logging in B2C Commerce using the Logger and Log classes.
本技能将指导你使用Logger和Log类在B2C Commerce中实现日志功能。
Overview
概述
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 |
B2C Commerce提供的日志框架包含以下功能:
| 功能 | 描述 |
|---|---|
| 日志级别 | debug、info、warn、error、fatal |
| 日志分类 | 按功能领域组织日志 |
| 自定义文件 | 写入专用日志文件 |
| NDC | 用于追踪的嵌套诊断上下文(Nested Diagnostic Context) |
| BM配置 | 按分类启用/禁用不同级别 |
Log Levels
日志级别
| Level | Method | Description | Default State |
|---|---|---|---|
| | Detailed debugging information | Disabled (never on production) |
| | General information | Disabled by default |
| | Warning conditions | Always enabled |
| | Error conditions | Always enabled |
| | Critical failures | Always enabled, can send email |
| 级别 | 方法 | 描述 | 默认状态 |
|---|---|---|---|
| | 详细的调试信息 | 禁用(生产环境中始终关闭) |
| | 常规信息 | 默认禁用 |
| | 警告情况 | 始终启用 |
| | 错误情况 | 始终启用 |
| | 严重故障 | 始终启用,可发送邮件 |
Basic Logging
基础日志实现
Using Logger (Static Methods)
使用Logger(静态方法)
The class provides static methods for quick logging:
Loggerjavascript
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);Loggerjavascript
var Logger = require('dw/system/Logger');
// 简单消息
Logger.debug('Debug message');
Logger.info('Info message');
Logger.warn('Warning message');
Logger.error('Error message');
// 带参数的消息(Java MessageFormat语法)
Logger.info('Processing order {0} for customer {1}', orderNo, customerEmail);
Logger.error('Failed to process {0}: {1}', productId, errorMessage);Using Log (Instance Methods)
使用Log(实例方法)
The class provides instance-based logging with categories:
Logjavascript
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);Logjavascript
var Logger = require('dw/system/Logger');
// 获取指定分类的日志实例
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
日志分类
Categories help organize and filter log messages:
javascript
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.
日志分类有助于组织和过滤日志消息:
javascript
var Logger = require('dw/system/Logger');
// 为不同功能区域创建不同分类的日志实例
var checkoutLog = Logger.getLogger('checkout');
var paymentLog = Logger.getLogger('payment');
var inventoryLog = Logger.getLogger('inventory');
var integrationLog = Logger.getLogger('integration');
// 使用对应分类的日志实例
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);日志分类可在Business Manager的Administration > Operations > Custom Log Settings中配置。
Custom Named Log Files
自定义命名日志文件
Write to dedicated log files instead of the standard custom log files:
javascript
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);将日志写入专用日志文件,而非标准自定义日志文件:
javascript
var Logger = require('dw/system/Logger');
// 获取带自定义文件前缀的日志实例
var orderExportLog = Logger.getLogger('orderexport', 'export');
var feedLog = Logger.getLogger('productfeed', 'feed');
// 消息将写入custom-orderexport-*.log文件
orderExportLog.info('Exporting order {0}', orderNo);
// 消息将写入custom-productfeed-*.log文件
feedLog.info('Processing product {0}', productId);File Name Rules
文件名规则
The parameter must follow these rules:
fileNamePrefix| 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 |
fileNamePrefix| 规则 | 要求 |
|---|---|
| 长度 | 3-25个字符 |
| 允许字符 | a-z、A-Z、0-9、 |
| 首尾字符 | 必须以字母或数字开头和结尾 |
| 禁止规则 | 不能以 |
File Naming Pattern
文件命名格式
Custom log files follow this pattern:
custom-<prefix>-<hostname>-appserver-<date>.logExample:
custom-orderexport-blade0-1-appserver-20240115.log自定义日志文件遵循以下命名格式:
custom-<prefix>-<hostname>-appserver-<date>.log示例:
custom-orderexport-blade0-1-appserver-20240115.logQuota
配额限制
Maximum 200 different log file names per day per appserver.
每个应用服务器每天最多支持200个不同的日志文件名。
Checking Log Level Status
检查日志级别状态
Check if a log level is enabled before expensive operations:
javascript
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在执行高开销操作前,先检查对应日志级别是否启用:
javascript
var Logger = require('dw/system/Logger');
var log = Logger.getLogger('myCategory');
// 在构建高开销字符串前检查
if (log.isDebugEnabled()) {
log.debug('Full cart contents: {0}', JSON.stringify(cart));
}
// 在执行高开销计算前检查
if (log.isInfoEnabled()) {
var stats = calculateDetailedStats(); // 高开销操作
log.info('Statistics: {0}', JSON.stringify(stats));
}
// 可用的检查方法
log.isDebugEnabled(); // 如果debug日志启用则返回true
log.isInfoEnabled(); // 如果info日志启用则返回true
log.isWarnEnabled(); // 如果warn日志启用则返回true
log.isErrorEnabled(); // 如果error日志启用则返回trueStatic Level Checks
静态级别检查
javascript
var Logger = require('dw/system/Logger');
if (Logger.isDebugEnabled()) {
Logger.debug('Debug message');
}javascript
var Logger = require('dw/system/Logger');
if (Logger.isDebugEnabled()) {
Logger.debug('Debug message');
}Message Formatting
消息格式化
Messages support Java MessageFormat syntax:
javascript
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));日志消息支持Java MessageFormat语法:
javascript
var Logger = require('dw/system/Logger');
var log = Logger.getLogger('order');
// 位置参数
log.info('Order {0} has {1} items totaling {2}', orderNo, itemCount, total);
// 重复使用同一参数
log.info('Product {0}: {0} is out of stock', productId);
// 复杂对象(使用JSON.stringify处理对象)
log.debug('Request: {0}', JSON.stringify(requestData));Nested Diagnostic Context (NDC)
嵌套诊断上下文(NDC)
NDC helps trace related log messages across a request:
javascript
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();
}
}NDC有助于在请求链路中追踪相关日志消息:
javascript
var Logger = require('dw/system/Logger');
var Log = require('dw/system/Log');
var log = Logger.getLogger('checkout');
var ndc = Log.getNDC();
function processOrder(orderId) {
// 将上下文推入栈中
ndc.push('Order:' + orderId);
try {
log.info('Starting order processing');
processPayment();
processShipping();
log.info('Order processing complete');
} finally {
// 离开作用域时务必弹出上下文
ndc.pop();
}
}
function processPayment() {
ndc.push('Payment');
try {
log.info('Processing payment'); // NDC显示:Order:123 Payment
} finally {
ndc.pop();
}
}NDC Methods
NDC方法
| Method | Description |
|---|---|
| Add context to the stack |
| Remove and return top context |
| View top context without removing |
| Clear entire context |
| 方法 | 描述 |
|---|---|
| 将上下文添加到栈中 |
| 移除并返回栈顶上下文 |
| 查看栈顶上下文但不移除 |
| 清空整个上下文栈 |
Best Practices
最佳实践
1. Use Categories
1. 使用日志分类
javascript
// 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');javascript
// 推荐:按功能领域分类
var log = Logger.getLogger('payment.processor');
var log = Logger.getLogger('inventory.sync');
var log = Logger.getLogger('order.export');
// 避免:不使用分类
Logger.info('Something happened');2. Check Level Before Expensive Operations
2. 高开销操作前检查日志级别
javascript
// 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));javascript
// 推荐:构建高开销字符串前先检查
if (log.isDebugEnabled()) {
log.debug('Full response: {0}', JSON.stringify(largeObject));
}
// 避免:始终构建高开销字符串
log.debug('Full response: {0}', JSON.stringify(largeObject));3. Include Context in Messages
3. 消息中包含上下文信息
javascript
// Good: Includes relevant context
log.error('Payment failed for order {0}, customer {1}: {2}',
orderNo, customerId, errorMessage);
// Avoid: Missing context
log.error('Payment failed');javascript
// 推荐:包含相关上下文
log.error('Payment failed for order {0}, customer {1}: {2}',
orderNo, customerId, errorMessage);
// 避免:缺少上下文
log.error('Payment failed');4. Use Appropriate Levels
4. 使用合适的日志级别
javascript
// 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);javascript
// debug:详细技术信息
log.debug('SQL query: {0}', query);
log.debug('API request body: {0}', JSON.stringify(body));
// info:重要事件
log.info('Order {0} placed successfully', orderNo);
log.info('Customer {0} logged in', customerId);
// warn:潜在问题
log.warn('Inventory low for product {0}: {1} remaining', productId, qty);
log.warn('Slow API response: {0}ms', responseTime);
// error:需要关注的故障
log.error('Payment declined for order {0}: {1}', orderNo, reason);
log.error('Failed to connect to service {0}: {1}', serviceName, error);
// fatal:严重系统故障
log.fatal('Database connection lost');
log.fatal('Critical configuration missing: {0}', configKey);5. Use Custom Log Files for Integration
5. 集成场景使用自定义日志文件
javascript
// 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');javascript
// 为每个集成使用专用日志文件
var erpLog = Logger.getLogger('erp-sync', 'erp');
var omsLog = Logger.getLogger('oms-export', 'oms');
var crmLog = Logger.getLogger('crm-sync', 'crm');6. Don't Log Sensitive Data
6. 不要记录敏感数据
javascript
// 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);javascript
// 推荐:掩码处理敏感数据
log.info('Payment processed for card ending in {0}', cardNumber.slice(-4));
// 避免:记录敏感数据
log.info('Payment processed for card {0}', cardNumber);Business Manager Configuration
Business Manager配置
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 |
在Administration > Operations > Custom Log Settings中配置自定义日志:
| 设置 | 描述 |
|---|---|
| Log to File | 为每个级别启用文件日志 |
| Receive Email | 接收fatal级别通知的邮箱地址 |
| Root Category | 所有分类的默认设置 |
| Custom Categories | 按分类覆盖默认设置 |
Configuring Categories
配置分类
- Go to Custom Log Settings
- Click Add Category
- Enter category name (e.g., ,
checkout)payment - Set log levels to enable
- 进入Custom Log Settings
- 点击Add Category
- 输入分类名称(例如:、
checkout)payment - 设置要启用的日志级别
Log Output Format
日志输出格式
Log entries follow this format:
[timestamp] [level] [category] messageExample:
[2024-01-15 10:30:45.123 GMT] [INFO] [checkout] Order ORD123 placed successfully日志条目遵循以下格式:
[时间戳] [级别] [分类] 消息示例:
[2024-01-15 10:30:45.123 GMT] [INFO] [checkout] Order ORD123 placed successfullyDetailed Reference
详细参考
- Log Files - Log file types, locations, and retention
- Log Files - 日志文件类型、位置和保留策略
Script API Classes
脚本API类
| Class | Description |
|---|---|
| Static logging methods and logger factory |
| Logger instance with category support |
| Nested Diagnostic Context for tracing |
| 类 | 描述 |
|---|---|
| 静态日志方法和日志实例工厂 |
| 支持分类的日志实例 |
| 用于追踪的嵌套诊断上下文 |