Basic Logging
ByteHide Logger provides six logging levels with simple, intuitive methods. Each level serves different purposes and accepts various parameters for flexible logging.
Logging Methods Overview
Method | Purpose | Parameters |
---|---|---|
Log.trace(message, options) | Most detailed diagnostic information | string message , object options |
Log.debug(message, options) | Detailed diagnostic information | string message , object options |
Log.info(message, options) | General information messages | string message , object options |
Log.warn(message, options) | Warning messages | string message , object options |
Log.error(message, options, error) | Error messages | string message , object options , Error error |
Log.critical(message, options, error) | Critical errors | string message , object options , Error error |
Basic Logging Methods
Trace Level
Use for the most detailed diagnostic information:
Log.trace('Entering function processOrder');
Log.trace('Processing item 1 of 10');
Log.trace('Database connection established');
Debug Level
Use for detailed diagnostic information during development:
Log.debug('User authentication started');
Log.debug('Cache miss for key: user_123');
Log.debug('API response received in 250ms');
Info Level
Use for general information about application flow:
Log.info('Application started successfully');
Log.info('User logged in');
Log.info('Order processed successfully');
Advanced Logging Methods
Warn Level
Use for potential issues that don't stop execution:
// Simple warning
Log.warn('API rate limit approaching');
// Warning with context
Log.warn('Non-critical operation failed, using fallback', {
context: { operation: 'cacheUpdate', fallback: 'database' }
});
Error Level
Use for errors that affect functionality:
// Error with context and error object
try {
await processOrder(orderId);
} catch (error) {
Log.error('Failed to process order', {
context: { orderId, userId },
metadata: { attempt: 1 }
}, error);
}
// Error with context only
Log.error('Invalid configuration detected', {
context: { configFile: 'config.json', section: 'database' }
});
Critical Level
Use for critical errors that may cause application termination:
// Critical error with error object
try {
await initializeDatabase();
} catch (error) {
Log.critical('Failed to initialize database - application cannot continue', {
context: { connectionString: '***' }
}, error);
process.exit(1);
}
// Critical error without error object
Log.critical('Out of memory - shutting down', {
metadata: { memoryUsage: '95%' }
});
Options Object
All logging methods accept an options
object with these properties:
const options = {
context: { orderId: '123', userId: '456' },
tags: ['orders', 'payment'],
correlationId: 'req-abc123',
metadata: { processingTime: 250, attempt: 1 }
};
Log.info('Order processed successfully', options);
Practical Examples
API Request Logging
// Express.js route
app.post('/api/orders', async (req, res) => {
const correlationId = req.headers['x-correlation-id'] || generateId();
Log.info('Order creation started', {
correlationId,
context: { customerId: req.body.customerId },
tags: ['api', 'orders']
});
try {
const order = await orderService.create(req.body);
Log.info('Order created successfully', {
correlationId,
context: { orderId: order.id },
metadata: { processingTime: Date.now() - startTime }
});
res.json(order);
} catch (error) {
Log.error('Order creation failed', {
correlationId,
context: { customerId: req.body.customerId },
tags: ['api', 'orders', 'error']
}, error);
res.status(500).json({ error: 'Internal server error' });
}
});
Service Layer Logging
class OrderService {
async createOrder(orderData) {
Log.info('Creating new order', {
context: { customerId: orderData.customerId },
tags: ['service', 'orders']
});
try {
const order = await this.repository.save(orderData);
Log.info('Order created successfully', {
context: { orderId: order.id },
metadata: { itemCount: orderData.items.length }
});
return order;
} catch (error) {
Log.error('Failed to create order', {
context: { customerId: orderData.customerId },
tags: ['service', 'orders', 'error']
}, error);
throw error;
}
}
}
Background Task Logging
class EmailProcessor {
async processEmails() {
Log.info('Email processing started', {
tags: ['background', 'email']
});
const emails = await this.getePendingEmails();
Log.debug('Found pending emails', {
metadata: { count: emails.length },
tags: ['background', 'email']
});
for (const email of emails) {
try {
await this.sendEmail(email);
Log.trace('Email sent successfully', {
context: { emailId: email.id, recipient: email.to }
});
} catch (error) {
Log.error('Failed to send email', {
context: { emailId: email.id },
tags: ['email', 'error']
}, error);
}
}
Log.info('Email processing completed', {
metadata: { processed: emails.length },
tags: ['background', 'email']
});
}
}
Best Practices
When to Use Each Level
- Trace: Function entry/exit, loop iterations, detailed flow
- Debug: Variable values, cache hits/misses, intermediate results
- Info: Application milestones, user actions, business events
- Warn: Recoverable errors, deprecated usage, performance issues
- Error: Exceptions, failed operations, data inconsistencies
- Critical: System failures, security breaches, unrecoverable errors
Context Best Practices
// ✅ Good - Structured context
Log.error('Order processing failed', {
context: {
orderId: order.id,
stage: 'payment',
amount: order.total
}
}, error);
// ❌ Avoid - String concatenation
Log.error(`Order ${order.id} processing failed at payment stage with amount ${order.total}`);
// ✅ Good - Relevant context only
Log.error('Database query failed', {
context: { query: 'getUserById', userId }
}, error);
// ❌ Avoid - Too much context
Log.error('Database query failed', {
context: entireUserObject
}, error);
Next Steps
- Error Logging - Learn proper error handling with Error and Critical methods
- Data Masking - Protect sensitive information
- User Identification - Associate logs with users
- Correlation IDs - Track requests across services
- Global Metadata - Add consistent context to all logs